Commit Graph

5378 Commits

Author SHA1 Message Date
k88936 1f5329b90c Merge remote-tracking branch 'origin/master' into feat/tribo3d-integeration
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m24s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m59s
Project CI / Backend tests (pull_request) Successful in 5m28s
Project CI / Native shell tests (pull_request) Successful in 6m39s
Project CI / Frontend tests (pull_request) Successful in 2m21s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 9m44s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 9m57s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m59s
Project CI / Repository checks (pull_request) Failing after 2m32s
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
#	docs/project-memory/shared-memory/pitfalls.md
2026-09-24 21:18:31 +08:00
k88936 0c5aeb5271 导出压缩包里的目录改成第一次写文件时才建,不再留空目录
- `useImageCanvasAssetExportWorkflow`:三个导出目录(images / media / 3d_models)从「开包就全建好」改成 `createExportFolderResolver` 按需创建,同一轮导出每个目录只建一次;没有对应内容的压缩包里不再出现空的 `media/`、`3d_models/`
- 用例:只导出图片时压缩包里不存在 media / 3d_models 的任何条目
- docs/adr 0003:后果里补上「目录按需创建、空目录不进包」
2026-09-24 21:14:19 +08:00
k88936 2204df139c 3D 开关互斥:打开分件就关掉四边面 / 智能减面,反之亦然
- `applyModel3dSwitchChange` 不再原样套用改动:收到「生成部件 = 开」时清掉四边面与智能减面,收到任一几何模式打开时清掉生成部件;让刚刚打开的那个赢,面板上不留提交前校验必然拒绝的组合
- 只关掉某个开关时不动其它开关(关分件不该顺带清空几何模式)
- 用例:两个方向的互斥各一例 + 只关一个开关不动其它
2026-09-24 21:12:43 +08:00
k88936 8e169e17b8 换模型时不再拿上一个模型的地址渲染 3D 查看器
- useResolvedAssetReadUrl:地址与「它是为哪个 objectKey 换回来的」一起返回(`resolvedObjectKey`),换签期间归属清空——只按地址字符串判断的话,调用方分不出「新资源 + 旧地址」这一帧
- Model3dViewerModal:只有确认地址属于当前模型才交给查看器;该帧按「正在准备模型地址」提示,不闪「地址不可用」
- 用例:换模型那一帧不渲染查看器;换 objectKey 时旧地址的归属先清空
2026-09-24 21:11:56 +08:00
k88936 dfbde6fbc1 3D 生成面板补 TODO:弹出式对话框的标记与焦点管理要一起做
- 面板容器只标了 role="dialog"、没标 aria-modal,也没有焦点约束与焦点归还(评审 #74)
- 加上 TODO(a11y-modal) 说明为什么单独补标记反而会误导,以及「与焦点管理一起做 / 一次性推广到所有同类面板」两条路,本轮不改行为
2026-09-24 21:07:09 +08:00
k88936 d4416e8b88 把「已提交但没写下记录」的崩溃窗口写进文档
- docs/technical Tripo 集成方案:at-most-once submit 段新增「崩溃窗口(已知并接受,消不掉)」一条——submit 受理与 checkpoint 落库之间崩溃时库里没有任何记录,该窗口加判断消不掉;固定 max_attempts = 1 保证不会二次 submit / 二次计费,代价是这笔生成按失败退款、provider task id 也没留下
- docs/后端数据契约:provider checkpoint 那条把「重新 claim 一定能读到」的保证收窄为「checkpoint 已写下之后」,并指向集成方案的这一段
2026-09-24 21:06:59 +08:00
k88936 8fa2bfc3ed 多视图视图地址的注释改成 TODO:接线时必须补地址校验,并删掉引错的 ADR 依据
- platform-tripo:`view_value` 的说明不再引用 ADR 0001(那份 ADR 里没有这条约定),改成 `TODO(multiview-url-validation)`,写明当前只有冒烟示例与接口测试能构造 `Url` 形态、api-server 没有现役入口,以及真正接线时必须在构造侧补协议 / 账号密码 / 内网主机校验
- 同时点明 image-to-model 的 `PublicUrl` 是同一处待办
2026-09-24 21:06:28 +08:00
k88936 e20ff2e89e provider 报 unknown 任务状态时改为可重试,不再直接判死
- platform-tripo:`TaskStatus::Unknown` 不再归一成 `OutputSchema` 终态失败,改成新的 `TripoError::TaskStatusUnknown`,并把它的可重试性判为真(SDK 自己也没把 unknown 算进终态)
- platform-tripo:补用例——provider 回 `"status":"unknown"` 时必须返回可重试的 `TaskStatusUnknown`,不能当成正常快照
- api-server:错误映射补 `TaskStatusUnknown` 分支(502 + 固定文案,轮询侧早已按可重试继续查到截止时间)
- api-server worker:状态查询遇到可重试错误时补一条 warn 日志,便于区分「一直是 unknown」和「一次网络抖动」
- docs:Provider 集成方案写明 unknown 按可重试处理及其理由
2026-09-24 21:06:04 +08:00
k88936 2aa59328de 3D 产物登记失败时删掉已经传上去的对象
- storage:新增 `discard_model3d_artifact`,按对象键删除刚写入的产物;OSS 未配置或删除失败都只记警告并带上对象键,方便人工清理
- worker:预览图上传失败时删掉已传的模型对象;登记失败时把模型与预览图两个对象都删掉;`persist_result` 改成接收引用,好让调用方在失败后还能按对象键清理
- docs/technical:写明「上传成功但后续失败就删掉对象,不接受失败就烂在 bucket 里」
2026-09-24 20:46:42 +08:00
k88936 8af02daeea 3D 产物上传带上退避重试,一次瞬时网络失败不再废掉整笔生成
- platform-oss:新增按前缀拼对象键的 `put_object_with_transient_retry`,与内部对象 PUT 共用同一套「可判定才重试」规则与退避(传输 / 超时 / 408 / 429 / 5xx 才重试,确定性 4xx 直接失败),body 只准备一次、每次 attempt 复用引用计数字节;重试次数或退避配置不足时按配置错误失败关闭
- api-server storage:3D 产物的模型 / 预览图 PUT 改用该入口,最多 3 次尝试、退避 250 / 500 ms(与角色动画同一口径);模型上限 512 MiB 但实际产物远小,重试成本可控
- 新增用例:重试次数为 0 与退避不足都失败关闭;对一定解析不出的域名会真的按退避重试多次
- docs/technical:写明产物 PUT 的重试口径与「每个网络动作都要能重试」的理由
2026-09-24 20:43:39 +08:00
k88936 75f757f807 图生 3D 在真正提交前再确认一次剩余预算
- worker:`submit_and_checkpoint` 接收 provider 截止时间,图生 3D 在下载源图、上传给 provider 之后、真正 submit 之前再调一次 `ensure_submit_budget`
- 原因写进注释:解析源图这两步都可能耗时到把预算用光,而 submit 不可撤销且计费,宁可本次尝试判失败,也不要提交上去立刻被截止时间判失败、白花一次外部调用
- `ensure_submit_budget` 的说明补上两处调用点
2026-09-24 20:40:14 +08:00
k88936 4ca1329d24 任务状态查询本身带上退避重试,瞬时故障不再作废一次计费任务
- platform-tripo:`get_task` 内部按 `TripoSettings::retries` 对瞬时故障(连接抖动 / 超时、408、429、5xx)退避重试,确定性失败(任务 id 非法、响应结构不符、404)立即返回;重试字段与退避函数改名,不再只服务产物下载
- api-server worker:查询在重试后仍是瞬时故障时继续按轮询间隔查到预算用尽,只有确定性失败才立刻收口
- 新增用例:一次 500 后成功(重试生效)、404 只打一次请求(不重试),并给测试客户端加了可指定 base_url 的构造
- docs/technical:写明查询带退避重试与「确定性失败立即返回」的边界
2026-09-24 20:39:12 +08:00
k88936 a08e3bf262 产物地址只允许公网主机,回环与内网段一律拒收
- platform-tripo:`TripoUrl::parse` 在协议与 userinfo 检查之后,再加一道主机检查——回环、内网、链路本地、组播与保留段(含云元数据 169.254.169.254)全部拒收;`localhost` 及其子域同样拒收;IPv4-mapped 的 IPv6 地址按内嵌的 IPv4 判定,`::ffff:127.0.0.1` 绕不过去
- 保留段按 IANA 特殊用途表逐段列出(0/8、100.64/10、192.0.0/24、198.18/15、240/4),因为 `Ipv4Addr::is_reserved` 与 `is_global` 在当前工具链上仍是 nightly
- 新增用例覆盖 17 个拒收地址与 5 个放行地址;产物下载用例本来就跑在 127.0.0.1 的本地 mock 上,改用 `parse_unchecked_for_test` 构造
- docs/technical:写明这条主机规则与「域名解析结果在这一层看不见」的已知限制
2026-09-24 20:36:57 +08:00
k88936 a6409d79dc 3D 定价不再在加载时检查加总溢出
- pricing:加载校验删掉「两段加价项相加 + 全表最高底价」的溢出检查与对应的 overflow_error 助手,只保留每段键齐全与合法性的校验
- 理由写进注释:真实查价只用一个端点的底价与它自己的加价项,价格都是手填的小数字,撞不到 u32 上限;按两段相加去挡反而会拒掉能正常计费的配置
- 计费点的 checked_add 保留为唯一一道溢出闸,溢出即失败退款(PriceOverflow 的说明同步改掉「配置阶段已挡过一次」的说法)
2026-09-24 20:34:57 +08:00
k88936 93ef6cebf3 图生 3D 的引用预检改为按归类信号收敛,不再拿状态码猜
- api-server:`resolve_editor_reference_record_by_id_for_owner` 拆出 `..._classified` 版本,失败带「引用不可用 / 其它」归类;原函数保持逐字段一致的对外行为(其它调用方不受影响)
- api-server tripo3d/image_source.rs:注入的解析闭包改为返回归类后的失败,只对 `Unavailable` 收敛成「图片输入必须是当前账号已登记的画布资源或素材」,400 / 404 里的 runtime 与通用过程错误原样上报;模块注释同步
- 用例:`image_source_resolution_only_collapses_unavailable_references` 改成「Unavailable 收敛、400/404/403/409/5xx 一律保留原错」
- docs/project-memory:pitfalls 新增「4xx 不等于用户输入错」一条,记下这条口径与新增模块文案时要同步的清单
2026-09-24 19:55:21 +08:00
k88936 d04f74bd34 Tripo 启动检查连解析后的字段一起校验,不再只看环境变量原文
- api-server tripo3d/provider.rs:`validate_tripo_startup_config` 在原有 env 校验之后,追加对 `AppConfig` 字段值的校验(零超时、重试越界),与请求期 `tripo_settings` 读的是同一对字段
- 用例:新增 `startup_rejects_invalid_parsed_fields_from_any_construction_path`,覆盖「直接构造的配置带着非法值也不能通过启动检查」
2026-09-24 19:54:08 +08:00
k88936 6e081676f0 provider 的 4 字头不再一律按「你的参数不对」回客户端
- api-server tripo3d/errors.rs:401/403 按上游凭据或权限不可用(502,`tripo-api-unauthorized`)、404 按上游找不到(502,`tripo-api-not-found`)、409 按上游冲突(409,`tripo-api-conflict`)、其余 4 字头按上游拒绝(502,`tripo-api-refused`);只有 400 / 422 继续回 400 `tripo-api-rejected`
- 文件头部说明补上这条分档口径
- 用例:`provider_client_side_4xx_stays_bad_request` 覆盖 400 / 422;新增 `provider_non_parameter_4xx_is_not_reported_as_bad_request` 覆盖 401/403/404/409/402 的状态码、reason 与「不回传上游原文」
2026-09-24 19:53:52 +08:00
k88936 14e72379fc 落点预检改为按归类信号收敛,服务端没配好不再被说成「落点选错了」
- api-server:新增定点查询失败归类 `EditorPointLookupKind` / `EditorPointLookupFailure` 与 `classify_editor_point_lookup_failure`,只把「目标不存在 / 不属于当前账号」的固定文案认成用户侧不可用,其余(服务身份 403、定价身份未初始化、版本冲突、runtime 与连接故障)原样带出
- api-server tripo3d/target.rs:`collapse_target_unavailable` 改为只看归类,不再按 `is_client_error()` 分档,落点预检的模块注释同步
- 用例:target 侧覆盖「Unavailable 收敛、403/400/409/5xx 一律保留」;editor_project 侧新增归类用例,钉住运行时服务无权的 403 与「模型定价服务身份尚未初始化」不在不可用清单里
2026-09-24 19:53:38 +08:00
k88936 453e351fc6 3D 资源没有预览图时封面留空,不再拿模型对象顶上去
- api-server:`project_editor_client_media_src` 对 `model3d` 在没有预览(`thumbnail_src` 与存储的 `image_src` 都缺)时直接返回空,不再回落到模型对象;用例改成断言空串,并补「存储的 image_src 是空白」一例
- docs/adr 0003:写明这是唯一允许「有对象但 `imageSrc` 为空」的类别,消费方按空值显示占位;被否决项里补上「拿模型对象冒充 imageSrc 的投影回落」
- docs/technical Tripo 集成方案:资源表说明改成「有预览才填」,验收项 11 改成「预览缺失时留空、不得回落成模型对象」
- 画布侧 `Model3dViewerModel` 的注释同步:历史布局里仍可能留着指向模型本体的地址,图片元素不能加载它
2026-09-24 19:51:47 +08:00
k88936 2dfb60a34e 格式判定的注释与文档改成「信任后端的检测结果」,不再说魔数纠正错误声明
- packages/model3d-viewer:`resolveModel3dViewerFormat` 与字节识别函数的注释改写——声明优先是因为后端的 `content_type` 写入前已按字节核过,魔数只在声明缺失或认不出来时兜住,不负责纠错一个认得出来但不对的声明
- docs/technical Tripo 集成方案:补上同一条口径,与实现里「声明 → 字节魔数 → 地址扩展名」的顺序对齐

行为不变,只改注释与文档。
2026-09-24 19:51:25 +08:00
k88936 a61725003e 补齐定价文档里漏掉的版本比对:技术方案与决策记录同步为整段覆盖
- docs/technical Tripo 集成方案:删掉「后台保存携带定价版本做事务内比对、不一致 409」这句,改成整段覆盖、不做版本比对
- docs/project-memory 决策记录:在 2026-09-23 那条设计决策末尾追加 2026-09-24 的修订说明,指向同日「模型定价保存去掉版本比对」
2026-09-24 19:51:19 +08:00
k88936 34eee8ec6a Merge pull request 'ui editor 页面优化' (#337) from feat/ui-editor-v3 into master
Project CI / AI game creator shell Rust crates (push) Successful in 1m13s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m52s
Project CI / Backend tests (push) Successful in 4m42s
Project CI / Native shell tests (push) Successful in 6m4s
Project CI / Frontend tests (push) Successful in 2m7s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m39s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m6s
Project CI / AI game creator shell web tests (push) Successful in 1m28s
Project CI / Repository checks (push) Successful in 1m53s
Reviewed-on: #337
2026-09-24 19:45:46 +08:00
k88936 fecb8fe76f Merge remote-tracking branch 'origin/master' into feat/ui-editor-v3
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m25s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m57s
Project CI / Backend tests (pull_request) Successful in 4m44s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Failing after 6m40s
Project CI / Native shell tests (pull_request) Successful in 6m11s
Project CI / Frontend tests (pull_request) Successful in 2m27s
Project CI / Repository checks (pull_request) Successful in 2m50s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 9m44s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m38s
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
2026-09-24 19:43:20 +08:00
k88936 bdab414d32 Merge pull request '重构/对话错误类型化, 避免string-typed' (#474) from feat/fail-as-event into master
Project CI / AI game creator shell Rust crates (push) Successful in 1m29s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m57s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Reviewed-on: #474
2026-09-24 19:42:49 +08:00
k88936 ad2b37c6d3 后台模型定价保存去掉版本比对:保存即整段覆盖
- shared-contracts:删掉 `EDITOR_GENERATION_PRICING_VERSION_CONFLICT` 常量
- spacetime-module:`EditorGenerationPricingConfigUpsertInput` 去掉期望版本字段,删掉版本比对方法与它的用例,入库只按请求内容整段覆盖
- spacetime-client:重新生成定价 upsert input 绑定(少一个字段),记录映射同步去掉版本
- api-server:进程内缓存去掉版本字段与 409 冲突错误,`editor_generation_pricing()` / `save_editor_generation_pricing()` 只返回配置本身,`EditorGenerationPricingStore::replace` 注释写明「只是缓存刷新、不做版本校验、不是拦截点」
- api-server admin/app:后台 GET 不再返回 `updatedAtMicros`,POST 不再读 `expectedUpdatedAtMicros`,删掉 409 映射与「旧版本被拒」用例,新增「连续保存两次以后一次为准」
- admin-web:定价类型去掉版本字段,保存请求不再回传版本,删掉 409 分支与「重新读取」提示及其用例
- docs:主规范新增「保存语义」段(整段覆盖、同时只有一个管理员在操作、缓存替换不是拦截点),后端数据契约、ADR 0005、里程碑 / 实施计划、决策记录与 pitfalls 同步为删除版本比对
2026-09-24 19:33:41 +08:00
k88936 3900aa9157 容器尺寸变化时只重算相机取景,不再重新采一遍顶点
- packages/model3d-viewer/framing:取景求解器把每个采样点投影后的「上下向 / 左右向 / 深度」存成样本,resolve 可以带上新的宽高比重算;顶点投影与宽高比无关,比例变化时只在这份样本上重取最大值,距离算法与取值口径不变(含非有限顶点作废整次取景的旧行为)
- packages/model3d-viewer/scene:顶点采样改成加载后只做一次,computeFraming 只调用 resolve(aspect);拖拽面板连续触发 ResizeObserver 时不再重复 updateMatrixWorld 与逐顶点读取(单网格上限 20 万点)
- framing.test:补两条用例——带新比例重算与全新求解器结果一致、非有限顶点回落到与尺度相关的默认距离
2026-09-24 19:19:58 +08:00
k88936 6679dd2ebf 把 Tripo 配置写成明确的破坏性部署要求,并说明刻意不做开关
- docs 开发运维:Tripo 两项配置改成以「破坏性部署要求」表述,写明升级前必须配好、不做开关也没有缺配置先启动的逃生口,不需要 3D 的机器只跑不检查该配置的两个角色
- docs/adr 0006:补上同一条口径与理由(允许缺配置启动就会退回「起得来但悄悄坏掉」的形态),并写明被否决的逃生口
2026-09-24 19:18:27 +08:00
k88936 647822bbc4 写明产物是单文件,多文件模型的兄弟资源拼接只算兜底
- packages/model3d-viewer:把 resolveModel3dViewerResourceUrl 的注释改成实话——产物是单文件(.glb 自带几何贴图,.fbx 媒体内嵌),多文件模型不会出现,最多是「模型 + 一个 bin」;这段补签名只是最后一层兜底,签名按单个文件签发时会被云端拒绝,不指望它能读成功
- docs/adr 0003:同一条前提写进 ADR,并写明将来真要支持多文件模型时应当由宿主为每个兄弟文件分别换取临时地址,而不是继续扩展这段拼接
2026-09-24 19:18:10 +08:00
k88936 2fa89006c4 Merge remote-tracking branch 'origin/master' into feat/fail-as-event
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m39s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m53s
Project CI / Backend tests (pull_request) Successful in 5m10s
Project CI / Native shell tests (pull_request) Successful in 6m36s
Project CI / Frontend tests (pull_request) Successful in 2m6s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 9m8s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 10m2s
Project CI / Repository checks (pull_request) Successful in 1m53s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m24s
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
2026-09-24 19:17:48 +08:00
k88936 5748cf303f 种子字段的对外类型改成普通数字,不再导出 bigint
- shared-contracts:多视图请求与文生 / 图生参数的 seed 注记从 `bigint | null` 改成 `number | null`,并写明只支持 JS 安全整数范围(2^53-1)内的取值;Rust 侧仍是 `Option<i64>`,反序列化行为不变
- packages/shared:重新生成 model3d 绑定,seed 变成 `number | null`,请求体可以直接 JSON 序列化(带 bigint 的请求在 JSON.stringify 阶段必定抛错);顺带补上此前漏生成的多视图请求文档注释(「多视图生 3D」→「多视图生成 3D」)
- docs/technical:在 Tripo Provider 集成方案里写明 seed 为什么按 number 导出、代价是超出 2^53-1 的取值无法从 TS 侧精确构造
2026-09-24 19:17:42 +08:00
suzmii 96b0fada3a Merge pull request 'AGC ACL 提权修复按目标做 single-flight,避免并发重复弹 UAC(#498)' (#502) from fix/acl-elevation-single-flight into master
Project CI / AI game creator shell Rust crates (push) Successful in 1m28s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m7s
Project CI / Backend tests (push) Successful in 5m6s
Project CI / Native shell tests (push) Successful in 6m39s
Project CI / Frontend tests (push) Successful in 2m14s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m0s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 10m12s
Project CI / AI game creator shell web tests (push) Successful in 1m36s
Project CI / Repository checks (push) Has been cancelled
Reviewed-on: #502
2026-09-24 19:15:34 +08:00
suzmii a9f57c98ce Merge pull request 'AGC 模型目录改为启动期从上游同步,退役写死的 gpt-6-astra/luna 与别名(#506)' (#507) from enhance/default-model into master
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
Reviewed-on: #507
2026-09-24 19:15:22 +08:00
k88936 7cb7bd9581 合并:把 origin/master 的对外 MCP 语义工具与状态条、Markdown 修复并进接单化分支
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
- 冲突(`chat-composer.suite.ts` 接单窗口用例)按双方意图合并:保留上游「窗口期就要显示处理中卡片」,同时保留本分支「卡片要等宿主 `turn.started.at` 才开始读秒」;用例改为窗口期断言卡片在、无「已耗时」,再补发 `turn.started` 与开口用户条目后才断言气泡与读秒出现。
- 补上运行中回合的起点链路(合入前只有收口条目带起点,运行中卡片读不到秒):`useDirectThreadChatSubscription` 暴露 `turnStartedAt`,控制器透传 `directTurnStartedAt`,`DirectProjectChatView` 交给 `buildDirectChatTurns`。
- 同步 ADR、实施计划、`decision-log`、`pitfalls` 的口径与注释(两态投影;接单窗口只有卡片且不读秒)。
- 其余上游变更直接并入:对外 OpenAPI / MCP 语义工具方案与实现、状态条读秒粒度与几何、对话 Markdown 容错。
2026-09-24 19:13:53 +08:00
k88936 065b4ea330 给 UI 设计文档三个工具补上可读的回执明细与入参摘要
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
- 三个工具的持久回执补白名单分支:只放身份、相对路径、计数与回填说明,不再整块变成明细不可用
- 身份字段禁控制字符并限长,相对路径必须归一化后落在 ui/ 下,含宿主路径或 file URI 即失败关闭
- 回填说明按既有口径把绝对路径脱敏成占位符,超长或带控制字符的整条明细失败关闭
- 明细总长仍守 500 字符上限:清单能放多少放多少,放不下的部分用总数表达
- 入参摘要给出设计图逐张身份或目标文档 id,并把三个工具加进可读名单,不再只报哈希
- 补四条用例覆盖可读明细、脱敏、越界路径失败关闭与入参摘要
2026-09-24 19:08:18 +08:00
k88936 c39798e491 写明 ts-rs 的 feature 一律保持全开
- server-rs/Cargo.toml:把注释里「ts-rs 一律常开」改成明确口径——保持默认 features 原样,不写 default-features = false、也不逐个关掉,成员 crate 需要新能力时优先用默认已覆盖的部分,不改任何依赖声明
2026-09-24 19:07:48 +08:00
k88936 9bcd8f728b 后台各页的整数解析统一到共享助手
- apps/admin-web/src/pages/pageUtils.ts:新增 parsePositiveInteger,用 Number + Number.isSafeInteger,空串 / 非数字 / 小数 / 0 / 负数一律收敛成 0
- 删除 AdminTaskConfigPage、AdminProfileWalletConfigPage、AdminRechargeProductPage、AdminRedeemCodePage 与 adminEditorGenerationPricing 里各自的一份实现,5 个页面统一从 pageUtils 引入,修掉「钱包页拒 1.5、任务页把 1.5 当 1」这类口径不一致
- adminEditorGenerationPricing.test.ts 的引入路径同步改到 pageUtils
2026-09-24 19:07:32 +08:00
k88936 acdfb8ed73 3D 冒烟示例把产物写到 target 目录,不再落到仓库里
- server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs:产物落盘目录从「当前工作目录」改为 <cargo target>/tripo-smoke-artifacts,开始前建目录并打印路径;该目录本来就在入库排除范围内,根目录不会再攒出临时模型
- server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs:文件头文档同步改为说明新的产物落点
2026-09-24 19:05:51 +08:00
k88936 02f334b04a 删掉根目录临时 3D 样例模型并移除对应的根级忽略规则
- 删除仓库根目录手工下载的 image_to_model.glb / multiview_to_model.glb / text_to_model.glb 三个临时样例(合计约 125 MB,本来就没入库)
- .gitignore:移除只为它们存在的十条根级规则(/*.glb、/*.gltf、/*.fbx、/*.bin、/*.png、/*.jpg、/*.jpeg、/*.webp、/*.ktx2、/*.tga),根目录再出现同类文件会正常显示为未跟踪,不再被静默忽略
2026-09-24 19:05:43 +08:00
k88936 74609e2a5e 把 UI 设计文档三个工具算进项目变更门禁
- 项目变更判定与项目版本号推进判定补上 UI 设计文档的三个工具:成功返回即算改过项目
- 只重写派生产物的代码生成工具不推进项目版本号,避免虚报推进量、把"项目被别处改动"的误报再造出来
- 新建文档与跑工作流这两个工具在观察明细里报出真实推进格数,失败路径也报,避免切图素材已登记却漏计
- 非法人写的读明细逻辑收敛成一个helper,三处调用共用
- 补六条门禁用例覆盖成功即算、只出代码不算推进、真实推进量优先、失败但已推进才算
- 同步共享记忆的项目概览与决策记录
2026-09-24 18:58:12 +08:00
k88936 1ff1a9965b 前端:删掉 Direct 的本地乐观用户气泡,用户气泡只来自宿主条目
- controller 删 `pendingUserItemId` / `beginTurnCommand` / `endTurnCommand`:忙态改由 `beginTurnBusy` / `endTurnBusy` 持有,宿主认领判据 = `turnRunning` 或收口计数变过(一轮在同一次 consume 里开始并结束)
- controller 删 `startTurn` 的乐观追加与 `messageAppended` 重跑参数、`DirectProjectTurnInput.messageText` 与首轮的 `directInitialTurnText`;controller 不再需要 `assets`
- 投影删 `awaiting-start` 展示态(只剩 `running` / `finished`)、`localSentTimes` / `sameIdentitySentAt`、本地用户气泡与它开回合的路径;带身份的拒单提示在会话末尾自成一组,不挂进上一轮,也不开运行态标记
- 时间口径:起点只认 `turn.started.at`、终点只认 `turn.completed.at`,用户气泡时钟取宿主落盘 / 观测时间;两边都空的回合整条「本轮结束于 … 」隐藏,不再出现 0.0 秒
- 用例:改造 `directTurnPresentation`(本地用户消息不进回合、拒单提示自成一组、两态判据、失败说明按身份归位)、`directProjectTurn` / `directProjectTurnStatus` / appSurface 窗口期用例,`directProjectTurn` 补 `afterEach(cleanup)`
- 注释与文档:ADR「命令接单化」后续更新、实施计划新增「删掉本地乐观用户气泡」、decision-log 与 pitfalls 同日条目、Codex 原始历史方案的口径句、`codex_app_server` 用户条目时间注释
2026-09-24 18:20:24 +08:00
k88936 565c2277d5 恢复工作流时只读快照,不再重放已完成步骤的改动
- 检查点每步除记录结果外,再落一份「该步应用完之后」的状态快照,切分那步另带回填出错说明,旧日志无快照仍可解析
- 主流程只应用本次新完成那一步的改动,已完成步骤整步跳过,不再重复登记切图或重复累加回填说明
- 崩溃恢复改为只读检查点里的状态快照并逐级取回,删掉按记录结果重算目标状态的旧实现
- 只有结果、没有状态快照的旧检查点行按未完成处理,由主流程重跑该步
- 漂移与写回幂等判据改为对照快照:状态既不是本轮起点、也不是切分后那份才算漂移;文档已等于切分后快照即视为写回完成
- 同步 ADR、技术方案、代码地图与共享记忆里的检查点口径
2026-09-24 18:16:34 +08:00
suzmii 29c5409ac4 Merge remote-tracking branch 'origin/master' into fix/acl-elevation-single-flight
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m4s
Project CI / Backend tests (pull_request) Successful in 3m49s
Project CI / Frontend tests (pull_request) Successful in 1m57s
Project CI / Native shell tests (pull_request) Successful in 5m48s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 8m59s
Project CI / Repository checks (pull_request) Successful in 1m50s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m21s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 9m36s
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
#	docs/project-memory/shared-memory/pitfalls.md
2026-09-24 18:16:15 +08:00
k88936 cc472d0736 图生 3D 的引用类型判别改用枚举
- server-rs/crates/api-server/src/tripo3d/image_source.rs:ResolvedReference.kind 从 &'static str 改成 ResolvedReferenceKind 枚举,From<EditorReferenceRecord> 写值与匹配比较由同一处产出,字符串错字不再只在运行期暴露
- server-rs/crates/api-server/src/tripo3d/image_source.rs:对外文案仍由 as_str() 生成,用例同步改用枚举取值
2026-09-24 18:03:05 +08:00
k88936 d6f2ae157a 文档:回合顺序修复写进 ADR、实施计划与共享记忆
- ADR:补「开口用户条目先于整轮里的一切失败」这条顺序不变式(发点在接单 + 落盘之后、起 codex 之前),以及界面「回合归属只认身份」的口径
- 实施计划:新增「回合顺序修复(2026-09-24)」一节,写清现场、根因、两条改动与回归用例
- decision-log:新增同日决策(宿主发点提前 + 前端按身份归位、收口早退不吞说明)
- pitfalls:新增同日条目,并记下排查提示——先分清逻辑回合的 turn.started / turn.completed 与 app-server 协议的 turn/start 请求
2026-09-24 18:02:50 +08:00
k88936 4a75de1c31 前端:失败说明按回合身份归位,不再落进上一轮、气泡也不再自成假回合
- 回合归属改成按身份(开口用户条目的 canonical itemId):失败说明条目带 turnUserItemId(reducer 写,缺身份时保持原顺序语义),buildDirectChatTurns 按身份分组,同一身份的条目永远同一轮
- 本轮开口条目还没到(回合在宿主下发条目之前就失败、或历史切片还没读回)时,本地乐观气泡按身份挂回自己那一轮,不再另开一轮:界面不再出现「错误显示在用户消息上面」+「气泡底下 0.0 秒」+「上一轮借走本轮终点(15.6 秒)」这一组现象
- 收口早退不再吞掉还没写进界面的失败说明(订阅重建后的 bootstrap 只回放生命周期锚点):只补说明、终点时间与「回合完成」计数,不重开回合、不动本轮起点 / 终点 / 身份
- 用例:directTurnPresentation 复现现场(两个回合、说明与气泡同段、耗时不再借上一轮的终点);directThreadChat 补身份字段与早退不吞说明两条
2026-09-24 18:02:43 +08:00
k88936 2487a2c8e6 宿主:开口用户条目的发点提前到接单之后,失败说明才能挂回自己那一轮
- 本轮开口用户条目(item_completed,direct-codex:{clientTurnId}:user)原来在 app-server turn/start 应答之后才下发;接单到 turn/start 之间的失败(连不上 app-server、执行器未通过验收、历史注入失败)走不到那一步,事件流里只有逻辑回合的一对事件,没有开口条目
- 把那段内联下发抽成 emit_direct_thread_user_item,发点提前到「接单成立、用户条目落盘成功、起 codex 之前」(direct_runtime/user_input.rs 的命令主体),并删掉 turn/start 之后那一处:线上仍只有一处下发,不变式变成「接单 → 开口用户条目 → 整轮里其余一切」
- 新增回归用例 the_opening_user_item_is_emitted_before_anything_that_can_fail_in_the_turn:断言行首两条事件是带身份的 turn.started 与开口用户条目,终态只能在它们之后
- 回显过滤用例补上同一发点的模拟步骤(生产入口的两个动作:落盘 + 下发)
2026-09-24 18:02:26 +08:00
suzmii 997eba2b7b Merge branch 'master' into enhance/default-model
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m35s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m5s
Project CI / Backend tests (pull_request) Successful in 4m40s
Project CI / Native shell tests (pull_request) Successful in 6m13s
Project CI / Frontend tests (pull_request) Successful in 2m7s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 9m13s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 9m55s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m34s
Project CI / Repository checks (pull_request) Successful in 1m58s
2026-09-24 18:02:01 +08:00
k88936 06f091f0ff 平台层校验补上 pbr 依赖贴图
- server-rs/crates/platform-tripo/src/common/validation.rs:validate_generation_options 增加 texture=false 与 pbr=true 的组合拒绝(TripoField::Pbr),直连调用方不用再把这种不会成立的组合拖到 provider 侧才报错;放在 generate_parts 分支之后,不改变该分支原有的归因
- server-rs/crates/platform-tripo/src/common/validation.rs:补用例锁住 texture=false + pbr=true 被拒、texture=true 时放行
2026-09-24 18:01:24 +08:00
k88936 b83113619e 产物结构体不再派生 Debug,改成只打元数据
- server-rs/crates/platform-tripo/src/common/types.rs:TripoArtifactBytes 去掉 derive(Debug),改为手写实现,只输出 url / content_type / content_length / 字节数,几十 MB 的 bytes 不会再被一次 {:?} 刷进日志
- server-rs/crates/platform-tripo/src/common/types.rs:补用例锁住 Debug 只带字节数、不带字节内容
2026-09-24 18:00:45 +08:00
k88936 03aec35350 写明 TripoUrl 脱敏只覆盖 query 与 fragment
- server-rs/crates/platform-tripo/src/common/types.rs:redacted() 的文档注明脱敏范围只到 query / fragment,若 provider 改成把 token 写进路径(如 path-style SAS)则需一并处理路径段;无 query 分支补注释说明路径原样保留
2026-09-24 18:00:30 +08:00