fix(contracts): studio.yaml 契约评审跟进——收紧 modifyPatch + idempotency 语义(单轮 codex 评审)

codex xhigh 契约评审 FREEZE-WITH-FIXES(零 P0 破坏)。逐条收口:
- P1 payload 必填 + mode×target.kind 锁定映射(后端可信边界校验,不用 oneOf 保 mock/codegen 简单)
- P1 target path/id anyOf 强制至少其一
- P1 payload value/intent 按 mode 必填(后端校验)
- P2 AssetContextItem 补 provider + 后端派生 assets[].id 说明
- P2 idempotency 语义(同 userId+op+key 命中返既有 taskChain/缺省不去重/TTL 24h)
- P2 execution §5.6 JSON 指针示例纠错 /gameDefinition/config/speed→/config/speed(config 顶层,对齐 keystone)

复验:YAML 绿、14 $ref 零悬空、六类对齐 keystone、现有端点/VO 零破坏。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zizi 2026-06-17 16:00:52 +00:00
parent d97d0bae5c
commit 38729ffdaa
2 changed files with 15 additions and 6 deletions

View File

@ -29,6 +29,7 @@ openapi: 3.0.3
# x-feign-contracts(新增 seam,studio 为调用方,本契约不对外暴露 Feign):
# - aigc-api AigcApi.submitGenerate 扩 mode/baseVersionId/modifyPatch/idempotencyKey(生命周期编排参数,additive;后端线落地)。
# - project-api ProjectApi 取 baseVersion 源项目引用 + 新预览版落库(version 产物权威仍在 project;源项目独立 game_source_project 表存 V18)。
# idempotency 语义(create/modify/extend 共用):同 userId+operation+idempotencyKey 命中则返回既有 taskChain(不重复触发生成);缺省=不去重;建议 TTL 24h。
info:
title: 造梦AI studio 模块 API
version: 1.0.0
@ -221,8 +222,12 @@ components:
StudioModifyReqVO:
type: object
required: [baseVersionId, mode, target]
description: 改源不改产物(execution §5.6 modifyPatch);产新预览版,不动 currentVersion,走发布审核
required: [baseVersionId, mode, target, payload]
description: >-
改源不改产物(execution §5.6 modifyPatch);产新预览版,不动 currentVersion,走发布审核。
【mode×target.kind 锁定映射——后端可信边界校验,违则 1-112-*** 拒(schema 不用 oneOf 编码以保 mock/codegen 简单)】:
mode=deterministic ⇔ target.kind∈{asset,config,level} ∧ payload.value 必填(确定性覆写免 LLM);
mode=regenerate-module ⇔ target.kind=behavior ∧ payload.intent 必填(LLM 只重生成那一个 behavior)。
properties:
baseVersionId: { type: integer, format: int64, description: '被改的 base 产物版本 ID(project.game_version.id)', example: 4096 }
mode: { type: string, enum: [deterministic, regenerate-module], description: 'deterministic=确定性编辑源文件免 LLM;regenerate-module=LLM 只重生成单 behavior 模块', example: 'deterministic' }
@ -233,7 +238,10 @@ components:
StudioModifyTarget:
type: object
required: [kind]
description: 寻址源项目部件(path 与 id 二选一)
anyOf:
- { required: [path] }
- { required: [id] }
description: 寻址源项目部件(path 与 id 至少其一:JSON 指针或部件 id)
properties:
kind: { type: string, enum: [asset, config, level, behavior], description: '换美术=asset / 调参=config / 改关卡=level(scene) / 改玩法=behavior' }
path: { type: string, description: '源项目内 JSON 指针(如 /config/speed、/assets/0、/gameDefinition/scenes/2)', example: '/config/speed' }
@ -241,7 +249,7 @@ components:
StudioModifyPayload:
type: object
description: mode=deterministic 用 value(直接覆写免 LLM);mode=regenerate-module 用 intent(喂 LLM 重生成意图)
description: mode=deterministic 用 value(直接覆写免 LLM,必填);mode=regenerate-module 用 intent(喂 LLM 重生成意图,必填);后端按 mode 校验(见 StudioModifyReqVO 锁定映射)
properties:
value: { type: object, additionalProperties: true, description: 'deterministic 新值(确定性覆写)' }
intent: { type: string, maxLength: 1000, description: 'regenerate-module 改玩法逻辑的自然语言意图(只重生成那一个 behavior)', example: '把陨石下落改成会左右摇摆' }
@ -259,11 +267,12 @@ components:
StudioAssetContextItem:
type: object
required: [category, ref]
description: 六类素材引用(对齐 source-project.schema.json assetSpec.category;取代旧 attachments)
description: 六类素材引用(输入态,对齐 source-project.schema.json assetSpec.category;取代旧 attachments)。后端 asset 节点据此派生 sourceProject.assets[].id(项目内 id)、provider 默认 mmx-cli(§5.5)。
properties:
category: { type: string, enum: [sprite, character, effect, scene, ui, music], description: '六类:图元/角色/特效/场景/界面/音乐' }
ref: { type: string, description: '平台 assetId/ref(主)', example: 'asset_88231' }
url: { type: string, format: uri, description: '只读镜像 URL(可空)' }
provider: { type: string, description: '素材来源 provider(可空,默认 mmx-cli;切 provider 不动消费侧,§5.5)', example: 'mmx-cli' }
# ========== 响应 VO ==========
StudioTemplateRespVO:

View File

@ -322,7 +322,7 @@ modify = 在固定结构上改一处 + 重构建;对齐 v2 review §3.2(改源
"mode": "deterministic | regenerate-module", // 确定性编辑 | LLM 重生成模块
"target": { // 寻址源项目部件
"kind": "asset | config | level | behavior", // 换美术=asset / 调参=config / 改关卡=level(scene) / 改玩法=behavior
"path": "string", // 源项目内 JSON 指针(如 /gameDefinition/config/speed、/assets/0、/gameDefinition/scenes/2)
"path": "string", // 源项目内 JSON 指针(如 /config/speed、/assets/0、/gameDefinition/scenes/2;config/assets 为顶层,scenes 在 gameDefinition 下,对齐 keystone)
"id": "string" // 或按部件 id 寻址(behaviors[].id / assets[].id)
},
"payload": { // mode=deterministic:新值(直接覆写,免 LLM);mode=regenerate-module:重生成意图(喂 LLM)