合并远端 master(直连 Codex 改造)
冲突 19 处 / 6 个文件,逐处判定归属而不是二选一:
· commands.rs —— 保留本分支的 hydrate_game_creator_plan_gdd_state 输入解析,
丢掉与 master 重复的项目根定义(master 把它挪到了后面)。
· types.ts / useHomeProjectCreation.ts —— 取 master 把 mode/prompt/attachments
重构成 HomeDraft 的形状,保留本分支新增的 startMode。
· App.tsx —— directGameChatRuntime(master)与 !planningStartMode(本分支)是两个
互不相干的条件,合并保留;refreshDirectProjectSurface 在 merge base 里就带预览
逻辑,是 master 主动删掉并改名成 refreshDirectProjectManifest 的,取 master;
capturePendingGameChatStageManifestBeforeNextRun 是分支新增且仍被调用,保留。
· SupervisorChatOnlyView.tsx —— master 的 directCodex 短路与本分支的
projectedRuntime / descendantsStillActive 正交,逐处合成。
· project-development.suite.ts —— 那段专业 Agent 断言 base 里就有、master 主动
删除(直连 Codex 之后不再适用),取 master。
两处语义缺口一并补上:master 新增的 codex_app_server 构造
AgentRuntimeProviderRequestSnapshot 时缺本分支新增的 planning_session_binding
字段(首页直连对话不属于任何立项 session,填 None);首页提交按钮的 aria-label
还引用着已被删除的 homeAgentMode,取 master 的固定文案。
**做方案 UI 入口暂时缺失,待定。** master 在 bacd7a9da 里把 HomeAgentMode 整个删了,
首页的「做游戏 / 做素材 / 做方案」模式选择不再存在,而 startMode 在前端只有那一个
来源(homeDraftStartMode(mode))。立项策划链路的代码全部保留——后端、prompt、
澄清卡、审批卡、E2E 都在——但首页现在统一按 direct-build 进入
(HOME_DRAFT_START_MODE 常量,已在原处留注释)。入口放哪由产品侧决定后另做一笔。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
| 当前阶段 | Phase 6 |
|
||||
| 当前状态 | Phase 0~6 已收口;统一创作页已升级为 `UnifiedCreationWorkspace`,平台壳不再直接依赖旧工作台文件 |
|
||||
| 当前并行波次 | 波次 D(验收与冻结) |
|
||||
| 当前重点 | 以跨玩法门禁作为后续新增玩法和回归的常规质量基线 |
|
||||
| 当前重点 | 后续新增玩法按仓库入口规范、当前开发运维文档和现役定向测试验收 |
|
||||
|
||||
## 目标与范围
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
此表即总进度记录,后续每次 phase 收口、启动或回退时,只更新这里和下方任务状态。
|
||||
|
||||
当前已完成 Round 0~4 / Phase 0~6。后续新增玩法或统一链路改动以本文档和 `quality-gates/【玩法创作】跨玩法回归与冒烟门禁-2026-05-30.md` 为常规质量基线。
|
||||
当前已完成 Round 0~4 / Phase 0~6。后续新增玩法或统一链路改动以仓库入口规范、当前开发运维文档和现役定向测试为质量基线。
|
||||
|
||||
## 执行轮次
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
|
||||
- RPG 例外边界指定 interaction 测试通过。
|
||||
- Bark Battle 创作入口、结果页试玩/发布和正式 runtime 指定 interaction 测试通过。
|
||||
- 视觉小说工作台、生成阶段、结果页和运行态测试通过,`npm run check:visual-novel-vn11` 通过。
|
||||
- 视觉小说工作台、生成阶段、结果页和运行态测试通过,当时的视觉小说负向扫描无异常。
|
||||
|
||||
### Phase 5:结果页、发布、作品架与广场收口
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
目标:形成后续新增玩法可复用的稳定门禁。
|
||||
|
||||
- 按玩法输出创作入口、生成页、结果页、试玩、发布、作品架、广场、runtime smoke 矩阵。
|
||||
- 增补 `quality-gates/README.md` 与跨玩法回归 / 冒烟门禁,不再只覆盖首批四条链路。
|
||||
- 当时补齐跨玩法回归 / 冒烟矩阵,不再只覆盖首批四条链路;当前执行入口已收敛到根 `package.json` 和开发运维文档。
|
||||
- 固化移动端竖屏优先验收,桌面端作为兼容验证。
|
||||
- 补齐“新增玩法接入 PRD 检查块”和代码评审检查清单。
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
- Phase 3 自动回归通过:拼图、抓大鹅、敲木鱼、跳一跳、宝贝识物、大鱼、方洞结果页相关测试共 67 项;跳一跳直达结果页恢复测试通过。
|
||||
- Phase 4 / Phase 5 指定交互回归通过:RPG 例外边界、Bark Battle 闭环、作品详情、推荐 runtime、公开 read model 与跳一跳恢复相关 interaction 测试共 18 项。
|
||||
- Phase 5 详情 / 弹窗 / 作品架回归通过:公开详情、错误弹窗、反馈弹窗、作品展示 helper、作品架交互测试共 63 项。
|
||||
- `npm run check:visual-novel-vn11`、`npm run check:spacetime-schema`、`npm run check:encoding` 均通过。
|
||||
- 当时的视觉小说负向扫描、`npm run check:spacetime-schema`、`npm run check:encoding` 均通过。
|
||||
- API smoke 通过:`GET http://127.0.0.1:8082/healthz` 返回 `{"ok":true,"service":"genarrative-api-server"}`。
|
||||
- 竖屏浏览器 smoke 通过并保存截图:`.app/browser-check/phase-flow-20260530-round5/`,覆盖 `/creation/jump-hop`、`/creation/visual-novel`、`/creation/square-hole`、`/creation/bark-battle`、`/creation/baby-object-match`、`/creation/jump-hop/generating`、`/creation/jump-hop/result`、`/runtime/jump-hop`。
|
||||
|
||||
@@ -220,7 +220,7 @@ Phase 6 不再继续拆新波次,当前只把 Phase 2 到 Phase 5 的最小验
|
||||
| --- | --- | --- |
|
||||
| Phase 2 | `npm run check:encoding`、`npm run typecheck`、`npm run admin-web:typecheck`、`npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/unified-creation/unifiedCreationSpecs.test.ts src/components/unified-creation/UnifiedCreationPage.test.tsx src/components/unified-creation/UnifiedGenerationPage.test.tsx` | 校验入口配置、统一字段 spec、统一创作页和统一生成页。 |
|
||||
| Phase 3 | `npm run test -- src/components/unified-creation/workspaces/PuzzleCreationWorkspace.interaction.test.tsx src/components/unified-creation/workspaces/Match3DCreationWorkspace.interaction.test.tsx src/components/unified-creation/workspaces/WoodenFishCreationWorkspace.test.tsx src/components/unified-creation/workspaces/JumpHopCreationWorkspace.test.tsx src/components/jump-hop-result/JumpHopResultView.test.tsx src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx src/components/edutainment-creation/BabyObjectMatchWorkspace.test.tsx src/components/edutainment-result/BabyObjectMatchResultView.test.tsx src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.test.tsx src/components/big-fish-creation/BigFishAgentWorkspace.interaction.test.tsx src/components/big-fish-result/BigFishResultView.test.tsx src/components/big-fish-runtime/BigFishRuntimeShell.test.tsx`;`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "direct jump hop result route"` | 校验普通表单 / 图片 / 音频工作台仍按结构化 payload 提交,跳一跳结果页直达恢复不白屏,并把 BabyObjectMatch / BigFish 一并纳入最小回归。 |
|
||||
| Phase 4 | `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "opening RPG agent workspace does not refetch session snapshot in a render loop|create tab resumes agent workspace when draft has no compiled result yet|create tab resumes agent workspace when session has no draft profile even if summary counts look compiled|opening a compiled draft with a missing agent session falls back to draft hub"`、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "create tab opens bark battle entry form from the template card|bark battle draft result can test before publish and publish to work detail|direct bark battle runtime public code opens published runtime"`、`npm run check:visual-novel-vn11` | 校验特殊工作台例外、Bark Battle 公开闭环和视觉小说负向门禁。 |
|
||||
| Phase 4 | `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "opening RPG agent workspace does not refetch session snapshot in a render loop|create tab resumes agent workspace when draft has no compiled result yet|create tab resumes agent workspace when session has no draft profile even if summary counts look compiled|opening a compiled draft with a missing agent session falls back to draft hub"`、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "create tab opens bark battle entry form from the template card|bark battle draft result can test before publish and publish to work detail|direct bark battle runtime public code opens published runtime"`、`npm run test -- src/components/visual-novel-creation/VisualNovelAgentWorkspace.test.tsx src/components/visual-novel-result/VisualNovelResultView.test.tsx src/components/visual-novel-runtime/VisualNovelRuntimeShell.test.tsx` | 校验特殊工作台例外、Bark Battle 公开闭环和视觉小说现役链路。 |
|
||||
| Phase 5 | `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "agent draft result publishes to gallery from publish panel|creation hub published work enters existing detail view|creation hub published work experience button enters world directly|creation hub published work start uses loaded detail profile instead of library summary"`、`npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "published puzzle works appear on home and mobile game category channel|published big fish works stay hidden from platform home and mobile game category channel|home recommendation Match3D runtime keeps profile generated models when card summary is stale|home recommendation Match3D runtime passes top-level UI background assets|home recommendation Match3D runtime reloads detail when card only has UI assets"`、`npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/platform-entry/PlatformErrorDialog.test.tsx src/components/platform-entry/PlatformFeedbackView.test.tsx src/components/rpg-entry/rpgEntryWorldPresentation.test.ts`、`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx` | 校验结果页、发布、作品架、公开详情、推荐 runtime 和公开 read model,并补公开详情作者展示口径与作品架恢复矩阵。 |
|
||||
|
||||
如果这轮还改了 SpacetimeDB schema,追加 `npm run check:spacetime-schema`;如果还改了 API 路由、BFF、公开列表或 `/works/detail` 回读,追加 `npm run dev:api-server`,并另开终端从 `.app/dev-stack.json` 读取实际 `api-server` URL 后检查 `/healthz`。
|
||||
@@ -246,7 +246,7 @@ Phase 6 不再继续拆新波次,当前只把 Phase 2 到 Phase 5 的最小验
|
||||
| T5-3 | 是 | 最小回归通过 | 公开 read model 对齐 | 广场/详情/分享码缺口与执行清单 | T3/T4 方案稳定 | 后端 owner |
|
||||
| T5-4 | 是 | 最小回归通过 | 统一错误与完成反馈回归 | `PlatformErrorDialog`、`PlatformTaskCompletionDialog` 覆盖 | T3/T4 方案稳定 | 平台壳 owner |
|
||||
| T5-5 | 是 | 自动回归通过 | 统一创作壳滚动收口 | `UnifiedCreationPage` 统一接管四条入口滚动、跳一跳纳入统一壳 | T3/T4 方案稳定 | 平台壳 owner |
|
||||
| T6-1 | 否 | 已完成 | 全链路质量门禁扩展 | `quality-gates/README.md`、跨玩法回归 / 冒烟门禁、Phase 2 到 Phase 5 最小验证集合 | T3/T4/T5 完成 | QA owner |
|
||||
| T6-1 | 否 | 已完成 | 全链路质量门禁扩展 | Phase 2 到 Phase 5 最小验证集合;现已收敛到根脚本和开发运维文档 | T3/T4/T5 完成 | QA owner |
|
||||
| T6-2 | 否 | 已完成 | 全量验收与冻结 | 状态表、未接入声明、最终测试记录 | T6-1 | Release owner |
|
||||
|
||||
并行原则:
|
||||
@@ -270,13 +270,13 @@ Phase 6 不再继续拆新波次,当前只把 Phase 2 到 Phase 5 的最小验
|
||||
| P3-C 方洞评估包 | 可与 P3-A、P3-B、P3-D 并行 | 部分回归通过 | 判断 `square-hole` 保留 Agent 形态还是迁表单/图片工作台 | 不直接大改实现 | 例外或迁移方案、字段清单、风险、验收用例 | 文档评审通过;若改代码,补对应工作台测试 |
|
||||
| P3-D 大鱼评估包 | 可与 P3-A、P3-B、P3-C 并行 | 部分回归通过 | 判断 `big-fish` 保留 Agent 形态还是迁表单/图片工作台 | 不直接大改实现 | 例外或迁移方案、字段清单、风险、验收用例 | 文档评审通过;若改代码,补对应工作台测试 |
|
||||
| P4-A RPG 例外包 | 可与 P4-B、P4-C 并行 | 自动回归通过 | 明确 RPG 对话式工作台如何接入统一阶段、错误、完成、发布去向 | 不把 RPG 当新增玩法默认模板 | 例外声明、阶段映射、刷新恢复和发布验收 | RPG 指定 interaction 测试、作品详情/进入世界回归 |
|
||||
| P4-B 视觉小说例外包 | 可与 P4-A、P4-C 并行 | 自动回归通过 | 明确视觉小说特殊生成和结果页边界 | 不迁入外部平台社区、支付、榜单、回放 | 例外声明、上传资产口径、生成/结果/发布验收 | `npm run check:visual-novel-vn11` 和视觉小说相关测试 |
|
||||
| P4-B 视觉小说例外包 | 可与 P4-A、P4-C 并行 | 自动回归通过 | 明确视觉小说特殊生成和结果页边界 | 不迁入外部平台社区、支付、榜单、回放 | 例外声明、上传资产口径、生成/结果/发布验收 | 视觉小说创作、结果和运行态相关测试 |
|
||||
| P4-C 汪汪声浪决策包 | 可与 P4-A、P4-B 并行 | 自动回归通过 | 判断 `bark-battle` 是特殊工作台例外还是回到表单模式 | 不同时做两套入口 | 决策记录、阶段映射、发布和 runtime 验收 | Bark Battle 创作、发布、runtime 指定测试 |
|
||||
| P5-A 结果页矩阵包 | 可与 P5-B、P5-C、P5-D 并行 | 最小回归通过 | 列清每个玩法结果页能力、缺口和最小补丁 | 不在结果页新增无需求的大功能 | 结果页能力矩阵、局部重试/上传/发布边界 | 对应结果页测试和手测记录 |
|
||||
| P5-B 作品架恢复包 | 可与 P5-A、P5-C、P5-D 并行 | 最小回归通过 | 生成中、失败、待发布、已发布都能从作品架恢复 | 不只靠前端内存 notice | 作品摘要字段、作品架 adapter、恢复测试 | 作品架相关 interaction 测试;移动端草稿 Tab smoke |
|
||||
| P5-C 公开 read model 包 | 可与 P5-A、P5-B、P5-D 并行 | 最小回归通过 | 公开列表、详情、分享和推荐 runtime 对齐后端 read model | 不让前端拼源表当事实源 | 后端 read model/BFF 缺口清单和实现 | 公开列表/详情/API smoke;必要时 `npm run dev:api-server` + `/healthz` |
|
||||
| P5-D 统一反馈包 | 可与 P5-A、P5-B、P5-C 并行 | 最小回归通过 | 错误和异步完成统一进入平台弹窗 | 不在页面内重复裸错误 banner | `PlatformErrorDialog`、`PlatformTaskCompletionDialog` 覆盖矩阵 | 平台弹窗测试、跨流程失败/完成手测 |
|
||||
| P6-A 门禁包 | 串行,依赖 P3/P4/P5 | 已完成 | 固化跨玩法自动测试、竖屏手测和 API smoke | 不继续接新玩法 | `quality-gates/`、冻结前命令集合 | 跨玩法回归与冒烟门禁通过 |
|
||||
| P6-A 门禁包 | 串行,依赖 P3/P4/P5 | 已完成 | 固化跨玩法自动测试、竖屏手测和 API smoke | 不继续接新玩法 | 冻结前命令集合;现已收敛到根脚本和开发运维文档 | 跨玩法回归与冒烟验证通过 |
|
||||
| P6-B 冻结包 | 串行,依赖 P6-A | 已完成 | 更新总状态表,标记已统一、例外接入、暂不接入 | 不遗留“状态未知”玩法 | 总进度、风险清单、后续维护规则 | `npm run check:encoding`、关键门禁通过、文档索引有效 |
|
||||
|
||||
### 并行执行注意事项
|
||||
@@ -370,6 +370,6 @@ Phase 6 不再继续拆新波次,当前只把 Phase 2 到 Phase 5 的最小验
|
||||
1. 将 Round 4 / Phase 6 作为当前冻结基线,后续只做同口径回归,不再新增波次。
|
||||
2. 对 Phase 3、Phase 4、Phase 5 只处理回归发现的真实缺口,不扩新玩法。
|
||||
3. 更新冻结状态表,明确每个玩法是已统一、例外接入还是暂不接入。
|
||||
4. 后续新增玩法默认遵循本文档和 `quality-gates/【玩法创作】跨玩法回归与冒烟门禁-2026-05-30.md`,无需再补新的总计划轮次。
|
||||
4. 后续新增玩法默认遵循仓库入口规范、当前开发运维文档和现役定向测试,无需再补新的总计划轮次。
|
||||
|
||||
当前轮次看 Round 4 / Phase 6;Round 0~4 已作为历史完成记录保留。
|
||||
|
||||
@@ -95,6 +95,59 @@
|
||||
- 运行页已直接移除“测试切片”控制行及其本地播放/序号状态和样式,只保留游戏运行画面、信息展示与数值微调;AppSurface 合同同时锁定该控件不再渲染、对应 CSS 不再存在。
|
||||
- 当前 direct 产物是多文件入口,而历史 `validate_game_html_smoke` 仍按单文件内联 HTML 契约检查;本次 direct 链路不隐藏触发该旧门禁,若要把多文件产物纳入旧门禁需另行设计读取工作区文件的验证契约。
|
||||
|
||||
## 7.1 默认纯转发收口(2026-08-19)
|
||||
|
||||
### 已确认偏差
|
||||
|
||||
- 虽然普通聊天已经调用 `chat_with_game_creator_direct_codex`,`direct_runtime` 仍会在每条消息前自行判断美术、在消息后强制浏览器试玩、二次整改和版本登记。
|
||||
- 这使“你好”“今天多少号”等非项目消息也被包装成游戏交付任务,用户看到了“准备运行当前本地游戏”“静态烟测”等旧 Runtime 痕迹;已有游戏的普通对话同样被强制拖入完整验收。
|
||||
|
||||
### 收口决策
|
||||
|
||||
1. 普通客户端默认链路固定为 `客户端消息 -> 同一项目 Codex app-server thread -> 原样可读回复`。客户端不根据关键词、文件存在性或模型回复推断/决定“新建、续做、生成美术、试玩、修复”。Codex 回合确实改动标准游戏文件后,客户端只按磁盘事实做资源与版本投影,不把投影本身当作另一次创作流程。
|
||||
2. 默认 direct turn 只负责:项目根边界、同线程复用、系统提示词/skills 注入、进程与凭据隔离、协议异常安全错误、消息显示,以及实际文件变更后的确定性客户端投影。它不自动调用陶泥儿生图、浏览器预览、static smoke、二次 LLM 或隐藏返工;没有文件变化的普通聊天不得修改 manifest、revision 或版本。
|
||||
3. Codex 是唯一执行主体:它根据用户消息、系统提示词、工程结构和自身可用工具判断是否聊天、修改已有游戏、创建游戏或执行验证;客户端不得恢复 Supervisor、专业 Agent、harness 或固定游戏流程作为补偿。
|
||||
4. 系统提示词必须清楚区分:非项目问题直接正常回答且不触碰工作区;项目修改按需要读写当前项目;用户明确要求生成/验收时由 Codex自行执行或如实说明工具限制。客户端不以“安全”为由把任意消息重写成生成任务。
|
||||
5. 回归验收至少覆盖同一实际项目中连续发送“你好”“今天多少号”:均不得触发平台美术、预览、试玩、版本登记或文件变更;再发送一个明确项目修改请求,必须仍复用同一 Codex thread 且由 Codex 自行处理,实际变更的 `game/` 文件随后应出现在客户端“游戏代码”和“项目版本”中。
|
||||
|
||||
## 7.2 当前桌面端验收的内置 Codex 侧车 staging 修复(2026-08-20)
|
||||
|
||||
### 现场问题
|
||||
|
||||
- 当前 checkout 执行 `npm run agc` 后,前端 `127.0.0.1:3080`、本地 API `127.0.0.1:8082` 与 SpacetimeDB `127.0.0.1:3101` 均已健康,但桌面壳没有稳定出现。
|
||||
- 原因是 `src-tauri/build.rs` 每次 Cargo 构建都无条件覆盖 `src-tauri/resources/codex/win-x64/codex.exe` 与 `manifest.json`。Tauri dev watcher 将资源写入识别为源码变化,再次启动 Cargo 构建,形成“构建 -> 覆盖约 300 MiB 侧车 -> watcher 重建”的循环。
|
||||
|
||||
### 修复与验收计划
|
||||
|
||||
1. 内置 Codex 侧车继续从锁定的 npm 原生包 stage 到正式 bundle resource,保留版本与 SHA-256 完整性清单;但仅当二进制内容实际变化时复制,且仅当清单文本变化时写入。
|
||||
2. 不取消 `cargo:rerun-if-changed` 对上游侧车与声明文件的监听;上游升级仍必须触发重新 stage,运行时仍拒绝 hash 不匹配的内置可执行文件。
|
||||
3. 真实回归:从干净的本次 AGC dev 进程重启,确认一次必要的首次构建后不再出现连续的 `codex.exe changed` 重建,Tauri 窗口稳定打开;再完成 direct Codex 普通对话与项目修改的客户端验收。
|
||||
|
||||
## 7.3 首页自动创建项目与项目内对话收口(2026-08-20)
|
||||
|
||||
### 收口契约
|
||||
|
||||
1. 首页只保留一个“陶泥儿”创作入口,不展示模式选择,也不在首页渲染用户或助手消息气泡。
|
||||
2. 每次提交非空正文或附件时,客户端对且只对本次提交调用一次 `create_automatic_local_game_project`,在系统文档目录的 `Genarrative GameAgent/` 下分配唯一 `gameagent-*` 工作区;不弹目录选择器,也不复用最近项目。
|
||||
3. 工作区初始化后先把附件导入该项目,再立即进入项目开发工作台;用户原始正文作为 `initialPrompt` 交给 project-bound direct Codex thread。意图理解、是否修改游戏以及后续试玩均在项目内完成,首页不运行 projectless Codex 对话。
|
||||
4. 项目工作台产品文案统一使用“陶泥儿”“智能创作”,不显示“项目总控”“自动执行”“Supervisor”或“专业 Agent”。客户端只做项目创建、附件导入和确定性投影,不恢复旧多 Agent Runtime。
|
||||
5. 首页的创建状态只显示在主输入区;“最近项目”使用独立静态说明,不能复用“正在创建工作区 / 正在回复 / 已回复”等全局状态。
|
||||
|
||||
### 验收合同
|
||||
|
||||
- 普通文本、游戏需求和带附件需求都必须先创建项目,再在 `陶泥儿项目对话` 中出现同一条原始用户消息与 Codex 回复;`chat_with_game_creator_home_direct_codex` 不得暴露为首页 Tauri handler。
|
||||
- 连续点击或连续 Enter 只能创建一个工作区;创建进行中按钮禁用,但编辑器不得生成首页聊天气泡。
|
||||
- 附件必须经 `upload_local_asset` 写入新项目后再交给项目 Codex;不得只把附件元数据留在首页,也不得把浏览器本地路径写入聊天正文。
|
||||
|
||||
## 7.4 真实项目验收发现的 Codex 原生组件闭包(2026-08-20)
|
||||
|
||||
- 真实创建项目时,Codex 0.147.0 能启动 app-server,但首轮文件修改明确失败为缺少 `codex-code-mode-host.exe`;项目只有初始化占位页,未生成游戏。
|
||||
- 根因是旧 staging 只复制 `bin/codex.exe`,没有保留同版本 npm 原生包依赖的 code-mode host、`rg`、command runner、sandbox setup 和 `codex-package.json` 相对布局。
|
||||
- Windows x64 内置资源现按固定白名单 stage 完整原生组件闭包;清单升级为 `genarrative-codex-sidecar.v2`,逐文件记录并校验 SHA-256,Tauri resources 保持 `bin/`、`codex-path/`、`codex-resources/` 布局。资源映射只属于 `tauri.windows.conf.json`,通用配置不得让其他平台在 Tauri build script 阶段校验 Windows 专属文件。API Key、登录状态和用户配置仍不进入安装包。
|
||||
- 同次真实验收还发现 direct 项目页的可访问名称残留“项目总控”;视觉文案虽已是“陶泥儿”,读屏仍会暴露旧产品模型。direct 分支现统一使用“陶泥儿项目对话 / 陶泥儿消息 / 陶泥儿实时回复 / 陶泥儿对话内容”,旧名称只保留给显式 legacy 诊断入口。
|
||||
- 修复后同一客户端已真实写入 `game/index.html`、`game/style.css`、`game/game.js`。客户端必须继续把这次真实文件变化确定性登记为游戏代码和项目版本;该步骤不启动 Supervisor、harness、平台美术或二次 LLM。
|
||||
- direct 产品入口的显式“播放”只做用户授权、本地路径/权限边界和预览服务器启动,不再先执行旧 `game.static_smoke` 的 Canvas-only 形态合同;DOM、Canvas、WebGL 及外链 `game.js` 均可进入客户端运行视图。显式 legacy `/smoke` 与旧诊断入口仍保留原严格检查,不能冒充真实浏览器试玩。
|
||||
|
||||
## 8. 陶泥儿美术闭环与资源分类收口(2026-08-16)
|
||||
|
||||
### 问题
|
||||
@@ -245,3 +298,61 @@
|
||||
2. 若本机目录预检失败,客户端返回稳定的“本机开发者凭据存储目录未安全初始化;未创建远端凭据”分类,不请求远端创建接口、不发起美术生成、不写 operation 或账本,也不刷新登录态或自动重试。
|
||||
3. 远端响应后原子写入仍可能因并发或磁盘故障失败;该极窄路径必须单独分类为“凭据已创建但未能安全保存”,提示用户在账户开发者凭据页面撤销后再试,不能自动创建第二把凭据。诊断和正式 UI 只展示上述安全摘要与恢复建议,不包含 access token、开发者凭据、响应正文、绝对路径或签名 URL。
|
||||
4. 验收先在当前失败项目上恢复:对遗留的空且 owner 不匹配目录做可恢复隔离后,再复用同一项目发送“继续完成此前三消游戏”。成功标准包括本机私钥存在但不读取其内容、平台素材与版本登记完成、desktop/mobile Chromium 试玩证据和隔离进程恢复;此前已创建但无法恢复的远端孤儿凭据作为明确剩余风险,绝不自动撤销。
|
||||
|
||||
## 14. 审核 AGC Skill Pack、按需加载与真实工具内核(2026-08-20)
|
||||
|
||||
### 14.1 目标架构
|
||||
|
||||
普通项目链路固定为 `薄 Runtime + Codex 唯一执行 + 按需 Skill + 真实工具`。Runtime 不再通过关键词、固定步骤或产物字符串计数替 Codex 判断用户意图,也不恢复 Supervisor、专业 Agent 或 harness;它只负责工作区、凭据、不可逆副作用、进程协议和确定性客户端投影。
|
||||
|
||||
系统提示词只保留最小核心约束、当前项目文件的有界快照和一份审核 Skill 索引。不得再把项目中的 `.codex/skills`、`.agents/skills`、`.hermes/skills` 全文批量拼入 64 KiB 提示词,也不得把主站全部 Skill 复制给普通游戏项目。完整 `SKILL.md` 与直接引用文件由 Codex 原生 Skill 机制在命中意图后按需读取。
|
||||
|
||||
### 14.2 审核索引与五类 Skill
|
||||
|
||||
客户端内置 `agc-skill-pack.v1` 清单。每项只公开名称、用途、触发条件、所需工具、版本和内容 SHA-256;审核文件变化时必须在同次变更重算对应指纹。启动时逐文件复核清单和编译进客户端的内容,任何缺失、额外文件、路径越界或指纹不匹配都失败关闭;路径边界显式拒绝反斜杠、Windows 盘符、UNC、绝对路径和 `..`,不能因测试运行在 Linux 就把 Windows 绝对路径当作普通相对文件名。审核包只包含:
|
||||
|
||||
1. `agc-project-structure`:项目根、`game/`、`assets/`、`.agent/` 的职责和禁止创建平行项目的约束。
|
||||
2. `taonier-art-assets`:陶泥儿标准美术包、平台来源、警告语义和真实素材使用;`grid-2x2` 与四切片只是推荐路径,不是所有游戏的完成门。
|
||||
3. `agc-web-game-development`:根据当前需求自由选择 DOM、Canvas 或 WebGL,并完成可玩的 HTML/CSS/JavaScript 实现。
|
||||
4. `agc-browser-playtest`:调用客户端提供的真实双视口浏览器工具,读取截图、控制台、网络、Canvas/WebGL 和交互证据后自行修复。
|
||||
5. `agc-client-projection`:解释客户端如何按磁盘事实投影代码、素材、revision 和版本;Codex 不直接伪造或改写 manifest 中的平台身份。
|
||||
|
||||
`genarrative-external-editor-api` 的异步、凭据、operation 和 warning 语义经审核后融入 `taonier-art-assets`;不把原始主站技能目录直接暴露给游戏项目。`gpt-image-2-apimart` 只有在对应受控工具真正配置时才能作为显式备用能力,首版不以文字假装可用。`genarrative-play-type-integration`、SpacetimeDB、微信支付和其它主站工程 Skill 明确排除。
|
||||
|
||||
### 14.3 渐进加载实现
|
||||
|
||||
DirectProject app-server 启动前,把上述审核包安装到本次隔离 HOME 的 `.agents/skills/`;DirectHome 不安装项目创作 Skill,也不暴露项目工具。Codex 首轮只得到五项元数据和索引,不得到完整正文;触发后由原生 Skill 读取对应 `SKILL.md`,引用最多一层且只能命中清单文件。项目内任意 Skill 不再由 AGC 提示词构建器主动读取或拼接。
|
||||
|
||||
Skill 包版本与内容指纹参与 DirectProject app-server 连接池身份。客户端升级或 Skill 内容变化后必须建立新进程/新 thread,不能复用旧目录中的过期 Skill;同一版本的连续聊天仍复用同一 Codex thread。
|
||||
|
||||
### 14.4 真实工具与安全边界
|
||||
|
||||
DirectProject 仅配置客户端自身的本地 stdio MCP,首版暴露三个受控工具:
|
||||
|
||||
- `agc_read_skill_resource`:只读取审核清单中某个 Skill 直接声明的一层 `references/*.md`;不接受绝对路径、`..`、未声明文件、主站 Skill、项目文件或宿主文件。它补足禁用通用 shell 后的渐进引用读取能力,不扩大工作区权限。
|
||||
- `taonier_prepare_game_art`:按 Codex 提供的游戏 brief 创建或恢复陶泥儿标准美术包。工具内部继续使用当前 External v1 请求、持久生成账本、稳定幂等键和 `operationId`;未知提交只轮询或以原请求/原 key 恢复,绝不因模型重试重新扣费。完整可信图集缺切片时返回 warning 并保留完整图集,不能伪造切片或阻断后续代码实现。
|
||||
- `agc_browser_playtest`:由当前客户端启动 loopback 预览和受限 Chromium,对 desktop/mobile 采集真实截图、页面状态、控制台异常、失败请求、Canvas/WebGL 图片使用与有限交互探针,并把结构化证据和截图作为工具结果返回 Codex。该工具不使用旧固定玩法 harness。
|
||||
|
||||
MCP 子进程复用当前客户端二进制的专用无窗口模式,从工作目录取得唯一项目根;命令行不传项目路径或凭据。它只处理 MCP 和审核引用读取;真实浏览器与付费美术通过随机 loopback 地址回到持有项目上下文的客户端主进程执行,避免 Codex 隔离用户环境阻断 Chrome,也避免把 GUI 登录态复制给子进程。陶泥儿开发者 Key 只由客户端主进程按受信任 origin 从当前用户私有文件读取并在内存中使用,不进入 Codex 环境变量、系统提示词、argv、项目文件、日志或工具结果。凭据缺失时工具返回可行动的“先在客户端登录并准备本机开发者 Key”,不得假装生成成功。
|
||||
|
||||
DirectHome 继续禁用 MCP、命令和写入。DirectProject 仍禁用通用 shell、任意网络和多 Agent;文件修改只走 Codex 受限原生能力,外部副作用只走上述本地工具。付费生成、路径权限、文件事务、图片下载/解码、来源身份和客户端投影继续由确定性代码守住。
|
||||
|
||||
### 14.5 验收合同
|
||||
|
||||
- Rust 单测:清单五项精确、SHA-256 匹配、路径无越界;新项目没有本地 Skill 目录仍能安装审核包;DirectHome 不安装;项目中的主站/SpacetimeDB/支付 Skill 不进入系统提示词。
|
||||
- 提示词测试:普通问候只包含索引,不包含任一完整 Skill 正文;美术 Skill 正文由 Codex 原生触发读取;API Key、Bearer、auth.json、宿主绝对路径不进入上下文。
|
||||
- fake app-server:DirectProject 配置本地 MCP 且 DirectHome 保持 `mcp_servers={}`;连续回合复用 thread;MCP item 可完成而不是被当成协议违规;无 Supervisor/child/harness。
|
||||
- MCP 协议测试:initialize、tools/list、tools/call 均为有界 JSON-RPC;未知工具、路径越界、缺凭据明确失败;美术调用复用同一账本/operation,不重复提交;浏览器调用返回双视口真实报告和截图内容。
|
||||
- 回归:typecheck、AppSurface、Rust 定向与完整串行测试、编码检查、rustfmt 和 diff check 全部通过。
|
||||
- 真实客户端:从当前 checkout 新建项目,由同一项目 Codex thread 自主选择陶泥儿美术 Skill、调用真实平台工具、写入游戏、调用真实浏览器试玩并按证据修复;客户端最终显示平台美术、游戏代码和项目版本。单独验证“你好”“今天多少号”不调用美术或浏览器工具、不改文件、不登记版本。
|
||||
|
||||
### 14.6 当前实施与验收状态(2026-08-20)
|
||||
|
||||
- 五项审核 Skill 已由版本化清单和逐 Skill SHA-256 编译进客户端;DirectProject 初始化后显式调用 `skills/extraRoots/set` 与 `skills/list`,缺项或解析错误直接失败。DirectHome 不安装该包。项目内 `.codex/.agents/.hermes` Skill 正文不再被系统提示词批量拼接。
|
||||
- 本地 `agc_tools` MCP 已实际暴露 `agc_read_skill_resource / taonier_prepare_game_art / agc_browser_playtest` 三项工具并固定自动审批;引用读取严格限制为清单内一层 Markdown。真实 `gpt-5.6-sol max` 回合已读取 `agc-project-structure` 的直接引用并正确返回路径边界。
|
||||
- 浏览器和美术副作用由随机 loopback 工具桥回到客户端主进程;真实 Codex 工具调用已得到 desktop/mobile `readyState=complete`、整体 `passed=true` 与 2 张截图。普通“你好,今天多少号”真实回合只回答日期,游戏文件、manifest、revision 均未变化。
|
||||
- 开发网关会在 API Key Responses 成功响应中附带 `X-Codex-*` ChatGPT 额度头;隔离 app-server 会把它误判为余额 0。Direct conversation 现经只接受 Bearer `/responses` 的 loopback 流式代理转发,并剥离该组账户头;真实回合从 `usage-limit-exceeded` 恢复为完成。旧 ToolHost 不经过此代理。
|
||||
- 2026-08-21 真实客户端复跑已由当前登录会话为所选服务端建立新的私有开发者 Key;旧失效文件只改名保留,不读取、不打印也不提交。Codex 经 `taonier_prepare_game_art` 成功生成并登记 `assets/art-spec.png`、`assets/direct-game-background.png` 与 `assets/art-spritesheet.png`,三项均带平台 Canvas 来源身份。首次回合中第三个 `art-spritesheet` operation 已以稳定幂等键受理;重启客户端后只恢复该 operation,随后再次调用完整美术包时仍只有同一账本和 operation,三个 PNG 时间戳不变、账户泥点不再下降,工具两次均返回 `status=completed`、3 个 `assetPaths`、3 张图片且无 warning。
|
||||
- 同一真实项目已由 Codex 把平台背景、规范图棋子和核心图集实际接入 `game/index.html / style.css / game.js`。真实 Chromium 报告 `passed=true`:desktop/mobile 均为 `readyState=complete`、Canvas 非空、无 console error 与 exception;desktop 仅有非致命 `favicon.ico` 404。两张截图确认桌面和手机均完整显示甜点星球三消画面,且结构化运行时证据观察到平台图片进入渲染。
|
||||
- 真实复跑同时暴露并修复两个收尾缺陷:DirectProject 不能沿用普通 LLM 的 180 秒整回合超时,现改为 15 分钟基础空闲窗口、MCP 工具活动期 110 分钟空闲窗口、整个 turn 120 分钟硬上限;DirectHome 与旧 ToolHost 继续保持原超时。系统提示词和浏览器整改回灌同时明确 shell/unified_exec 被安全禁用时应使用已注入的游戏文件快照与结构化证据,不得误报“没有读取工具所以无法验收”,也不得要求 Codex 直接保存 `.agent` 版本。定向回归为 Direct Runtime 35/35、Codex app-server 23/23(另 1 项真实账号测试按设计 ignored)。
|
||||
- 最后一轮改后 GUI 复验在桌面控制被物理 Escape 中止后未继续自动操作;非 UI CLI 又因不继承 GUI 登录态而得到 `usage-limit-exceeded`。因此本节只把已落盘的真实生图、幂等复用和双视口浏览器证据记为已完成,不把改后最终聊天回复或新增项目版本伪报为已验收;下次从当前客户端发送普通项目消息即可复核新的等待窗口与证据回灌文案。
|
||||
|
||||
@@ -183,6 +183,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- **结论**:`WP1` 的 `repair_depth≤1` 结论未被推翻;Unknown 只增加前向不兼容时的保守阻塞,不会放宽普通做游戏链路的返工深度门。
|
||||
- **验收门禁与关联**:定向回归须覆盖未知 raw round-trip、barrier/waiting、无条件返工拒绝、保守 lineage 分类,以及损坏 sidecar 整体锁死;详见技术方案第 23.7 节裁决三与第 23.8 节 `M1C-0b` 门禁。
|
||||
|
||||
## 2026-08-15 完美像素编码前按整数倍 nearest 放大到接近源图
|
||||
|
||||
- 背景:2026-08-10 起成功产物直接落逻辑网格 PNG,画布按资源实际宽高显示,结果会明显小于源图。用户要求保持逻辑图宽高比,并把产物放大到接近原图;禁止再走非整数 nearest 拉回精确源尺寸(会让逻辑块宽窄不一)。
|
||||
- 决策:`style="pixelArt"` 与手动 `POST /api/editor/images/pixel-art-snaps` 仍共用 `snap_pixel_art_with_grid_policy`。检测、切线、采样、Alpha、strict 拒兜底不变。`resample` 之后、`encode_png` 之前,用单一整数 N 做 nearest 放大:`N*` 为 `(C·W + R·H) / (C² + R²)`,在 `floor` / `ceil`(小于 1 当 1)中取距离平方更小者,并列取较小 N;超单边 `10000` 或总像素 `8294400` 则降 N,最低 `N=1`。只持久化这一张 PNG。手动算法指纹升为 `perfect-pixel-v3`。
|
||||
- 不做:改 walker、透明补边、裁切、横纵不同倍率、Lanczos / bilinear、另存逻辑图、前端框缩放、失败路径、新测试。
|
||||
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`、`docs/【编辑器】画板角色形象生成入口设计-2026-06-15.md`、`docs/【编辑器】画板图标素材生成入口设计-2026-06-15.md`、`docs/【编辑器】图片画布结构化持久化与迁移回滚方案-2026-07-19.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-08-15 AGC game-chat 主代码 Run 接管直属美术 delivery
|
||||
|
||||
- 背景:真实 `gpt-5.6-sol / max` 验收中,`art-director` 失败后已形成 `ready + needs-repair` delivery,但认领、合同读取、claim observation 和完成 blocker 均硬编码为 Supervisor-only;实际直属父 Run `code-prototype` 无法消费回执,随后又发起 29 次 Provider 请求。
|
||||
|
||||
@@ -536,15 +536,6 @@ H5 支付链接跳转在原生壳声明 `app.openExternalUrl` 时必须优先走
|
||||
该命令同时会运行微信小程序 `miniprogram/host-bridge/`、`miniprogram/shell/`、`pages/web-view` 样式和 `scripts/miniprogram-web-view-auth.test.ts` 的壳层测试,保证微信桥接层拆分后的支付、订阅消息、九宫切图、分享目标和 WebView 登录 / 分享入口行为与 Expo、Tauri 壳一起验收。
|
||||
该命令还会反查微信小程序 `app.json.pages` 与 `host-bridge/protocol.js` 现役页面 URL、H5 小程序页面常量、WebView 分享入口、分享目标消息类型、`WEB_VIEW_SOURCE_QUERY`、微信请求头运行时标记、H5 runtime parser、H5 路由保留字段和 H5 / API base URL 格式,避免页面路由、来源标记、宿主上下文 query 或域名配置在微信壳、H5 HostBridge 与运行时配置之间分叉。旧生成结果订阅授权页和对应 H5 service 不再进入清单。生产 / 开发 H5 与 API 域名都必须显式配置为纯 HTTPS domain,运行时开发域名回退生产域名只作为异常兜底。
|
||||
|
||||
内容检查:
|
||||
|
||||
```bash
|
||||
npm run check:data
|
||||
npm run check:overrides
|
||||
npm run check:smoke
|
||||
npm run check:content
|
||||
```
|
||||
|
||||
全量检查:
|
||||
|
||||
```bash
|
||||
@@ -559,18 +550,12 @@ npm run check:server-rs-ddd
|
||||
|
||||
## Gitea CI 与 PR 检查
|
||||
|
||||
- 仓库 CI 入口是 `.gitea/workflows/project-ci.yml`,向 `master`、`codex/ai-game-creator-app` 推送和所有 PR 创建、更新时必须运行,也允许手工触发。
|
||||
- 仓库 CI 入口是 `.gitea/workflows/project-ci.yml`,在 `master` push、所有 PR 创建或更新以及手工触发时运行。
|
||||
- CI 固定拆分为 `Repository checks`、`Frontend tests`、`Backend tests`、`Native shell tests` 四个 required job;对应 PR context 完整名称是 `Project CI / Repository checks (pull_request)`、`Project CI / Frontend tests (pull_request)`、`Project CI / Backend tests (pull_request)`、`Project CI / Native shell tests (pull_request)`,首次运行后仍须从 Gitea 最近一周 context 表复核。测试使用独立 job,不能只藏在综合检查 step 中;原生壳验收单独运行以便定位重型构建失败。
|
||||
- 四个 job 共同覆盖 `npm run check`,并追加 `npm run check:server-rs-ddd`、`cargo test --locked --workspace --no-fail-fast --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --all-targets --manifest-path server-rs/Cargo.toml` 和 `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`。Backend job 必须先用 `cargo fetch --locked` 的 5 次整命令级有界重试准备当前 `server-rs` 锁定依赖,再进入会触发 `cargo build` 的 DDD / module-runtime 产物边界门禁;不得把依赖准备放在该门禁之后,否则镜像缺少锁新增 crate 时会在首次 registry / TLS 抖动处提前失败。后端 runner 安装 `ffmpeg`,避免视频抽帧测试因工具缺失提前返回。`codex/ai-game-creator-app` 分支必须用独立 lockfile 安装 AI 游戏创作壳依赖,其原生壳入口还必须覆盖 `npm run ai-game-creator-shell:check`、release build smoke,并检查 AI Tauri `Cargo.lock` 不漂移。原生壳 job 还要通过 Google 官方签名 APT 源安装 `google-chrome-stable`,用于 headless preview 的真实 DOM / canvas smoke;同时安装 `ripgrep`,把 `actions/setup-node` 的完整 Node.js 22 发行目录与 root-owned rustup proxy 映射到 `/usr/local`,供只接受受信任系统命令目录的 `command.exec` 沙箱测试使用,不能放宽生产命令目录白名单。Tauri 的 1132 项级别 suite 固定 `--test-threads=1`,避免共享 Agent Runtime 后台锁与异步终态在 libtest 并行调度下互相干扰。
|
||||
- 四个 job 共同覆盖根检查、前端与脚本测试、生产运维 fixture、server-rs DDD/workspace 测试和原生壳验收;AI 游戏创作壳检查与 release build smoke 对所有触发方式一致执行。
|
||||
- checkout 必须使用完整历史。PR 将 base SHA 写入 `SPACETIME_SCHEMA_BASE_REF`,直接推送 `master` 使用 before SHA;事件基线不可解析时直接失败。Gitea 检查的是 PR head 而非预合并 commit,workflow 必须拒绝不包含最新 base commit 的过期 PR,分支保护同时保持“PR 过期禁止合并”。
|
||||
- 普通 PR job 不读取业务 secret,不运行真实 API/SpacetimeDB/OSS/支付/生成/live smoke,也不执行会修改外部状态的维护、迁移、发布或备份命令。
|
||||
- Gitea 至少升级到 `1.26.4` 后才能注册执行 PR job 的 runner;`ubuntu-latest` 标签只映射到固定 digest 的 Ubuntu 24.04 级 Docker/临时隔离镜像,不使用浮动镜像 tag,不映射 host,不向 job 暴露 Docker socket、业务 secret 或不必要内网。runner 能访问 Gitea、GitHub Actions 与 `actions/node-versions`、nodejs.org、npm、Rust 分发、crates.io 和 Google Chrome 的 `dl.google.com` 官方签名 APT 源;workflow 的官方 action 固定完整 commit,若内网禁用 GitHub,先在当前 Gitea 镜像对应 commit 并改用绝对 URL。受控镜像优先预装 rustup。Gitea 1.26 的任务超时由 runner 全局配置控制;首次运行成功后,`master` 分支保护必须要求上述四个 job 全部成功。
|
||||
- `genarrative-station` 当前使用 Gitea `1.26.4` + 基于 Runner `2.0.0-dind-rootless` 的固定 digest 修补镜像:只修复 `systempaths=unconfined` 的空 slice 被 `mergo` 丢失,真实 job 必须保持 `MaskedPaths=[]`、`ReadonlyPaths=[]`;外层仍非 privileged、无 `CAP_SYS_ADMIN`,内部 Docker 只监听 Unix socket,`docker_host: "-"` 阻止 socket 进入 job。job 只在 `gitea-actions` internal network,通过 `/git` reverse gateway 访问 Gitea,通过拒绝私网、保留地址和 metadata 的 80/443 proxy 访问公共依赖;直连公网和 Gitea 数据网必须失败。内层 bwrap 所需 namespace/proc 选项只能用于该 rootless DinD,不能放宽宿主 rootful runner。系统依赖步骤在 root job 中不调用 sudo,非 root 时用 `sudo -E` 保留受控 proxy;Cargo 关闭 HTTP multiplexing 并设置 10 次网络重试,rustup bootstrap/toolchain 安装也按有界次数重试。AI 原生壳 job 把 Node 发行目录与 rustup proxy 安装到 `/usr/local` 的受信任只读路径,并在测试前执行完整 bwrap canary。宿主 compose helper 必须把 `/opt/gitea-stack` 挂到同名绝对路径,避免相对 volume 错误落到 `/stack` 空目录。
|
||||
- 四个 job 共同覆盖 `npm run check`,并追加 `npm run bgfilter-worker:smoke-test`、`npm run check:production-health-patrol`、`npm run check:production-api-release`、`npm run check:production-api-deploy`、`npm run check:server-rs-ddd`、`cargo test --locked --workspace --no-fail-fast --manifest-path server-rs/Cargo.toml`、`cargo check -p api-server --all-targets --manifest-path server-rs/Cargo.toml` 和 `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`。BgFilter 的 `.test.mjs` 使用 Node test runner,必须由 workflow 显式调用;生产巡检 / 发布 / 部署行为检查只运行无密钥临时 fixture,不连接现场环境。`ffmpeg` 由预构建 job 镜像提供,避免视频抽帧测试因工具缺失提前返回。`codex/ai-game-creator-app` 分支的原生壳入口还必须覆盖 `npm run ai-game-creator-shell:check` 和 release build smoke。
|
||||
- checkout 必须使用完整历史。PR 将 base SHA 写入 `SPACETIME_SCHEMA_BASE_REF`,直接推送 `master` 使用 before SHA;事件基线不可解析时直接失败。Gitea 检查的是 PR head 而非预合并 commit,workflow 必须拒绝不包含最新 base commit 的过期 PR,分支保护同时保持“PR 过期禁止合并”。
|
||||
- 普通 PR job 不读取业务 secret,不运行真实 API/SpacetimeDB/OSS/支付/生成/live smoke,也不执行会修改外部状态的维护、迁移、发布或备份命令。
|
||||
- Gitea 至少升级到 `1.26.4` 后才能注册执行 PR job 的 runner。runner 保留 `ubuntu-latest` 固定 digest 映射,并把 workflow 使用的 `genarrative-ci` 映射到 runner 内层 Docker 已装入的完整 Image ID;不映射 host,不向 job 暴露 Docker socket、业务 secret 或不必要内网。当前 CI 镜像约 `1.788 GB`,Image ID 为 `sha256:c04b114b1f145072c9df7842c4c974e1bb2eaaf391d95d84c9212a460546b7d5`,标签映射为 `genarrative-ci:docker://sha256:c04b114b1f145072c9df7842c4c974e1bb2eaaf391d95d84c9212a460546b7d5`。内层 Docker 数据持久化且 `force_pull: false`,该 ID 缺失时失败关闭,不现场拉取或回退浮动 tag。Runner 2.0.0 支持 job 级 `timeout-minutes`,但 runner 全局 `3h` 仍是硬上限;首次运行成功后,`master` 分支保护必须要求上述四个 job 全部成功。
|
||||
- `deploy/container/gitea-ci-job.Dockerfile` 固定 Ubuntu base digest `sha256:58ea92624c7c09582e05594d95488331045053d3a3f34cf09649f2a32313a614`、Rust stage digest `sha256:19817ead3289c8c631c73df281e18b59b172f6a31f4f563290f69cddd06c30e9`、带 SHA-256 校验的 Node `22.23.1`、Google Linux 主签名指纹和 Chrome `150.0.7871.181-1`,预装 Rust 1.96、`rustfmt`、Chrome、`bwrap`、`rg`、`ffmpeg`、`clang/lld` 与 Tauri / 后端系统依赖,并预热根 npm、server-rs 与桌面壳 Cargo 下载缓存。构建脚本使用约 `1.638 MB` 的白名单 tar context,不发送源码、素材或本地私密文件;`cargo fetch --locked` 同时受 Cargo 网络重试和最多 5 次整命令级重试保护,最后必须通过断网 fetch。更新按 `scripts/gitea-ci-job-image.sh build/verify -> export 仓库外镜像归档 -> load-runner -> 确认无活跃 job -> 仓库外备份 config -> 替换 label -> docker restart --timeout 660` 执行;真实 CI 全部通过后才清旧镜像。回滚先把 workflow 改回 `ubuntu-latest`,再恢复 config 备份并重启。备份不进 Git,不在共享文档记录宿主私密路径或注册信息。
|
||||
- runner、隔离镜像、工具链和网络边界的当前配置以 `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 为准,不在共享记忆中复制易漂移的镜像大小、Image ID 或安装步骤。
|
||||
- 四个 workflow job 都使用 `runs-on: genarrative-ci`,先用镜像内脚本直接从 Gitea checkout,再以 `GENARRATIVE_GITEA_CI_CHECK_RUNTIME=1` 运行 `scripts/check-gitea-ci-job-image.sh`,同时校验缓存锁、工具链、完整 bwrap sandbox 和 Chrome headless。workflow 不再包含 GitHub checkout action、apt、setup-node 或 rustup 安装,并设置 `RUSTUP_AUTO_INSTALL=0`;工具链变更时先重建镜像。每个 job 仍各自执行 `npm ci` 以校验 lockfile 和隔离 PR 依赖,但优先复用镜像只读 cache,不烘入 `node_modules`,不挂载跨 PR 可写 Actions cache。`genarrative-station` 继续使用固定 digest 的 Runner `2.0.0-dind-rootless` 修补镜像,真实 job 保持 `MaskedPaths=[]`、`ReadonlyPaths=[]`、`Privileged=false`、`Binds=[]`,`docker_host: "-"` 阻止 socket 进入 job。job 只在 `gitea-actions` internal network,锁文件差量依赖只经拒绝私网、保留地址和 metadata 的 80/443 proxy,直连公网和 Gitea 数据网必须失败;npm 与 Cargo 都设置 10 次网络重试,Cargo 继续关闭 HTTP multiplexing。
|
||||
|
||||
## 后端相关默认验证
|
||||
|
||||
@@ -749,12 +749,12 @@
|
||||
- 验证:`npm run test -- src/components/image-editor/ImageCanvasEditorModel.test.ts src/components/image-editor/ImageCanvasInteractionModel.test.ts`,并在多素材画布拖拽时确认参考线仍能命中邻近图层且 pointermove 不再明显掉帧。
|
||||
- 关联:`src/components/image-editor/ImageCanvasEditorModel.ts`、`src/components/image-editor/ImageCanvasInteractionModel.ts`、`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
|
||||
|
||||
## 图片画布视口拖动卡顿先查自动保存和小地图合帧
|
||||
## 图片画布拖动卡顿先查 Stage 合帧和交互期自动保存
|
||||
|
||||
- 现象:素材多或序列帧多时,拖动小地图视口框或手型平移明显卡顿,像是接口慢或 CSS 动画掉帧,但网络请求不一定异常。
|
||||
- 原因:`pointermove` 高频修改 `viewport` 会触发画布重渲染、小地图模型重算和工程持久化 effect;持久化链路会同步 `serializeCanvasLayout`、`JSON.stringify` 并写 sessionStorage。远端 PATCH 有防抖也挡不住本地同步缓存写入。
|
||||
- 处理:把 viewport 拖动标记为临时交互;拖动中只更新画布显示,不触发项目保存、session cache 写入或封面快照上传,`pointerup` / `pointercancel` 后保存最终 viewport。小地图拖动的 `updateViewportFromMinimapDrag` 必须用 `requestAnimationFrame` 合帧,结束拖拽时 flush 最后一帧。
|
||||
- 验证:`npm run test -- src/components/image-editor/useImageCanvasViewportControls.test.tsx src/components/image-editor/useImageCanvasStageInteractions.test.tsx src/components/image-editor/useImageCanvasProjectPersistence.test.tsx --reporter verbose` 应覆盖小地图拖动合帧、平移 / 小地图 viewport 交互边界,以及拖动期间不写 sessionStorage / 不调用 `saveEditorProjectLayout`。
|
||||
- 现象:素材多或序列帧多时,拖动图层、生成占位、小地图视口框或手型平移明显卡顿,像是接口慢或 CSS 动画掉帧,但网络请求不一定异常。
|
||||
- 原因:高刷新率输入设备会在单个屏幕帧内发出多次 `pointermove`;每次直接 `setLayers` / `setViewport` 都会触发画布重渲染、吸附或小地图模型重算和工程持久化 effect。即使 `moveLayersFromDrag` 保留未移动图层的对象引用,若 WorldView 仍在每帧重建全部图层子树,所有真实位图的 URL hook、加载态、标签和 SVG 操作也会重复执行。持久化链路还会同步 `serializeCanvasLayout`、`JSON.stringify` 并写 sessionStorage,远端 PATCH 有防抖也挡不住本地同步缓存写入。
|
||||
- 处理:Stage 的图层、生成占位、框选和手型平移统一用单一在途 `requestAnimationFrame` 合并同帧输入,只应用最新坐标;结束拖拽时 flush 最后一帧,主动清理和卸载时 cancel。图层、生成占位、平移和小地图拖动一旦越过拖动阈值就标记为临时交互,拖动中不触发项目保存、session cache 写入或封面快照上传,`pointerup` / `pointercancel` 后保存最终布局。WorldView 的完整单图层节点必须按稳定 layer 对象浅比较 memo,父回调通过 latest ref 的稳定门面转发,避免未移动图层重渲染或读取陈旧闭包。小地图继续只在 viewport controls 内合帧,不要重复套 rAF。
|
||||
- 验证:`npm run test -- src/components/image-editor/ImageCanvasWorldView.test.tsx src/components/image-editor/useImageCanvasViewportControls.test.tsx src/components/image-editor/useImageCanvasStageInteractions.test.tsx src/components/image-editor/useImageCanvasProjectPersistence.test.tsx --reporter verbose` 应覆盖只重渲染移动图层、稳定节点调用最新回调、同帧只保留最新坐标、结束前 flush、卸载 cancel、小地图无双重合帧、图层 / 生成占位 / 平移 / 小地图交互边界,以及拖动期间不写 sessionStorage / 不调用 `saveEditorProjectLayout`。浏览器验收必须使用多个独立 raster URL,并区分 rAF 心跳与目标实际位置变化帧;共享 data URI SVG 和包含空闲尾帧的自由 rAF 不能作为拖动流畅证据。
|
||||
- 关联:`src/components/image-editor/useImageCanvasViewportControls.ts`、`src/components/image-editor/useImageCanvasStageInteractions.ts`、`src/components/image-editor/useImageCanvasProjectPersistence.ts`、`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
|
||||
|
||||
## 图片编辑器宣发素材生成器刷新后不要丢快照
|
||||
@@ -4298,6 +4298,27 @@
|
||||
- 处理:CONNECT 一开始就为 client socket 注册 `error / close`,解析完成后为 upstream socket注册同样的双向销毁处理;DNS 返回、写 200 和开始 pipe 前都检查 client 是否已销毁。任一端 error、close 或 timeout 都幂等 destroy 两端,不把普通客户端 reset 写成错误日志。不要用进程级 `uncaughtException` 吞掉问题,也不要只增加 npm/Cargo 重试掩盖 gateway 崩溃。
|
||||
- 验证:在独立 canary 和正式 gateway 上分别并发制造至少 500 次“CONNECT 后立即断开”,随后确认容器仍运行、restart count 不增加、日志无 EPIPE;再通过同一 proxy 对 npm registry 与 crates index 建立完整 TLS 隧道。切换前仍须确认 Gitea 无活跃 run 且 Runner 内层无 job 容器。
|
||||
|
||||
## 独立 AGC lockfile 不能丢失可选 WASM 包的 bundled 依赖节点(2026-08-21)
|
||||
|
||||
- 现象:`npm ci --prefix apps/ai-game-creator-shell` 在安装前失败,报告 lockfile 缺少 `@emnapi/core` / `@emnapi/runtime`;错误版本可能是 registry 当前满足 `^1.11.1` 的最新版,而不是原 lock 中曾记录的版本。
|
||||
- 原因:重写或解决 `apps/ai-game-creator-shell/package-lock.json` 冲突时,保留了 `@tailwindcss/oxide-wasm32-wasi` 对 bundled `@emnapi` 包的声明,却删掉了对应嵌套 package 节点。npm 会重新解析当前 registry 版本并判定 manifest 与 lock 不同步;这不是单一 npm 版本问题,也不表示应用应直接依赖两个 `@emnapi` 包。
|
||||
- 处理:只在最新目标分支执行 `npm install --package-lock-only --ignore-scripts --prefix apps/ai-game-creator-shell`,保留 npm 对 bundled 节点及 `peer` / `optional` 标记的完整规范化结果;确认子包 `package.json` 没有变化,不要手工只补报错中的两个版本。
|
||||
- 验证:至少用 Jenkins 对应 npm major 和当前开发 npm 分别执行干净的 `npm ci --prefix apps/ai-game-creator-shell`,再运行 AGC typecheck、编码检查和 `git diff --check`;根目录 `npm ci` 不能替代独立子包 lock 验证。
|
||||
|
||||
## Windows 专属 Tauri resource 不能写进通用配置(2026-08-21)
|
||||
|
||||
- 现象:Linux CI 已完成 AGC `npm ci`,却在 Tauri custom build command 中报 `resources/codex/win-x64/...exe doesn't exist`;Windows 侧车的 Rust staging 受 `cfg(windows)` 保护,因此非 Windows 构建不会生成这些文件。
|
||||
- 原因:Tauri 会在所有平台校验通用 `tauri.conf.json` 的 bundle resource 源路径;把 Windows x64 资源映射写进通用配置,等于要求 Linux / macOS 也预先拥有不属于其安装闭包的 Windows 可执行文件。
|
||||
- 处理:通用配置只保留跨平台 bundle 项;Windows 原生侧车的完整白名单放入 Tauri 自动合并的 `tauri.windows.conf.json`。不要提交二进制占位文件,也不要让非 Windows build script 下载或伪造 Windows 资源。
|
||||
- 验证:配置门禁断言通用配置没有 Windows resource、Windows 平台配置保留完整固定白名单;Linux 运行原生壳门禁必须越过 Tauri resource 校验,Windows release 仍由 build script 对 npm 原生包、SHA-256 清单和目标布局失败关闭。
|
||||
|
||||
## AGC Skill 指纹与相对路径校验必须跨平台一致(2026-08-21)
|
||||
|
||||
- 现象:内置 Skill 文件集合没有缺失,原生测试却统一报内容指纹不匹配;另一个测试在 Linux 上把 `C:\\temp\\SKILL.md` 判为安全相对路径,受控资源工具可能继续处理 Windows 盘符或反斜杠遍历形式。
|
||||
- 原因:审核文件定稿后未按最终字节重新生成 manifest SHA-256;同时 `std::path::Path` 只按当前宿主语义解析路径,Linux 不会把 Windows 盘符和反斜杠视为绝对路径或分隔符。
|
||||
- 处理:Skill 文件变化与 manifest 指纹更新必须同次提交,并提升审核包版本;资源引用只接受使用 `/` 的普通相对段,显式拒绝反斜杠、冒号盘符、UNC、绝对路径和父目录段,再查询审核清单。不要先把反斜杠替换成 `/` 后再做安全检查。
|
||||
- 验证:逐项按排序后的 `relativePath + NUL + file bytes + NUL` 重算并核对 manifest;Rust 单测同时覆盖 POSIX 绝对路径、`..`、`C:\\...`、`C:/...`、UNC 和反斜杠相对路径,受控 MCP 工具也必须把 Windows 绝对路径投影为 `isError=true`。
|
||||
|
||||
## Gitea CI 预构建镜像不能只靠 tag 判断内容
|
||||
|
||||
- 现象:宿主已重建带日期修订 tag 的 `genarrative/gitea-project-ci` 镜像,但 `genarrative-ci` job 仍跑旧内容,或直接报 image not found;另一种危险操作是只改 runner label,没把对应镜像装入 rootless runner 的内层 Docker。
|
||||
@@ -4787,8 +4808,8 @@
|
||||
|
||||
- 现象:像素规整后的图片虽然保持了源图宽高,放大观察却能看到相邻逻辑块占用的物理列数或行数不同,表现为部分块更宽、部分块更窄;整数倍样例看起来正常,换一张网格数不能整除输入尺寸的图才复现。
|
||||
- 原因:逻辑图宽高为检测后的列数、行数。把 `C × R` 的逻辑图用 nearest 恢复到 `W × H` 时,只要 `W % C != 0` 或 `H % R != 0`,目标栅格就只能在不同逻辑像素间分配 `floor / ceil` 数量的列或行;nearest 能避免混色,却不能让非整数缩放后的块严格等大。只用 `128 × 128 → 64 × 64 → 128 × 128` 这类整数倍测试会掩盖问题。
|
||||
- 处理:最终资产直接编码一格一像素的逻辑分辨率 PNG,不再执行输入 / 交付尺寸 nearest 恢复,也不要求成功输出与源图或占位尺寸相等。普通图片和角色的前置 Lanczos 交付尺寸归一仍用于确定检测输入;平底网格源与透明 RGBA 源仍必须同尺寸,不能把“取消输出同尺寸”误解为放开两个内部采样坐标系。
|
||||
- 验证:使用至少一组逻辑列数或行数不能整除输入尺寸的图片,断言输出宽高等于切线数减一而不是输入宽高;同时核对响应、project resource、账号素材和结果 layer 都记录最终 PNG 实际尺寸,且只持久化一个最终 PNG,没有输入尺寸恢复版、诊断图或额外资源。失败降级用例继续验证 Alpha / 交付尺寸守卫,不应因成功输出改为逻辑分辨率而删除。
|
||||
- 处理:采样仍是一格一像素;编码前只允许横纵同一整数 N 的 nearest 放大,N 取最接近规整输入尺寸的正整数,禁止非整数拉回精确 `W × H`。成品宽高比等于逻辑图,尺寸接近但不保证等于源图或占位。普通图片和角色的前置 Lanczos 交付尺寸归一仍用于确定检测输入;平底网格源与透明 RGBA 源仍必须同尺寸。
|
||||
- 验证:整数倍样例与非整除样例都不得出现宽窄不一的逻辑块;响应、project resource、账号素材和结果 layer 都记录最终 PNG 实际尺寸,且只持久化一个最终 PNG,没有未放大逻辑图、输入尺寸恢复版、诊断图或额外资源。失败降级用例继续验证 Alpha / 交付尺寸守卫。
|
||||
- 关联:`server-rs/crates/platform-image/src/pixel_art_snapper.rs`、`server-rs/crates/api-server/src/editor_project.rs`、`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
|
||||
|
||||
## Codex CLI 节点不能把进程终态当成 Runtime 提交证据(2026-08-10)
|
||||
@@ -4864,3 +4885,17 @@
|
||||
- 原因:测试代码仅为动态生成 RSA fixture 引入 `openssl` dev-dependency,从而把原本使用纯 Rust 加密实现的 crate 额外绑定到本机原生 OpenSSL 工具链;Strawberry 附带的库面向 MinGW,不等于可用的 MSVC OpenSSL SDK。
|
||||
- 处理:测试优先使用明确标记、只供测试的固定 PEM fixture,并继续通过项目自身的密钥解析与签名验证路径覆盖真实行为;不要仅为生成 fixture 引入系统原生库,也不要把 MinGW OpenSSL 路径写入 `OPENSSL_DIR` 冒充 MSVC 依赖。
|
||||
- 验证:运行目标 crate 的 `cargo tree -i openssl-sys --target all` 确认依赖已退出,再执行包含测试目标的 `cargo test --tests`,不能只用不会编译 dev-dependency 的 `cargo check --lib` 代替。
|
||||
|
||||
## 隔离 Codex app-server 会误吃代理的 ChatGPT 额度头(2026-08-20)
|
||||
|
||||
- 现象:同一自定义 Responses endpoint 和 API Key 直接 HTTP 为 200,普通用户 HOME 下的 smoke 也完成,但隔离 `CODEX_HOME/HOME` 的 app-server 在真正发请求前返回 `usageLimitExceeded`,并投影 credits balance 0。
|
||||
- 原因:开发网关把 `X-Codex-*` ChatGPT 账户额度头附在 API Key Provider 响应上;隔离进程没有用户 ChatGPT 额度状态覆盖,Codex 0.147 将这些头当作本地账户限制。模型、Key、MCP 和 Skill 均不是根因。
|
||||
- 处理:只为 Direct conversation 启动随机 loopback `/responses` 流式代理;它不注入 Authorization,只转发请求自带 Bearer,拒绝其它方法/路径并剥离 `X-Codex-*` 账户头。不要复制用户 `auth.json` 来掩盖问题,也不要把 Provider 切换当根因修复。
|
||||
- 验证:同时记录上游直接 200、未过滤时 credits=0/usage-limit、过滤后真实 turn completed;代理测试必须证明无 Bearer 拒绝、路径收窄、正文流式保留和额度头不下传。
|
||||
|
||||
## Codex MCP 子进程不适合直接启动桌面浏览器(2026-08-20)
|
||||
|
||||
- 现象:同一 `agc_browser_playtest` 在普通进程中能返回双视口截图,但从 Codex 启动的 STDIO MCP 子进程调用时 Chrome 启动超时。
|
||||
- 原因:MCP 子进程继承隔离 HOME/AppData 和 Codex 进程约束;把真实浏览器或 GUI 登录态硬塞给子进程既不稳定,也扩大凭据边界。
|
||||
- 处理:STDIO MCP 只做 schema 与协议适配;浏览器和付费美术通过随机 loopback 工具桥回到持有项目、登录态和正常桌面环境的客户端主进程。桥只绑定当前项目、限制请求大小和审核工具名,返回脱敏文本与有界 PNG。
|
||||
- 验证:必须从真实 Codex thread 发起 MCP 调用并观察 desktop/mobile `readyState=complete` 与两张截图;直接运行 MCP 二进制成功不能替代该链路。
|
||||
|
||||
@@ -54,10 +54,10 @@
|
||||
- 普通图片与角色在 provider 回图后先按统一业务像素矩阵尝试交付尺寸归一:允许无放大恢复时使用 Lanczos 重采样并居中裁切,无法安全恢复时保留 provider 实际尺寸并返回非阻断告警。普通图片随后以这张实际交付尺寸图同时作为网格分析源和 RGBA 采样源;角色先持久化同尺寸平底原图并交给 BgFilter,正常成功后把 Alpha 蒙版回贴到该平底原图,再以平底原图分析网格、以透明 RGBA 图采样。图标仍以已持久化的平底 provider 图尺寸为基准,BgFilter 成功并回贴 Alpha 后执行同样的双输入规整。固定首版参数为:分析色数 `16`、Alpha 覆盖阈值 `0.375`、像素格尺寸自动检测、相邻边缘峰间距使用线性插值 `P30` 估算步长、固定色板关闭、K-means 最大采样 `262144`。
|
||||
- 像素规整 CPU 工作使用进程级最大并发 `2`;取得并发许可的排队时间与实际处理时间共享最多 `30` 秒预算,同时不得晚于当前请求 deadline,最终以两者中更早者为准。输入图片任一边不得超过 `10000` 像素,总像素不得超过 `8294400`;超限、排队超时或处理超时均按像素后处理失败的 best-effort 规则保留进入该步骤前的图片。
|
||||
- 单格颜色按 `Σ(A × RGB) / ΣA` 进行 Alpha 加权;单格覆盖率按 `Σ(A / 255) / N` 计算。覆盖率大于等于 `0.375` 且 `ΣA > 0` 时输出硬 Alpha `255`,否则输出严格的 `[0,0,0,0]`;最终 Alpha 只允许 `0 / 255`。分析用 16 色只负责网格识别,不限制最终输出色数。
|
||||
- 逻辑低分辨率图只存在于内存;snapper 在规整内部使用 nearest 恢复到当前 RGBA 输入尺寸,并直接替换原本即将持久化的最终图片字节。普通图片和角色的该输入已经过前置 Lanczos 交付尺寸归一,或在无法安全归一时保留 provider 实际尺寸;图标输入以已持久化平底原图的实际尺寸为准。nearest 不替代前置尺寸归一,规整完成后不再执行第二次 Lanczos 或其它尺寸恢复。角色和图标应复用 Alpha 回贴阶段已经读取的平底原图;确需重新读取时,最多增加一次对已有 provider 对象的 OSS GET,不得新增 OSS PUT。
|
||||
- 逻辑网格图只存在于 snapper 内存;采样后按单一整数倍 nearest 放大到最接近规整输入的尺寸,再编码为唯一最终 PNG。横纵共用同一 N,保持逻辑图宽高比,禁止非整数拉回精确源尺寸、补边、裁切或 Lanczos / bilinear。普通图片和角色的规整输入已经过前置 Lanczos 交付尺寸归一,或在无法安全归一时保留 provider 实际尺寸;图标输入以已持久化平底原图的实际尺寸为准。整数倍放大不替代前置尺寸归一,规整完成后不再执行第二次尺寸插值。角色和图标应复用 Alpha 回贴阶段已经读取的平底原图;确需重新读取时,最多增加一次对已有 provider 对象的 OSS GET,不得新增 OSS PUT。
|
||||
- 像素模式的持久化增量必须为零:普通图片仍只上传原有一张最终主图;角色仍只保留原有 provider 原图与透明主图;图标仍只保留原有 provider 原图、透明图集和实际成功的切片。禁止保存逻辑低分辨率图、像素化前后双份主图、预览图、网格诊断图或报告,禁止新增 asset / resource 类型、项目资源、画布 item、队列 job kind 或数据库字段。
|
||||
- 像素后处理属于 best-effort:失败时保留进入该步骤前的图片,继续原有最终上传与画布完成,并通过既有通用 `warning` 返回非阻断原因,不把任务改为失败或退款。BgFilter 自身失败时仍按原 source-only fallback 收口,像素处理不运行;图标后处理成功后再执行原有自动拆分,拆分告警继续使用现有 `sliceWarning` 语义。
|
||||
- 选中已有静态栅格图层后的 `完美像素` 是独立的一键派生操作,不等同于生成请求上的 `style="pixelArt"`。它不打开参数面板,只处理当前活动图层,保留源图,并在源图右侧创建同尺寸 PNG 派生结果;音频、视频、图片序列和 `character-animation` 不显示该按钮。
|
||||
- 选中已有静态栅格图层后的 `完美像素` 是独立的一键派生操作,不等同于生成请求上的 `style="pixelArt"`。它不打开参数面板,只处理当前活动图层,保留源图,并在源图右侧创建整数倍放大后的 PNG 派生结果;该 PNG 宽高比等于逻辑图,尺寸接近但不保证等于源图;音频、视频、图片序列和 `character-animation` 不显示该按钮。
|
||||
- 完美像素、手动去背景、裁扩和所有图集切片是确定性派生操作,分别保存 `image.perfect-pixel`、`image.remove-background`、`image.crop-expand`、`spritesheet.split` 的 V2 `generationInputs`。四者固定 `fields: []`;存在正式来源资源 / 素材行时只保存服务端权威的 `references[id="source"]`,引用仅用于来源溯源,不是算法参数或可编辑槽位,没有正式行时保存空数组。改造 capability 使用独立 allowlist,四者及历史 `pixel-art-snap-*` 结果永不允许改造;自动切片的 source 是实际被切的透明图集,整张生成图集仍保留原生成 action。
|
||||
- 裁扩创建资源时,未携带 `sourceResourceId` 仍允许保存无正式来源引用的确定性结果;一旦携带该 ID,api-server 必须确认它属于当前 owner 和当前项目,否则以 `400` 拒绝,禁止同时持久化悬空 / 越权 `sourceResourceId` 和空来源配方。
|
||||
- 已有图片像素规整固定调用登录态同源 `POST /api/editor/images/pixel-art-snaps`,复用同一纯内存 Rust snapper、CPU 并发许可和输入尺寸上限。该入口免费、只走当前 HTTP 请求内的 inline 处理,不创建 `external_generation_job`,不刷新或自动打开任务侧栏,也不进入泥点扣费 / 退款链路。它另有一层端点级并发闸(最大 4、等待队列上限 2048),设在首次 IO 之前;队列满返回 `503` 并带 `Retry-After`,等待超预算返回 `504`。30 秒总预算从 handler 入口起算,覆盖归属校验的 SpacetimeDB 读取、OSS 下载、两层排队与规整,不是只算 CPU 部分。
|
||||
@@ -67,9 +67,9 @@
|
||||
- B 层的边界是可验证的、且已确认只服务完美像素:`requiresLiveSession: true` 全仓仅有一处置位(完美像素提交路径),`claimActiveInlineGenerationDialog` / `releaseActiveInlineGenerationDialog` / `hasActiveInlineGenerationDialog` 的全部五个调用点也都在完美像素的提交、重试与恢复上。直接体量:`perfectPixelOperationStore.ts` 203 行(测试 228 行)、`useInlineGenerationPlaceholderExpiry.ts` 140 行(测试 401 行)、`hydratePerfectPixelOperation` 128 行,加上工作流里的恢复 effect 与窗口锚定,生产代码约 1100 行、测试约 2500 行(后两个数字是估算,前面几个是实测)。同为免费、同步、无 durable job 的手动图集拆分只用约 85 行客户端代码(失败即报错,`taskId` 用随机 UUID,无幂等、无对账),是本仓库对同类问题的既有廉价答案;完美像素额外的 B 层是**特例而非范式**,不得据它给其它链路加同样的机制。
|
||||
- 前端提交前先创建关闭 composer 的右侧生成占位,再解析或上传源图以取得稳定引用,随后把版本化 `perfectPixelOperation` 请求快照写入**本机账本**(占位本身只带 `perfectPixelOperationId` 标记)并 flush 当前项目布局,最后才发送 POST。`canvasCompletion.dialogId` 同时作为 operation identity、稳定 task identity 的输入和本地源图上传 ID;同一 operation 的上传路径与后续 POST 请求都不得随机漂移。`sourceImageSrc` 优先由当前图层已有的 `objectKey / resourceId / sourceAssetId` 解析;尚未登记的浏览器本地图片只执行 `ticket → OSS PUT → confirm → objectKey`,不为这条持久化输入换取 signed URL。一个 `AbortSignal` 必须贯穿源文件 fetch / 图片解析边界、ticket、PUT、confirm,完整上传 helper 的可选换签也必须透传同一 signal。正式请求不得包含 `data:` / `blob:`、signed URL 或普通外链。后端在读取源图前必须把该字段解析为当前 owner 已登记的私有 OSS object key,并核对 project / resource / asset 归属。
|
||||
- 源准备与 operation journal 使用两段绝对预算:`ticket → PUT → confirm` 连同源解析共用 90 秒;confirm 成功后形成稳定 `perfectPixelOperation` 并**同步写入本机账本**(`perfectPixelOperationStore`,owner + project 双键的 localStorage),布局里只留 `perfectPixelOperationId` 标记。原先的 strict layout save 通道(60 秒绝对预算、revision ACK 前 POST 为零)已整体删除:账本不再寄生在用户布局上,本机写入不过网络也不受服务端校验影响,同样能保证请求可被追溯。被解除的是**客户端侧**「拿不到 revision ack 就拒发」这一层阻断;端到端依赖仍在——布局 PATCH 被校验拒绝、占位因此从未落库时,POST 仍会被服务端以 409 拒收。POST 前仍然 `await` 一次 best-effort 布局保存——服务端要求占位**此前已经持久化**,否则 `validate_editor_pixel_art_snap_placeholder_exists` 直接 409;但 best-effort 不再提供成功 ACK,因此客户端**无法证明**该前置已满足,只能提高满足它的概率(占位可能已由此前的自动保存落库,PATCH 也可能成功而 ACK 丢失)。该 flush 没有整体上限,所以 75 秒对账窗口必须在 flush 返回、authority 复核通过之后才锚定,且首次提交与人工重试同此口径;锚定只覆盖 `submittedAt / reconcileUntil`,按同一 `operationId` 覆盖账本,request 与 dialog / operation / task identity 逐字节不变。此阶段失败持久化为 `failed + perfectPixelOperation`,保留同一 `sourceImageSrc / dialogId / taskId / request`;重试请求必须与账本中的 POST JSON byte-for-byte 一致且不得重新上传。**明确接受的行为,不是缺口**:占位恢复可删除之后,用户删掉未收口占位再从源图发起会得到第二个 identity,旧的服务端操作若迟到落库就会多出一份素材,两个 `taskId` 无法幂等合并。按上文的优先级判据,这属于「已生成资源丢失关联」而非主链路故障,代价是用户自行删掉多余素材,**不得**通过让本机账本参与防重来「闭合」——那是被明令禁止的「禁止一张图处理两遍」。confirm 成功后浏览器在 operation 首次 PATCH 落库前立即崩溃仍可能留下 object-only 记录;完全消除该窗口需要服务端 durable upload journal,不属于当前前端修复。
|
||||
- 该已有图片入口使用 strict 语义:只接受静态 PNG / JPEG / WebP,GIF、APNG、动画 WebP、图片序列及其它非静态媒体必须在处理前拒绝。strict 与生成风格复用完全相同的 legacy profile、峰值估算、单轴步长补全、walker、采样和编码;仅当横纵两轴都未检测到步长、legacy 即将使用 `min(width,height)/64` 统一网格兜底时拒绝。任一轴已检测到步长时,两条路径行为和输出必须一致。源图读取、解码、尺寸校验、排队、像素规整或 PNG 编码任一步失败 / 超时 / 不适用时,请求失败,不保留原图副本冒充成功,不执行最终 OSS PUT,也不创建 project resource、账号素材或结果图层。成功时只对唯一的逻辑分辨率 PNG 执行一次 OSS PUT,并至多各创建一个 `editor_project_resource` 和一个 `editor_asset`,再按 `canvasCompletion` 写回一个派生图层;resource、asset、响应与图层使用该 PNG 的实际宽高,不要求与源图或占位尺寸相等,也不得另存输入尺寸恢复版、诊断图或前后对比图。
|
||||
- 该已有图片入口使用 strict 语义:只接受静态 PNG / JPEG / WebP,GIF、APNG、动画 WebP、图片序列及其它非静态媒体必须在处理前拒绝。strict 与生成风格复用完全相同的 legacy profile、峰值估算、单轴步长补全、walker、采样和编码;仅当横纵两轴都未检测到步长、legacy 即将使用 `min(width,height)/64` 统一网格兜底时拒绝。任一轴已检测到步长时,两条路径行为和输出必须一致。源图读取、解码、尺寸校验、排队、像素规整或 PNG 编码任一步失败 / 超时 / 不适用时,请求失败,不保留原图副本冒充成功,不执行最终 OSS PUT,也不创建 project resource、账号素材或结果图层。成功时只对唯一最终 PNG 执行一次 OSS PUT,并至多各创建一个 `editor_project_resource` 和一个 `editor_asset`,再按 `canvasCompletion` 写回一个派生图层;该 PNG 是逻辑网格经整数倍 nearest 放大后的结果,宽高比等于逻辑图,尺寸接近但不保证等于源图或占位;resource、asset、响应与图层使用该 PNG 的实际宽高,也不得另存未放大的逻辑图、输入尺寸恢复版、诊断图或前后对比图。
|
||||
- strict 的本次结果事实零写入边界截至首个最终 PNG PUT:所有可预判的引用、归属、类型、静态编码、元数据、网格适用性和 CPU 处理错误必须在此前失败;前置 owner-scoped 项目 / 素材读取仍可能按既有语义懒建默认 canvas / folder,这些基础记录不属于本次完美像素结果。后端先纯计算精确 object key 和候选 project resource,再调用只读 SpacetimeDB preflight 校验自定义素材目录归属、复用权威 completion planner,并执行 legacy / structured 的 2 MiB 总量与 512 KiB 单项门禁;默认目录尚未创建时允许通过,preflight 不写库。preflight 与 PUT / HEAD / 原子 persist 共用 60 秒绝对 deadline;preflight 失败或超时不得 PUT,也不得带 `resultPersistenceStarted`。最终 PNG 的 OSS PUT / HEAD 位于数据库事务外;验证上传结果后,asset object、project resource、账号素材与可选 canvas completion 由单个受 runtime service identity 保护的 SpacetimeDB procedure 在一次事务中原子提交,并重新校验目录、布局、幂等身份与 revision。preflight 不加锁或 reservation,所以通过后若目录或画布并发漂移,最终事务仍可能在 PUT 后拒绝并留下 OSS 孤儿对象;这是本次最小修复明确保留的 TOCTOU 边界。operation 以 `owner + project + canvasCompletion.dialogId` 为作用域,task / object / resource / asset ID 稳定派生,object key 携带规范请求与输入 / 输出摘要形成的 fingerprint;一旦 owner-scoped 项目快照已发现同 operation 的稳定 resource,本次 POST 不再执行 candidate-key exact replay,而是直接返回 `operationResultAlreadyExists=true` 并交由 GET 对账;输入漂移或部分既有事实失败关闭。HTTP timeout/drop 不能撤销已发往远端的 procedure,客户端仍须按稳定 `taskId / objectKey / resourceId` 对账,不能把未收到回包等同于未提交。
|
||||
- 手动入口的算法指纹随逻辑分辨率输出升级为 `perfect-pixel-v2`。在完成请求基础校验、owner-scoped 项目读取与占位验证后,只要同一稳定 `resourceId` 已存在,后端必须在来源解析、OSS GET、像素规整、candidate object key、preflight 与 OSS PUT 前返回 `409 + operationResultAlreadyExists=true`,并携带已鉴权的稳定 `resultResourceId`;不再按 candidate object key 继续 exact replay。前端 initial 与 retry 两条 catch 都按稳定资源与 task GET 项目对账,由权威快照明确 `applied`、`dialog-missing` 或 `conflict`;即使稳定记录的 `taskId` 损坏,也必须据 `resultResourceId` 找到该记录并失败关闭为冲突,不得持续等待。该标记表示旧权威结果已存在,不得与“本次 PUT 已开始”的 `resultPersistenceStarted` 混用;发布时仍须排空旧算法实例以规避独立新操作在 preflight 到提交之间的跨版本 TOCTOU。
|
||||
- 手动入口的算法指纹随整数倍接近原图放大升级为 `perfect-pixel-v3`。在完成请求基础校验、owner-scoped 项目读取与占位验证后,只要同一稳定 `resourceId` 已存在,后端必须在来源解析、OSS GET、像素规整、candidate object key、preflight 与 OSS PUT 前返回 `409 + operationResultAlreadyExists=true`,并携带已鉴权的稳定 `resultResourceId`;不再按 candidate object key 继续 exact replay。前端 initial 与 retry 两条 catch 都按稳定资源与 task GET 项目对账,由权威快照明确 `applied`、`dialog-missing` 或 `conflict`;即使稳定记录的 `taskId` 损坏,也必须据 `resultResourceId` 找到该记录并失败关闭为冲突,不得持续等待。该标记表示旧权威结果已存在,不得与“本次 PUT 已开始”的 `resultPersistenceStarted` 混用;发布时仍须排空旧算法实例以规避独立新操作在 preflight 到提交之间的跨版本 TOCTOU。
|
||||
- `POST /api/editor/images/pixel-art-snaps` 是有副作用的 unsafe POST。客户端不得为它配置 `EDITOR_REQUEST_RETRY_OPTIONS`,请求字节可能已发出后不因 transport 异常或 `408 / 425 / 429 / 502 / 503 / 504` 自动重放;Bearer 中间件在 handler 前以 `401` 拒绝、刷新 token 后的既有认证恢复不属于业务副作用重放,保持通用行为。POST 回包中的 `project / resource / asset` 不是结果 verdict;首次成功回包、未知异常、人工 exact replay 和刷新恢复都只读取项目 GET。`perfectPixelOperation.submittedAt / reconcileUntil` 在 pre-POST flush 返回、authority 复核通过之后、POST 发出之前建立统一 75 秒绝对窗口(该 flush 没有整体上限,锚在它之前会让窗口在请求发出前就烧光),POST 回包不能续期;读取必须立即执行一次,随后退避间隔不超过 5 秒,窗口已过期时仍执行一次即时 GET。每次项目读取使用 `requestJson.deadlineAt` 覆盖缺 token 补票、业务 fetch、401 refresh、重试退避与响应体读取;窗口内单次最多 10 秒且不得越过 `reconcileUntil`,过期后的唯一即时读取最多额外 10 秒。固定判据为:匹配 task 的唯一 resource 加已收口 dialog / 关联图层才是画布成功;dialog 不存在但存在匹配 task resource 才是 asset-only 成功;dialog 仍 generating、dialog 不存在且无匹配 resource、项目始终不可读或窗口耗尽均保持 unknown。素材库刷新只在项目终态后 fire-and-forget,同步抛错、异步拒绝或永久挂起都不得阻塞 verdict、项目快照应用和执行锁释放。
|
||||
- unknown 状态持久化为原 generation dialog 上的 `pending-confirmation + perfectPixelOperation`(账本在本机,布局只留 `perfectPixelOperationId`)。**用户可以随时删除该占位**,任何状态都不例外、也不弹确认:删除不撤销任何在途请求,结果照常落库并进素材库,服务端发现 dialog 已不在会返回 `DialogMissing`;封锁用户删除自己画布上的元素不是可接受的代价。删除后**结果不再自动回填画布**(服务端发现 dialog 已不在会返回 `DialogMissing`),这是用户主动放弃的结果,不得判定为缺陷;但对账本身不会因此停止——当前标签页已经在飞的 Promise 会继续读到终态,本机账本也会以孤儿身份在下次加载被读一次,结果确已落库时仍会提示用户去素材库取。未删除时用户可继续 GET 对账或显式按原 identity 重放。人工重试在 pre-POST flush **之后**才刷新观察窗口(同上一节的锚定口径),POST JSON 必须与持久请求 byte-for-byte 一致,不得按当前画布、目录、类型或标题重建,也不得创建第二个 dialog / task / object / resource / asset。hydrate 后只做 GET,不自动 POST、上传或重建请求。处理成功但事务内权威 dialog 已删除时,后端保留 object / resource / asset 并返回 asset-only 事实,canvas / revision 不变;前端只有在项目 GET 看见匹配 task resource 后才能提示“已保存到素材库”。现有布局 CAS 没有 deletion tombstone,completion 与其它已持久化布局编辑冲突时继续按权威 revision 守卫收口;尚未防抖落库的本地编辑合并不在本批范围。
|
||||
- 删除 generation dialog 的按钮、快捷键和右键菜单必须在写画布历史、清选择或执行低层移除前经过同一请求保护入口。未收口完美像素 operation 与其它占位同样可被立即删除,写正常的 `delete-generation-result` 历史并清理 identity;删除确认只对**计费**生成成立(现成弹窗讲的是「已消耗的泥点不会返还」,而完美像素 `generation_cost_mud_points = 0`),判据收敛为具名的 `requiresGenerationDeleteConfirmation`。低层 `removeCanvasGenerationDialogById` 必须无条件删除——低层对上层抗命正是「占位未删却写出伪历史」的根因。
|
||||
@@ -92,7 +92,7 @@
|
||||
- 吸附阈值以屏幕像素为准,换算到世界坐标后参与拖拽计算;边缘 / 中心线和等距吸附共用同一阈值。拖拽结束后只保存最终图层或生成占位布局,不保存临时参考线。
|
||||
- 项目页封面和画布图片图层必须先渲染项目卡、图层外框、标题、尺寸和操作 chrome;图片换签或解码未完成时,只在图片区域显示轻量加载态,不阻塞外框和文字等低成本信息先出现。
|
||||
- 素材量增大时,拖拽吸附热路径不得对所有素材做全量两两配对。边缘 / 中心线吸附保持线性扫描;等距吸附只在跨轴相交且轴向邻近的候选图层之间计算,避免大量远处素材拖慢 pointermove。
|
||||
- 画布自动保存使用防抖 + 串行队列:图层拖拽、缩放、资源新增和修改结果创建后延迟保存工程快照;如果上一次 `PATCH /api/editor/projects/{projectId}` 尚未完成,只保留最新待保存快照,待当前请求结束后再发送下一次保存,避免慢保存请求并发堆积触发发布入口连接限流。手型平移和小地图拖动属于临时 viewport 交互,拖动中只更新画布显示,不触发 `serializeCanvasLayout`、sessionStorage 项目缓存写入或封面快照上传,`pointerup` / `pointercancel` 后再保存最终 viewport。每次 `PATCH /api/editor/projects/{projectId}` 都必须携带最近一次服务端权威快照或保存 ack 给出的 `expectedRevision`;缺少版本号的请求在 HTTP 写入口直接拒绝,不允许回退到无版本覆盖。接口只返回 `{ projectId, canvasId, revision, updatedAt }` 轻量 ack,不返回完整 project;前端用 ack 更新后续保存版本。生成完成或显式读取返回较新权威快照时,若同项目仍有防抖待保存或在途保存的本地布局,前端必须以新快照的资源和生成终态为权威,只重放本地几何、层序、分组、隐藏、锁定、翻转、viewport、背景色和生成面板编辑,并立即基于新 revision 入队保存;后端新增项必须合入,后端已删除的旧项不得被本地旧快照复活,本地在请求期间删除的旧项也不得复活。
|
||||
- 画布自动保存使用防抖 + 串行队列:图层拖拽、缩放、资源新增和修改结果创建后延迟保存工程快照;如果上一次 `PATCH /api/editor/projects/{projectId}` 尚未完成,只保留最新待保存快照,待当前请求结束后再发送下一次保存,避免慢保存请求并发堆积触发发布入口连接限流。图层、生成占位、手型平移和小地图拖动都属于临时画布交互,拖动中只更新画布显示,不触发 `serializeCanvasLayout`、sessionStorage 项目缓存写入或封面快照上传,`pointerup` / `pointercancel` 后再保存最终布局或 viewport。每次 `PATCH /api/editor/projects/{projectId}` 都必须携带最近一次服务端权威快照或保存 ack 给出的 `expectedRevision`;缺少版本号的请求在 HTTP 写入口直接拒绝,不允许回退到无版本覆盖。接口只返回 `{ projectId, canvasId, revision, updatedAt }` 轻量 ack,不返回完整 project;前端用 ack 更新后续保存版本。生成完成或显式读取返回较新权威快照时,若同项目仍有防抖待保存或在途保存的本地布局,前端必须以新快照的资源和生成终态为权威,只重放本地几何、层序、分组、隐藏、锁定、翻转、viewport、背景色和生成面板编辑,并立即基于新 revision 入队保存;后端新增项必须合入,后端已删除的旧项不得被本地旧快照复活,本地在请求期间删除的旧项也不得复活。
|
||||
- 移动端保留同一套状态模型,底部工具栏可横向滚动,侧边栏默认可收起。
|
||||
- 项目页卡片默认点击打开工程;hover 项目卡片右下角显示 `...` 菜单,菜单承载重命名和删除。选择模式下项目卡片只切换选中态,不进入画布;底部批量工具栏提供全选 / 取消全选、已选数量、批量删除和退出选择模式。
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
- 生成图片点击后显示画布内 `Image Generator` 占位框和跟随占位框的生成输入框,生成失败保留占位和输入状态,生成成功后在占位位置创建真实图层,并让输入框继续跟随该生成图。
|
||||
- 选择 `1K / 2K` 或切换比例后,占位框在待生成和生成中阶段都必须立即显示对应目标像素尺寸;从普通图片、角色、图标图集或 UI 设计图进入改造时同样适用,完成落图前后不得从默认 1K 框跳变为 2K 成品。
|
||||
- 普通图片、角色和图标面板显示 `像素艺术` 勾选项并正确提交 / 恢复 `style: "none" | "pixelArt"`;其它生成或编辑面板不显示该选项。旧 payload、未知字符串、不支持 `kind` 和非字符串输入分别按本方案约定的兼容或错误语义处理。
|
||||
- `pixelArt` 输出 Alpha 只包含 `0 / 255`;普通图片和角色先完成 Lanczos 交付尺寸归一,再由 snapper 使用 nearest 把逻辑网格恢复到同一输入尺寸,规整后不得再次执行尺寸插值。成功和后处理失败两条路径都不得比 `none` 增加 OSS PUT、项目资源、账号素材或画布 item,逻辑低分辨率图不得出现在 OSS 或响应资源快照中。
|
||||
- `pixelArt` 输出 Alpha 只包含 `0 / 255`;普通图片和角色先完成 Lanczos 交付尺寸归一,再由 snapper 按整数倍 nearest 放大到最接近该输入的尺寸,规整后不得再次执行尺寸插值。成功和后处理失败两条路径都不得比 `none` 增加 OSS PUT、项目资源、账号素材或画布 item,未放大的逻辑网格图不得出现在 OSS 或响应资源快照中。
|
||||
- 生成中的占位图聚焦后支持键盘 `Delete` / `Backspace` 删除,不新增可见删除按钮;删除后对应异步回写必须按生成器 ID 判空并丢弃,不能把已删除素材重新落回画布。音乐 / 音频生成占位和已生成音频图层同样必须支持键盘删除。
|
||||
- 画布常用快捷键必须与右上角快捷键弹窗一致;新增快捷键时应同步更新 `ImageCanvasShortcutModel`、快捷键 hook 单测和本方案。输入框、文本域和 contenteditable 聚焦时不得触发画布编辑快捷键。
|
||||
- 撤销或恢复画布布局时不得覆盖同 ID 生成对象当前的任务生命周期、提示词、参考图和结果;上传持久化延迟回填内部资源 ID 不得把安全移动误判为素材替换。生成结果必须在加入画布前写入生成历史,自动适合视图不得覆盖这条栈顶记录。
|
||||
@@ -219,7 +219,7 @@
|
||||
- 素材面板支持按素材名、文件夹名、生成信息、用户可见模型、任务和媒体类型搜索,并支持选择模式框选。选择模式的选中集合以全部上传完成且媒体地址有效的可选素材为有效性边界,不因搜索、折叠或展开变化而收缩;只有素材被删除、进入上传中 / 失败态或媒体地址失效时才剔除对应选择及范围锚点。素材缩略图、标题、元数据和卡片空白区统一作为整行选择命中区:鼠标、键盘、触摸和笔输入单击都只切换当前素材,不替换其它已选素材;`Shift + 点击` 按当前可见顺序把连续区间增量加入现有选择,锚点当前不可见时退化为切换目标素材并建立新锚点。当前搜索结果的全选 / 取消全选只增量增删当前已展开的可见素材并保留其它选择,同时清空上次单项选择的范围锚点。触摸素材卡仍可切换选中态,但触摸列表空白区必须继续滚动,不能捕获为框选;鼠标 / 笔框选坐标必须包含列表滚动偏移,`pointerup` 提交最后坐标,`pointercancel` 只取消。内置、上传未完成、上传失败或无可读来源的素材行不得暴露可用的选择按钮。退出选择模式、关闭素材栏或切换到图层栏时必须同时清空选择锚点、选中集合和框选状态,非选择模式不得残留选中高亮。
|
||||
- 素材选择模式的批量工具栏是素材列表滚动区之外的固定底栏,始终显示跨搜索与折叠状态保留的全部已选数量、当前可见素材全选 / 取消全选、下载、删除和取消;下载和删除作用于完整选中集合,不得只消费当前可见 ID。删除集合中存在当前未显示素材时,必须先用危险确认弹窗明确展示全部删除数量和未显示数量,确认目标使用打开弹窗时的素材 ID 快照;选择集合、可见集合或选择模式漂移后关闭旧确认弹窗,确认前不得执行删除。工具栏自身禁止横向溢出和滚动,空间不足时按钮在工具栏内部换行。不得把工具栏作为滚动列表末项或依赖 `position: sticky` 的自然位置。移动端进入素材选择模式时必须提高素材侧栏高度并允许素材列表纵向滚动,为固定底栏之上至少保留一张素材卡的可操作空间,同时受当前视口高度上限约束,不得在横屏或嵌入式短视口中挤占画布。选择模式隐藏单素材下载 / 重命名动作,进入时清理已有拖拽 / 投放状态,并同时阻断素材行、文件夹空白区的内部素材移动和外部文件投放以及右键菜单,避免批量意图回退成单素材操作。Provider 与 `isEditorInternalProcessingModel(...)` 识别的内部处理模型不得进入搜索索引,避免出现隐藏字段可命中或命中但无可见匹配字段;原始审计元数据只保留给服务端和后台管理读取,普通用户(包括素材 owner)不得通过响应取得。
|
||||
- 图层面板支持按图层名、生成信息、用户可见模型、任务和媒体类型搜索;Provider 与内部处理模型同样不得进入搜索索引。普通用户图层快照也不得携带这些内部字段。支持选择多个图层后创建图层组,组名和 groupId 随画布布局保存。
|
||||
- 小地图支持拖拽视口框,拖动时画布 viewport 跟随移动;`pointermove` 更新必须通过 `requestAnimationFrame` 合帧,结束拖拽时 flush 最后一帧,避免高频 pointermove 直接压垮 React 渲染和项目持久化链路。
|
||||
- 小地图支持拖拽视口框,拖动时画布 viewport 跟随移动。Stage 中图层、生成占位、框选和手型平移的高频 `pointermove` 必须通过单一在途 `requestAnimationFrame` 合帧,同一帧只保留最新坐标;`pointerup` / `pointercancel` 必须 flush 最后坐标,主动清理或卸载必须 cancel,避免迟到回调。图层移动结果必须保留未移动 layer 的对象引用,WorldView 的完整单图层子树按该引用和选中、悬浮、生成、菜单等标量状态浅比较 memo;父级事件回调通过读取最新实现的稳定门面转发,不能因 callback identity 变化击穿全部图层 memo,也不能用自定义比较忽略回调后留下陈旧闭包。小地图保留 viewport controls 内部的单层合帧,不得在 Stage 再套一层 rAF 增加一帧延迟。性能验收使用多个独立 raster 图片 URL、外部可信 pointer 输入和实际位置变化帧,单独运行的 rAF 心跳、重复 data URI SVG 或拖动结束后的空闲帧不得计作拖动 FPS。
|
||||
- 鼠标滚轮默认按设备原始 `deltaX / deltaY` 二维平移画布视口;当按住 Shift 且设备上报 `deltaX = 0` 时,视口输入适配层把 `deltaY` 映射为横向位移并将纵向位移置零,核心平移模型仍只消费归一化后的 X / Y。按住 Ctrl / Cmd 滚轮才缩放画布,并阻止浏览器页面缩放。缩放比例显示保持现有换算口径,最低可缩小到 `5%`。
|
||||
- 工程刷新后能从后端恢复资源、图层布局和 viewport。
|
||||
- “我的”页项目入口能进入 `/project`;项目页能列出工程、重命名 / 删除单个工程、批量选择和批量删除;点击工程后进入 `/editor/canvas?projectid=<projectId>` 并按 query 加载该工程。
|
||||
|
||||
@@ -184,6 +184,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
|
||||
|
||||
- 模式合同:客户端 AppData 配置新增全局 `agentMode`,只接受 `codex_cli / provider`。缺省和新安装默认使用 `codex_cli`,原有 HTTP LLM Provider 路径完整保留并可显式切回 `provider`;切换只影响下一次节点请求,不新增 Runner、任务图、会话库、配置库或业务事实源。
|
||||
- 调度边界:正式 DAG、manifest、Agent task/session/run 身份、队列、锁、委派、all-join、完成门、Provider lifecycle、持久 retry/handoff 与 `needs-reconciliation` 继续由现有 AGC Runtime 掌控。每个被调度节点在 `codex_cli` 模式下直接启动一次非交互 `codex exec` 充当该节点的推理 Agent;Codex 返回当前 Runtime 广告函数的结构化调用,Runtime 仍是唯一 ToolHost,不允许 CLI 自己写项目、执行命令、调用 MCP 或形成第二套 revision / verification 真相。
|
||||
- 安装包侧车:Windows x64 release 固定随 Tauri resource 打包 `@openai/codex@0.147.0` 的原生 `codex.exe`;Rust build script 从 AGC 子包锁定依赖 stage 到 resource,并写入版本与 SHA-256 清单。Windows 侧车映射只写入 `tauri.windows.conf.json`,通用 `tauri.conf.json` 不得让 Linux / macOS 构建依赖未生成的 Windows 二进制。运行时只在文件摘要和 `codex-cli` 版本同时匹配清单时优先选内置侧车;缺失、损坏或版本漂移时跳过它,按既有 npm 安装、PATH 顺序回退。安装包同时携带 Apache-2.0 第三方声明;API Key、`auth.json`、Cookie、Token、用户 `CODEX_HOME`、用户配置和项目数据绝不打包。
|
||||
- CLI 安全边界:CLI 固定使用 argv 启动,禁止 shell 拼接;工作目录使用本次请求专用的空临时目录,不把游戏项目绝对路径写入 prompt、stdout、stderr 或持久记录。调用固定使用 ephemeral、忽略用户配置和 exec rules、read-only sandbox、never approval,并关闭 Codex shell tool;只继承 CLI 运行和认证所需的最小环境,显式移除宿主 `CODEX_API_KEY`。用户级 Codex 登录态继续由本机 Codex 自己读取,API Key、auth 文件、Cookie、Token、`CODEX_HOME` 私有内容不得复制到项目配置、Runtime sidecar、Agent DB、conversation 或日志;stdout / stderr 无换行时也受硬上限约束,stderr 诊断只记录固定分类、字节数和 SHA-256。
|
||||
- 协议边界:Runtime 把既有 `LlmRunRequest` 的消息和当前函数目录编码为有界 prompt,并从同一函数 JSON Schema 生成 Codex structured-output schema。CLI 输出转换为现有 `LlmRunResponse / LlmToolCall` 后,继续经过 native tool / MCP 参数校验、动作上限、权限、pending、receipt、验证与格式修复链;最终回复仍走现有脱敏和唯一提交路径,不新增平行响应协议。
|
||||
- 取消与恢复:Codex 子进程绑定当前 Provider request lifecycle,取消、暂停、Runner draining 或 GUI owner 丢失时终止并回收当前进程;started 后没有可信终态仍沿现有 Provider reconciliation 处理。`agentMode`、CLI 可执行身份和影响输出的 Codex 参数进入 `providerConfigFingerprint`,模式切换不得消费另一模式遗留的 retry/handoff。
|
||||
@@ -1164,6 +1165,14 @@ game-project/
|
||||
- 发布 GUI 内的 Codex CLI 可用性探测(包括候选版本检查和 `app-server --help`)必须与实际 Codex、MCP、Runner 和项目命令一样使用 `CREATE_NO_WINDOW`;读取对话或配置状态时即使连续探测多个候选,也不能创建或闪烁控制台窗口。
|
||||
- Node ESM 脚本必须用 `fileURLToPath()` 把 `import.meta.url` 转为 Windows 本地路径,禁止直接把 URL pathname 交给 `path.resolve()`;真实 agent-run smoke 的浏览器探测覆盖 Windows Chrome/Edge 固定安装位置。开发态 smoke 在旧安装版持有默认 AppData GUI owner 时使用独立 `--config-dir`,不得终止用户现有客户端。
|
||||
|
||||
## 2026-08-20 Direct Codex 审核 Skill Pack 与受控工具内核
|
||||
|
||||
- 普通项目对话只由一个 project-bound Codex app-server thread 执行。客户端系统提示词只放最小工程合同、当前游戏源码有界快照、项目 prompts 和审核 Skill 索引;不再批量读取项目 `.codex/.agents/.hermes` Skill 正文,也不恢复 Supervisor、专业 Agent 或 harness。
|
||||
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;任何审核文件变化都必须同步重算对应清单指纹。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文由 Codex 原生 Skill 机制按意图加载,一层引用只能经 `agc_read_skill_resource` 读取清单内 Markdown。引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和 `..`,不能依赖当前宿主的 `std::path` 语义判断其它平台路径。
|
||||
- DirectProject 只连接客户端内置的 `agc_tools` STDIO MCP,工具固定为审核引用读取、标准陶泥儿美术准备和 desktop/mobile 浏览器试玩。MCP 进程只做协议;真实浏览器和付费 External v1 调用通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key 或项目路径到模型上下文。三项工具固定自动批准,通用 shell、任意网络、多 Agent、插件和外部 MCP 继续关闭。
|
||||
- 陶泥儿生成继续复用既有私有 Key、持久幂等账本、operation 恢复、来源/下载/PNG 解码和 manifest 登记。完整可信图集缺切片可以继续,固定四切片只是推荐路径;凭据失效、来源不明或结果未知时失败关闭,不能自动换 Key 或重新扣费。
|
||||
- 自定义 LLM API Key 路由只在 DirectHome/DirectProject 经 loopback `/responses` 流式代理转发。代理不注入 Key,只要求请求自带 Bearer,并剥离开发网关错误携带的 `X-Codex-*` ChatGPT 账户额度头,防止隔离 app-server 把 API Provider 误判为余额 0;旧 ToolHost 保持原 Provider 行为。
|
||||
|
||||
- 2026-08-12 计划拒绝恢复:结构化 `runtime.plan_update` 被 Runtime 拒绝后,下一轮 Provider 请求按请求级目录收窄到实际项目 mutation 与 `respond_to_user`(已进入协作编排的 Supervisor 保留 `agent.delegate / agent.run_status`),并明确禁止再次规划、读取、搜索或验证;后续已有真实 mutation observation 后解除临时目录,不改变持久 executable policy。
|
||||
|
||||
- Goal Contract 绑定 project、可信根 Run Profile、source task SHA-256 和不可变 fingerprint;同一根 Run 只允许幂等重放完全相同的合同,语义变化必须进入新根 Run。已有合同的根 Supervisor 收到 steer 时,Runtime 必须按旧 rootRunId 串行化转换并在持锁后重验 Session 当前权威 Run,再取消并确认旧 rootRunId 的静态、ready、isolated 整棵树已进入终态或 `needs-reconciliation`;旧树未停稳时拒绝启动 replacement,停稳后才在同一 Session、source 和 Run Profile 创建唯一的新根 Run,不能把新增要求塞进旧合同继续完成。合同摘要作为 `decision` 投影到共享黑板,JSON sidecar 才是权威源;黑板冲突条目和专家事实仍追加保留。
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -52,7 +52,7 @@ v1 只开放以下能力:
|
||||
图片生成、图标 spritesheet 和 UI 素材提取的 completed compact `result` 可携带可选结构化 `warning { code, reason }`;任务查询顶层 `warning` 是可直接展示的有界摘要。外部 OpenAPI 当前公开四个稳定 `code`:
|
||||
|
||||
- `postprocess-failed-source-preserved`:生成成功,但透明处理、像素规整等后处理未完成,接口保留仍可使用的原图或进入该步骤前的结果。
|
||||
- `dimension-restore-fallback`:该告警只描述进入可选 `pixelArt` 处理前的交付尺寸归一结果;无法安全归一时,在该处理边界保留 provider 回图尺寸。它不描述或约束 `pixelArt` 成功后的最终尺寸;若随后像素规整成功,最终产物仍是逻辑分辨率 PNG,不能据此推断最终宽高等于 provider 回图。
|
||||
- `dimension-restore-fallback`:该告警只描述进入可选 `pixelArt` 处理前的交付尺寸归一结果;无法安全归一时,在该处理边界保留 provider 回图尺寸。它不描述或约束 `pixelArt` 成功后的最终尺寸;若随后像素规整成功,最终产物是整数倍放大后的 PNG,不能据此推断最终宽高等于 provider 回图。
|
||||
- `unsupported-image-style`:请求的图片后处理风格未知或不适用于当前生成类型,接口按无风格继续生成。
|
||||
- `multiple-generation-warnings`:同一成功响应合并了不同 `code` 的多条非阻断告警,具体原因按顺序拼接在 `reason`。
|
||||
|
||||
|
||||
@@ -218,10 +218,9 @@ npm run lint:eslint
|
||||
npm run typecheck
|
||||
npm run test
|
||||
npm run build
|
||||
npm run check:content
|
||||
```
|
||||
|
||||
一期创作流程统一化新增 `quality-gates/` 提交前门禁。涉及拼图、抓大鹅、敲木鱼统一创作页、统一生成页或 dev 栈启动脚本时,先执行 `quality-gates/README.md` 列出的脚本,再按对应门禁文档完成体验检查。
|
||||
修改 dev-stack 启动、端口探测、状态文件或退出清理时,先执行 `quality-gates/README.md` 列出的专项门禁;其它改动按本节和仓库入口规范选择现役定向测试,不再维护按历史玩法阶段冻结的平行门禁矩阵。
|
||||
|
||||
综合检查:
|
||||
|
||||
@@ -234,16 +233,16 @@ npm run check
|
||||
|
||||
### Gitea Actions PR 门禁
|
||||
|
||||
仓库级 Gitea Actions 工作流固定为 `.gitea/workflows/project-ci.yml`,在向 `master` 或 `codex/ai-game-creator-app` 推送、创建或更新 PR,以及手工触发时运行。工作流拆成四个必须通过的 job:
|
||||
仓库级 Gitea Actions 工作流固定为 `.gitea/workflows/project-ci.yml`,在向 `master` 推送、创建或更新 PR,以及手工触发时运行。工作流拆成四个必须通过的 job:
|
||||
|
||||
- `Repository checks`:调用唯一入口 `npm run check:repository-ci`,执行 `npm run lint`、主站与后台生产构建、内容数据检查和提交差异空白检查。本地 master `pre-push` 复用同一入口,禁止在 workflow 与 hook 中维护两份近似命令。
|
||||
- `Repository checks`:调用唯一入口 `npm run check:repository-ci`,执行 `npm run lint`、AI 游戏创作壳 AppSurface 定向测试、主站与后台生产构建和提交差异空白检查。本地 master `pre-push` 复用同一入口,禁止在 workflow 与 hook 中维护两份近似命令。
|
||||
- `Frontend tests`:按根 lockfile 与 `apps/ai-game-creator-shell/package-lock.json` 分别执行干净的 `npm ci`,再独立执行根 `npm run test`、`npm run bgfilter-worker:smoke-test`、`npm run check:production-health-patrol`、`npm run check:production-api-release` 和 `npm run check:production-api-deploy`,让 Vitest、Node test smoke harness 及不依赖真实服务的生产巡检 / 发布 / 部署行为 fixture 在 Gitea job 中持续执行;其中 `.test.mjs` 使用 Node test runner,不依赖 Vitest 的 `scripts/**/*.test.ts` 收集规则。
|
||||
- `Backend tests`:先对 `server-rs/Cargo.lock` 执行带 5 次整命令级有界重试的 `cargo fetch --locked`,再执行 `npm run check:server-rs-ddd`、`cargo test --locked --workspace --no-fail-fast`、`api-server --all-targets` 编译和 `spacetime-module` 编译;依赖准备必须位于会触发 Cargo build 的 DDD / 产物边界门禁之前,避免锁新增依赖未命中镜像缓存时绕过既有下载重试。runner 安装 `ffmpeg`,避免视频抽帧测试因工具缺失提前返回。依赖真实服务或密钥的测试必须显式 `ignored`,不能让普通 PR job访问现场环境。
|
||||
- `Native shell tests`:按根 lockfile 与 AI 游戏创作壳独立 lockfile 安装依赖后执行 `npm run check:native-shells`,覆盖微信壳、Expo 和 Tauri 的完整验收,并确认桌面壳与 AI 游戏创作壳的 `Cargo.lock` 都没有被构建过程改写。`codex/ai-game-creator-app` 分支的同名脚本还会执行 `npm run ai-game-creator-shell:check` 和 AI 游戏创作壳 release build smoke;共享 Agent Runtime 后台锁 suite 固定 `--test-threads=1`,不能用并行偶发失败后的逐项通过替代整套稳定门禁。
|
||||
- `Native shell tests`:按根 lockfile 与 AI 游戏创作壳独立 lockfile 安装依赖后执行 `npm run check:native-shells`,对所有触发方式一致覆盖微信壳、Expo 和 Tauri 的完整验收,并执行 `npm run ai-game-creator-shell:check` 与 AI 游戏创作壳 release build smoke;最后确认桌面壳与 AI 游戏创作壳的 `Cargo.lock` 都没有被构建过程改写。共享 Agent Runtime 后台锁 suite 固定 `--test-threads=1`,不能用并行偶发失败后的逐项通过替代整套稳定门禁。
|
||||
|
||||
四个 job 合起来覆盖根 `npm run check`,并补齐根检查没有包含的 BgFilter worker smoke harness、无密钥生产巡检 / 发布 / 部署行为 fixture、server-rs DDD、正式 workspace Rust 测试与现役后端编译门禁。普通 PR CI 不注入业务密钥,不启动真实 API、SpacetimeDB、OSS、支付、图片生成或生产 live smoke;需要现场环境、可变外部状态、Docker 编排或发布凭据的 `check:*` 继续按对应专题和 Jenkins 发布流程执行,不能遍历所有同名前缀脚本冒充 PR 门禁。
|
||||
|
||||
PR checkout 必须保留完整 Git 历史,并把 PR base SHA 传给 `SPACETIME_SCHEMA_BASE_REF`。`check:spacetime-schema` 依赖该基线识别已有表字段删除、改名、重排和改类型;事件给出的基线缺失或本地不可解析时必须直接失败,不能退化为空差异检查。Gitea 的 PR checkout 是 PR head,不是与目标分支的预合并 commit,因此 workflow 还会验证 PR head 包含事件中的最新 base commit;分支保护必须继续开启“PR 过期禁止合并”,过期分支先更新再重跑。向 `master` 直接推送时使用 push before SHA,手工触发时回退到 `origin/master`。
|
||||
PR checkout 必须保留完整 Git 历史,并把 PR base SHA 传给 `SPACETIME_SCHEMA_BASE_REF`。`check:spacetime-schema` 依赖该基线识别已有表字段删除、改名、重排和改类型;事件给出的基线缺失或本地不可解析时必须直接失败,不能退化为空差异检查。Gitea 的 PR checkout 是 PR head,不是与目标分支的预合并 commit,因此 workflow 还会验证 PR head 包含事件中的最新 base commit;分支保护必须继续开启“PR 过期禁止合并”,过期分支先更新再重跑。向 `master` 直接推送时使用 push before SHA;手工触发先尝试 `origin/master`,若它与 `HEAD` 相同则改用 `HEAD^`,仍无法得到不同提交时失败关闭。
|
||||
|
||||
启用或注册执行 PR job 的 runner 前,Gitea 服务端必须至少升级到 `1.26.4`;不得在 `1.26.2` 上执行不受信任 PR 代码。runner 保留 `ubuntu-latest` 标签作为已有固定 digest Ubuntu 24.04 级环境,同时提供专用 `genarrative-ci` 标签,并将后者映射到已装入 runner 内层 Docker 的完整 Image ID;两者均不得映射到 host 执行器,job 不得获得 Docker socket、业务环境变量、业务密钥或不必要的内网。workflow 不再现场运行 apt、`actions/setup-node` 或 rustup 安装;Node 22、Rust 1.96.0、`rustfmt`、Chrome、`bwrap`、`rg`、`ffmpeg`、`clang/lld` 和 Tauri / 后端系统依赖都由预构建镜像提供。checkout 由镜像内 `genarrative-gitea-checkout` 直接从当前 Gitea 拉取事件 commit,并执行 5 次有界重试;不得恢复为运行时从 GitHub 克隆 action。当前锁命中时,npm 与 Linux 目标 Cargo 下载可完全使用镜像内预热缓存;锁文件新增依赖时才经受控 proxy 补齐。构建 CI 镜像仍需访问固定基础镜像、Ubuntu / Google Chrome 软件源、nodejs.org、npm registry 和 crates.io。本阶段不使用共享 Actions cache,避免不受信任 PR 污染跨 job 可写缓存。当前 Runner 2.0.0 已支持 job 级 `timeout-minutes`,但 runner 全局 `3h` 仍是所有任务的硬上限。
|
||||
|
||||
@@ -270,13 +269,6 @@ workflow 首次成功运行后,在 Gitea `master` 分支保护中把 `Project
|
||||
|
||||
master 日常交付必须禁止直接 push,只允许经 PR 在当前 head 的四个 required context 全绿后合并;本地 `pre-commit` 的 staged ESLint/Prettier 和 master `pre-push` 的 Repository checks parity 只用于提前发现问题,可被 `--no-verify` 绕过,不能充当服务端权威门禁。紧急直推白名单如需保留,应按人员和时限最小化,并要求执行同一 `npm run check:repository-ci <base> <head>` 后回读 push CI。
|
||||
|
||||
视觉小说负向扫描与验收门禁:
|
||||
|
||||
```bash
|
||||
npm run check:visual-novel-vn11
|
||||
npm run check:visual-novel-vn12
|
||||
```
|
||||
|
||||
SpacetimeDB bindings:
|
||||
|
||||
```bash
|
||||
@@ -629,6 +621,8 @@ Nginx 与 Pingora 在维护 marker 存在时对内网来源绕过整站维护闸
|
||||
|
||||
`scripts/jenkins-checkout-source.sh` 是生产 Jenkinsfile 内部二次确认源码的统一入口。构建流水线由 Jenkins `GitSCM checkout` 先用凭据完成浅克隆,再以 `GENARRATIVE_JENKINS_REUSE_EXISTING_CHECKOUT=true` 调用脚本复用当前 checkout;只有显式 `COMMIT_HASH` 不在这次浅克隆里时,脚本才通过传入的 SSH 远端继续 fetch 并逐步加深。构建流水线和服务器初始化流水线传入 `COMMIT_HASH` 时,脚本必须先保持 `depth=1` 浅拉,若上游 commit 已在浅历史内则直接校验并 checkout;只有浅历史无法证明 commit 属于目标分支时,才按 `GENARRATIVE_JENKINS_CHECKOUT_DEEPEN_STEPS`(默认 `50 200 1000 5000`)逐步加深,最后才尝试展开完整历史。`Genarrative-Api-Deploy`、`Genarrative-Web-Deploy` 和 `Genarrative-Stdb-Module-Publish` 仍保留上游构建传入的 `COMMIT_HASH` 作为通知和追溯字段,但不再用它在目标机器重新 checkout 部署脚本。
|
||||
|
||||
`Genarrative-Api-Build` 与 `Genarrative-Stdb-Module-Build` 在浅克隆复用后必须取得待构建提交的第一父提交:本地对象缺失时只额外执行一次凭据保护的 `git fetch --depth=2 <source_commit>`,并把父提交 SHA 写入 `SPACETIME_SCHEMA_BASE_REF` 后再运行 `check:server-rs-ddd`。父提交不可取得、不可解析或与 `HEAD` 相同时必须失败关闭,禁止让 SpacetimeDB schema 门禁回退成 `HEAD` 自比。
|
||||
|
||||
`Genarrative-Stdb-Module-Publish` 在 `Pipeline script from SCM` 阶段如果一开始就报 `No such DSL method 'pipeline'`,优先检查 `jenkins/Jenkinsfile.production-stdb-module-publish` 是否带 UTF-8 BOM。Jenkins Declarative Pipeline 的首个 token 必须是纯 `pipeline`;仓库中的 Jenkinsfile 应保存为 UTF-8 without BOM,只有临时写给 Windows PowerShell 5.1 `-File` 执行的 `.ps1` 才需要按对应 helper 转成带 BOM。验证时可检查文件前三字节不再是 `EF BB BF`,并运行 `validateDeclarativePipeline` 或重放该流水线。
|
||||
|
||||
`Genarrative-Stdb-Module-Build` 或 SpacetimeDB module 构建失败若出现 Rust `E0425 cannot find function migrate_*`,优先排查 `server-rs/crates/spacetime-module/src/runtime/creation_entry_config.rs` 等同文件内默认种子迁移 helper 是否在分支合并时只保留了调用、漏掉了函数定义。`Genarrative-Stdb-Module-Build` 现在运行在 `linux && genarrative-build` 节点上,Checkout 与 Build 都走 bash + cargo + sccache,不再依赖 Windows PowerShell 或 Git Bash;Stdb module 的 `CARGO_HOME`、`CARGO_TARGET_DIR` 和 `SCCACHE_DIR` 默认落在稳定缓存根 `~/caches/genarrative-jenkins/stdb-module` 下,可用 `GENARRATIVE_STDB_CACHE_ROOT` 覆盖,避免 `WORKSPACE@tmp` 被清理后无改动也触发近似冷构建。修复时不要直接删除迁移调用;应恢复只纠偏历史默认种子且不覆盖后台手动配置的 helper,并用 `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml` 复现 Jenkins module 编译路径。
|
||||
|
||||
@@ -353,7 +353,7 @@ RPG / 拼图等运行态存档仍以 `/api/profile/save-archives` 的后端列
|
||||
- 封面、场景、角色立绘和音乐写平台 asset id 或 generated 引用。
|
||||
- 运行时图片渲染使用 `ResolvedAssetImage` 换签。
|
||||
|
||||
视觉小说禁止新增回放 / 录制 / 复盘类功能。`npm run check:visual-novel-vn11` 继续作为负向扫描门禁。
|
||||
视觉小说退役前的设计禁止新增回放 / 录制 / 复盘类功能;该约束不再作为当前工程门禁。
|
||||
|
||||
## 汪汪声浪 Bark Battle
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ worker 完成生成任务时,`api-server` 先把 Provider / OSS 结果准备
|
||||
|
||||
`POST /api/editor/images/pixel-art-snaps` 的完美像素化不是 external job completion:它免费、在当前 HTTP 请求内 inline 执行,不创建任务行,也没有 `job_id / worker_id / lease_token`。前端仍须先创建关闭 composer 的右侧 generation dialog,再解析或上传源图以取得稳定引用,随后 flush 包含该占位的当前布局,最后把稳定源媒体引用和带非空 `dialogId` 的 `canvasCompletion` 一次提交;结构化 / legacy canvas 的完成分流继续由后端决定,前端不能直接写表或本地补造正式 layer。
|
||||
|
||||
端点级并发排队、像素读取、静态 PNG / JPEG / WebP 编码门禁、解码、输入限制、legacy 网格步长估算、CPU 并发排队、规整和 PNG 编码全部发生在持久化前。两层排队的位置不同:端点级闸在首次 IO 之前,因此队列满的 `503` 早于任何 SpacetimeDB 读取和 OSS 下载返回;CPU 排队仍在下载之后、规整之前,等待超预算返回 `504`。两者都在持久化前失败,零写入结论不变。strict 与生成风格使用同一 profile、峰值估算、单轴步长补全、walker、采样和编码;仅在横纵两轴都未检测到步长、legacy 即将进入统一网格兜底时拒绝,任一轴已检测到步长时行为和输出完全一致。任一步失败、超时或不适用时不执行最终 OSS PUT,不创建 asset object、`editor_project_resource`、`editor_asset` 或结果 layer;不得保存原图副本、诊断图或前后对比图冒充结果。处理成功时,snapper 直接编码并 PUT 唯一一张 `(columns.len() - 1) × (rows.len() - 1)` 逻辑分辨率 PNG,不再 nearest 恢复到源图或交付尺寸,并至多各创建一个 project resource 和一个账号素材;源图已有正式 project resource 时,结果资源的 `source_resource_id` 指向该资源。结果 resource、asset、响应与 layer 使用最终 PNG 的实际宽高,不要求与源图或 generation dialog 占位尺寸相等,也不得另存输入尺寸恢复版。
|
||||
端点级并发排队、像素读取、静态 PNG / JPEG / WebP 编码门禁、解码、输入限制、legacy 网格步长估算、CPU 并发排队、规整和 PNG 编码全部发生在持久化前。两层排队的位置不同:端点级闸在首次 IO 之前,因此队列满的 `503` 早于任何 SpacetimeDB 读取和 OSS 下载返回;CPU 排队仍在下载之后、规整之前,等待超预算返回 `504`。两者都在持久化前失败,零写入结论不变。strict 与生成风格使用同一 profile、峰值估算、单轴步长补全、walker、采样和编码;仅在横纵两轴都未检测到步长、legacy 即将进入统一网格兜底时拒绝,任一轴已检测到步长时行为和输出完全一致。任一步失败、超时或不适用时不执行最终 OSS PUT,不创建 asset object、`editor_project_resource`、`editor_asset` 或结果 layer;不得保存原图副本、诊断图或前后对比图冒充结果。处理成功时,snapper 将逻辑网格按单一整数倍 nearest 放大到最接近规整输入的尺寸后编码并 PUT 唯一一张最终 PNG,禁止非整数拉回源图或交付尺寸,并至多各创建一个 project resource 和一个账号素材;源图已有正式 project resource 时,结果资源的 `source_resource_id` 指向该资源。结果 resource、asset、响应与 layer 使用最终 PNG 的实际宽高,宽高比等于逻辑图,尺寸接近但不保证等于源图或 generation dialog 占位,也不得另存未放大逻辑图或输入尺寸恢复版。
|
||||
|
||||
该零写入保证只覆盖首个最终 PNG PUT 前的可预判与处理阶段。进入持久化后,PNG / asset object、project resource、账号素材与 canvas completion 仍跨 OSS 和多个 SpacetimeDB procedure,沿用既有非事务顺序;后段失败可以保留此前已经确认的对象或记录,不做自动删除补偿,也不由客户端重放请求。调用方应按 `task_id / object_key / resource_id` 重新读取权威项目和素材快照后显式收口。
|
||||
|
||||
@@ -89,7 +89,7 @@ worker 完成生成任务时,`api-server` 先把 Provider / OSS 结果准备
|
||||
3. CAS 冲突时不得拿新 revision 原样重放旧整包;按当前项目保存冲突规则重新读取权威快照并显式收口;
|
||||
4. 客户端回包时若本地 dialog 已删除,不应用完成快照或写历史;现有布局 CAS 没有 deletion tombstone,completion 先提交、删除保存后冲突的极端竞态仍按权威快照收口。客户端不得为该 unsafe POST 配置 `EDITOR_REQUEST_RETRY_OPTIONS`。请求字节可能已发出后的 transport 异常或 `408 / 425 / 429 / 502 / 503 / 504` 不自动重放,先通过 GET 核对项目 / 素材快照,再由用户显式决定是否再次执行;Bearer 中间件在 handler 前拒绝请求后的既有认证恢复继续保留。
|
||||
|
||||
generation dialog 的 placeholder 宽高只参与占位与完成落点,不是结果媒体尺寸约束;completion 必须使用最终 PNG 资源的实际宽高构造结果 layer,不能为了匹配 placeholder 再缩放或拒绝逻辑分辨率结果。
|
||||
generation dialog 的 placeholder 宽高只参与占位与完成落点,不是结果媒体尺寸约束;completion 必须使用最终 PNG 资源的实际宽高构造结果 layer,不能为了匹配 placeholder 再缩放或拒绝整数倍放大结果。
|
||||
|
||||
## 4. 存量迁移
|
||||
|
||||
@@ -132,6 +132,6 @@ SpacetimeDB 必须先于依赖新 procedure / bindings 的 API 发布;前端
|
||||
- structured 模式下 typed 列而非扩展 JSON 决定几何、层级、分组、显示 / 锁定、资源引用、`asset_kind_override` 和 dialog 状态;标签展示和类型能力判断统一按 `override ?? resource default`。修改当前图层标签与清除覆盖都保持 `resource_id` 和资源行数量不变;复制共享同一资源并复制 override,随后各副本可独立修改 override。两个客户端基于同一 revision 写入时只允许一个成功,冲突方重载后端最新快照,不换上新 revision 原样重放旧整包。细粒度 batch mutation 是取消 2 MiB 兼容入口的后续项,不冒充为本次已完成。
|
||||
- worker completion 已使用 durable receipt 与统一原子提交;V2 布局 CAS、object/resource/asset/binding、job 终态和 receipt 在同一 procedure 结果内返回。故障注入必须证明资产校验失败与 canvas revision 冲突均为零部分写入,成功后重放不新增记录、事件或 revision。
|
||||
- structured 快照刷新后,上传参考图、生成结果、占位与 dialog 状态均可恢复;资源存在但布局写入失败时不会伪装为保存成功。
|
||||
- 完美像素处理失败 / 超时时 OSS、resource、asset 和 layer 均无新增;成功时只有一个逻辑分辨率最终 PNG、至多一个 project resource 和一个账号素材,所有宽高均取该 PNG 实际值且允许与源图 / 占位不同。处理中占位删除已先持久化时,完成请求不复活 dialog 或结果 layer;回包时本地占位已删除则不应用完成快照,已成功创建的资源 / 素材仍可读取;传输结果未知时客户端不自动重放 unsafe POST。
|
||||
- 完美像素处理失败 / 超时时 OSS、resource、asset 和 layer 均无新增;成功时只有一个整数倍放大后的最终 PNG、至多一个 project resource 和一个账号素材,所有宽高均取该 PNG 实际值且允许与源图 / 占位不同。处理中占位删除已先持久化时,完成请求不复活 dialog 或结果 layer;回包时本地占位已删除则不应用完成快照,已成功创建的资源 / 素材仍可读取;传输结果未知时客户端不自动重放 unsafe POST。
|
||||
- 回滚重组结果经 schema 校验、canonical hash / 资源引用核对且不超过 2 MiB;超限或不一致时明确拒绝且 structured 快照仍可读取。
|
||||
- 完成 `npm run spacetime:generate`,确认 Rust 表字段、migration、生成 bindings、HTTP DTO 与前端 `assetKindOverride` 形状一致;再运行 `npm run check:spacetime-runtime-access`、`npm run check:spacetime-schema`、相关 Rust / API / 前端定向测试、`npm run check:encoding` 和 `git diff --check`。
|
||||
|
||||
@@ -75,11 +75,11 @@
|
||||
- 图标素材面板增加紧凑的 `像素艺术` 勾选项。选择保存于现有生成器快照,并可随现有请求和队列 payload 传递;不写入用户可见 `generationInputs`、素材元数据或新建的持久化记录。
|
||||
- `style` 省略、为 `null`、空字符串或 `"none"` 时按内部 `None` 处理且不告警;`"pixelArt"` 启用像素规整。未知字符串按 `None` 继续生成,并通过既有通用 `warning` 返回 `unsupported-image-style`;非字符串 JSON 仍返回 `400`。
|
||||
- 2026-08-01 修订:`"pixelArt"` 不再只是后处理,同时向提交给 provider 的提示词末尾追加独立一行约束。图标链路使用「每个图标素材均为像素风格」,**不得**使用「画面为像素风格」——图集生成后要按纯色抠像,绿幕底必须保持平整,画面级像素化要求会与同一段提示词里的「纯色背景必须平整无纹理、无渐变」互相拆台;一张图内是多个彼此分离的素材,需要逐个点名,避免模型只把其中一部分做成像素块。注入发生在 `build_editor_icon_spritesheet_prompt` 返回之后,该函数签名和输出契约不变。约束句只随工程化提示词写入**原图 spritesheet** 的 `editor_project_resource` prompt 列;透明结果的 prompt 列是 `"去除纯色背景"`,自动拆分的切片是 `"自动拆分图集"`,两者都不含约束句。与普通图片和角色形象不同,本链路**响应体**的 `prompt` 字段返回的也是含约束句的工程化提示词,而不是用户输入——图标请求本身没有 `prompt` 字段(收的是 `iconDescriptions`),因此调用方(含外部 API v1)能直接看到绿幕子句、间距要求和本次新增的像素约束。以上 prompt 列写入与响应字段规则都是既有行为,与 `web/master` 一致,本次只是让被回传的模板多了一行。不新增 OSS PUT、项目资源、图集画布项或切片画布项。尚未约束各素材共用同一像素块大小(`estimate_step_size` 取全图相邻峰间距的第 30 百分位,块大小不一时步长估计会偏),等实测。
|
||||
- 图标链路以已持久化的带纯色背景 provider 原图实际尺寸为基准;BgFilter 正常成功后,把 Alpha 蒙版回贴到该同尺寸平底原图,再执行像素规整。网格分析源使用平底 provider 原图,RGBA 采样源使用 Alpha 已回贴的透明图;这两份内部输入仍必须同尺寸。规整结果按一格一输出像素直接编码为逻辑分辨率透明 spritesheet,不再经过独立的最终尺寸处理,成功后才进入原有连通域自动拆分。
|
||||
- 图标链路以已持久化的带纯色背景 provider 原图实际尺寸为基准;BgFilter 正常成功后,把 Alpha 蒙版回贴到该同尺寸平底原图,再执行像素规整。网格分析源使用平底 provider 原图,RGBA 采样源使用 Alpha 已回贴的透明图;这两份内部输入仍必须同尺寸。规整结果按一格一输出像素采样后,再按单一整数倍 nearest 放大到最接近规整输入的尺寸,编码为透明 spritesheet,成功后才进入原有连通域自动拆分。
|
||||
- 首版固定参数为分析色数 `16`、Alpha 覆盖阈值 `0.375`、像素格尺寸自动检测、固定色板关闭、K-means 最大采样 `262144`。单格颜色按 `Σ(A × RGB) / ΣA` 进行 Alpha 加权;覆盖率 `Σ(A / 255) / N >= 0.375` 且 `ΣA > 0` 时输出硬 Alpha `255`,否则输出严格 `[0,0,0,0]`。分析色数不限制最终输出色数。
|
||||
- 像素规整 CPU 工作使用进程级最大并发 `2`;取得并发许可的排队时间与实际处理时间共享最多 `30` 秒预算,同时不得晚于当前请求 deadline,最终以两者中更早者为准。输入图片任一边不得超过 `10000` 像素,总像素不得超过 `8294400`;超限、排队超时或处理超时均保留 Alpha 已回贴的透明图并走非致命降级,随后仍可进入原有自动拆分。
|
||||
- snapper 直接把逻辑分辨率图编码为最终透明 spritesheet;不得再用 nearest 或其它插值恢复到前述平底 provider 原图尺寸。图标链路继续不执行角色链路的前置 Lanczos 交付尺寸归一,但最终透明图集宽高仍可以与规整输入不同。实现应复用 Alpha 回贴阶段读取的平底 provider 原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图、透明图集和实际成功切片的持久化与画布数量不变。开启时透明图集本身就是唯一的逻辑分辨率 PNG;禁止另存输入尺寸恢复版、像素化前后双份图集、预览或诊断图,也不新增 asset kind、项目资源、画布 item、任务类型或数据库字段。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与 provider 原图或生成占位尺寸相等。
|
||||
- snapper 把整数倍放大后的图编码为最终透明 spritesheet;禁止非整数拉回平底 provider 原图尺寸。图标链路继续不执行角色链路的前置 Lanczos 交付尺寸归一,最终透明图集宽高比等于逻辑图,尺寸接近但不保证等于规整输入。实现应复用 Alpha 回贴阶段读取的平底 provider 原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图、透明图集和实际成功切片的持久化与画布数量不变。开启时透明图集本身就是唯一的整数倍放大 PNG;禁止另存未放大逻辑图、输入尺寸恢复版、像素化前后双份图集、预览或诊断图,也不新增 asset kind、项目资源、画布 item、任务类型或数据库字段。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与 provider 原图或生成占位尺寸相等。
|
||||
- 图标图集的 BgFilter `flat` 调用固定使用 `cross_check=on`。BgFilter 最终失败、Alpha 比例漂移超过 `5%`、provider 原图修复性回读失败、Alpha 回贴失败或透明图完整解码失败时,都统一只保留 provider 原图且不拆分,像素规整不运行;像素规整自身失败但透明图仍通过完整解码和尺寸守卫时,才保留该透明图并继续上传和拆分,通过通用 `warning` 非致命提示,不退款。`sliceWarning` 继续只表达可信透明图成功后的自动拆分失败。
|
||||
|
||||
## 去背与保存
|
||||
@@ -103,7 +103,7 @@
|
||||
- 默认提示文本会完整进入 prompt;用户输入不再被解析为素材数量。例如“各种敌人头像:骷髅 哥布林 强盗 龙 蝙蝠等”只是一段完整需求,不代表必须生成或拆出 `6` 个素材。
|
||||
- 默认打开图标素材面板时选中 `nanobanana2 / 1:1 / 1K`;模型切换后,角色和图标素材面板之间沿用上次选择的模型。
|
||||
- 图标素材生成请求必须带 `model`、`aspectRatio` 和 `imageSize`;`nanobanana2` 请求体必须包含 `generationConfig.imageConfig.aspectRatio/imageSize`,`gpt-image-2` 请求必须包含文档映射后的 `size`。
|
||||
- 图标素材面板可选择 `style: "none" | "pixelArt"`;`none` 完整保持原处理路径,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「每个图标素材均为像素风格」并在 Alpha 回贴后、自动拆分前执行内存像素规整,直接持久化逻辑分辨率透明图集;该图集可以与规整输入尺寸不同,最终 OSS PUT、项目资源、图集画布项和切片画布项数量不得因此增加。
|
||||
- 图标素材面板可选择 `style: "none" | "pixelArt"`;`none` 完整保持原处理路径,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「每个图标素材均为像素风格」并在 Alpha 回贴后、自动拆分前执行内存像素规整,直接持久化整数倍放大后的透明图集;该图集宽高比等于逻辑图、尺寸接近规整输入,最终 OSS PUT、项目资源、图集画布项和切片画布项数量不得因此增加。
|
||||
- 图标素材生成可以上传普通附加参考图;提交时图标主规范图走 `referenceId`,且只提交当前 owner 的项目资源 ID 或素材 ID。普通附加参考图单独走 `referenceImageSrcs`,继续允许稳定 `objectKey` / 项目资源 ID / 素材 ID,但禁止 Data URL / Blob URL。两类引用都写入 `generationInputs.references`,不得用普通附加参考图协议放宽主规范边界。
|
||||
- 透明背景处理和自动拆分都成功后,画布同时出现透明 spritesheet 主图、其右侧的 provider 原图,以及从原图右侧铺开的全部有效连通域图标图层,图标依次命名为 `素材 N`;透明图集成功但拆分失败时仍出现透明主图与右侧原图,透明背景处理最终失败时只出现 provider 原图。
|
||||
- 选中透明图集图层时显示 `拆分图集`;点击后源图集显示扫描蒙层与 `拆图中` 状态,工具栏按钮同步切换为旋转图标和 `拆图中` 并禁用重复提交。完成后恢复工具栏,不新增第二张图集,只在 provider 原图右侧追加自动识别的独立素材,并同步写入素材库。
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
- 角色 provider 回图先按统一业务像素矩阵执行交付尺寸归一:允许无放大恢复时使用 Lanczos 重采样并居中裁切,无法安全恢复时保留 provider 实际尺寸并返回非阻断告警。归一后的带纯色背景图先持久化并作为 BgFilter 输入;BgFilter 正常成功后,把 Alpha 蒙版回贴到这张同尺寸平底原图,再执行像素规整并上传透明主图。网格分析源使用已收口到实际交付尺寸的平底原图,RGBA 采样源使用 Alpha 已回贴的透明图;软 Alpha 只参与单格覆盖率和 Alpha 加权 RGB 计算,输出 Alpha 硬化为 `0 / 255`。
|
||||
- 首版参数固定为分析色数 `16`、Alpha 覆盖阈值 `0.375`、像素格尺寸自动检测、固定色板关闭、K-means 最大采样 `262144`。单格覆盖率 `Σ(A / 255) / N >= 0.375` 且 `ΣA > 0` 时输出 `A=255`,颜色按 `Σ(A × RGB) / ΣA` 计算;否则输出 `[0,0,0,0]`。分析色数不限制最终输出色数。
|
||||
- 像素规整 CPU 工作使用进程级最大并发 `2`;取得并发许可的排队时间与实际处理时间共享最多 `30` 秒预算,同时不得晚于当前请求 deadline,最终以两者中更早者为准。输入图片任一边不得超过 `10000` 像素,总像素不得超过 `8294400`;超限、排队超时或处理超时均保留 Alpha 已回贴的透明图并走非致命降级。
|
||||
- snapper 把每对相邻横纵切线围成的采样单元各压成一个输出像素,并把这张逻辑分辨率图直接编码为最终透明 PNG;不得再用 nearest 或其它插值恢复到当前 RGBA 输入尺寸。前述 Lanczos 交付尺寸归一继续保留,它只定义网格分析源与 RGBA 采样源的共同坐标系;两份内部输入仍必须同尺寸,但最终 PNG 宽高可以与该输入不同。实现应复用 Alpha 回贴阶段读取的已持久化平底原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图与透明主图两份产物、项目资源和画布图层数量不变。开启时透明主图本身就是唯一的逻辑分辨率 PNG;禁止另存输入尺寸恢复版、像素化前后双份主图、预览或诊断图,也不新增 asset kind、画布 item 或任务类型。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与生成交付尺寸或占位尺寸相等。
|
||||
- snapper 把每对相邻横纵切线围成的采样单元各压成一个输出像素,再按单一整数倍 nearest 放大到最接近规整输入的尺寸后编码为最终透明 PNG;禁止非整数拉回精确输入尺寸。前述 Lanczos 交付尺寸归一继续保留,它只定义网格分析源与 RGBA 采样源的共同坐标系;两份内部输入仍必须同尺寸,最终 PNG 宽高比等于逻辑图,尺寸接近但不保证等于该输入。实现应复用 Alpha 回贴阶段读取的已持久化平底原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图与透明主图两份产物、项目资源和画布图层数量不变。开启时透明主图本身就是唯一的整数倍放大 PNG;禁止另存未放大逻辑图、输入尺寸恢复版、像素化前后双份主图、预览或诊断图,也不新增 asset kind、画布 item 或任务类型。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与生成交付尺寸或占位尺寸相等。
|
||||
- 本功能不修改 BgFilter `flat` 调用、`cross_check=on`、fallback、Alpha 回贴或默认关闭 despill 的现状。BgFilter 最终失败时沿用只保留 provider 原图的既有收口且不运行像素规整;像素规整自身失败时保留已成功的透明图并继续原有持久化,通过通用 `warning` 非致命提示,不退款。
|
||||
|
||||
- `kind = "character"` 时,后端不直接把前端文本当完整生图提示词,而是把文本作为 `角色设定` 填入固定提示词骨架:
|
||||
@@ -85,10 +85,10 @@
|
||||
|
||||
## 生成规范参考图
|
||||
|
||||
- `生成规范 -> 角色规范`、`图标规范`、`图标规范`、`自定义规范` 的设定面板都支持上传 1 张参考图,并统一放在面板首行参考图区域。
|
||||
- `生成规范 -> 角色规范`、`自定义规范` 的设定面板支持上传多张参考图,最多 5 张;`图标规范` 保持单张规范参考图。所有参考图统一放在面板首行参考图区域,并可逐张删除。
|
||||
- 参考图入口只展示字段标题、缩略图或上传图标、文件名,不把参考规则说明铺在 UI 上。
|
||||
- 提交生成规范时,若存在参考图,前端必须把参考图作为 `referenceImageSrcs[0]` 提交到 `/api/editor/images/generations`,并在生图提示词开头自动追加“参考图生成规范”语义:要求模型参考图 1 的构图、风格、材质、色彩、形状语言和视觉层级生成规范图,但不要复制参考图中的文字、水印或无关背景。
|
||||
- 生成结果的信息快照必须记录该参考图,标题为 `参考图`,便于后续在图片信息面板回看生成输入。
|
||||
- 提交生成规范时,若存在参考图,前端必须按用户当前顺序把全部参考图提交到 `/api/editor/images/generations` 的 `referenceImageSrcs`,并在生图提示词开头自动追加“参考图生成规范”语义:要求模型参考图的构图、风格、材质、色彩、形状语言和视觉层级生成规范图,但不要复制参考图中的文字、水印或无关背景。
|
||||
- 生成结果的信息快照必须按当前顺序记录全部参考图,首张标题为 `参考图`,后续依次为 `参考图2`、`参考图3` 等,便于在图片信息面板回看生成输入。
|
||||
|
||||
## 新建生成图落点避让
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
- `从画布中选择` 后点击已有画布图片可绑定为角色规范,`Esc` 可退出点选状态。
|
||||
- 上传常规参考图后缩略图右下角显示序号。
|
||||
- 输入角色设定并生成时,请求包含 `kind: "character"`、角色设定 prompt、参考图数组、`model`、`screenColor`、`aspectRatio` 和 `imageSize`。
|
||||
- 角色面板可选择 `style: "none" | "pixelArt"`;`none` 的处理路径和产物保持不变,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「角色主体为像素风格」并在 Alpha 回贴后执行内存像素规整,直接持久化逻辑分辨率透明 PNG;该 PNG 可以与规整输入尺寸不同,最终 OSS PUT、项目资源和画布图层数量不得增加。
|
||||
- 角色面板可选择 `style: "none" | "pixelArt"`;`none` 的处理路径和产物保持不变,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「角色主体为像素风格」并在 Alpha 回贴后执行内存像素规整,直接持久化整数倍放大后的透明 PNG;该 PNG 宽高比等于逻辑图、尺寸接近规整输入,最终 OSS PUT、项目资源和画布图层数量不得增加。
|
||||
- 默认打开角色生成面板时选中 `nanobanana2 / 1:1 / 1K`;切换到 `gpt-image-2` 后再次打开角色或图标素材面板应沿用该模型。
|
||||
- 生成成功后在占位图位置创建 `assetKind: "character"` 图层,右上角显示 `角色` 标签,布局保存包含该字段。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user