把"一句话生成"对真实创作者放开前焊死 2 道硬阻塞闸:单用户压不垮全局串行 worker、违规 prompt 进不了生成与 feed。
契约先行(V15 DDL/错误码/配置类先于业务),feature-flag 默认关=现行行为逐字不变。
D12 控制平面 v0:
- 抽私有 enqueueWithControlPlane,submitGenerate 与 retryTask 共用(决策D:retry 也走全门,违规/超配额无法靠 retry 绕过)。
门序(最便宜→最贵):① 降级门(infra ConfigApi 读 aigc.generate.paused,fail-open on switch)
→ ② 配额+并发门(per-creator×level 当日非取消计数 + 在飞并发,判定一律 >=)
→ ③ 背压门(全局在飞 >= queue-depth-limit)→ ④ GP9 safety(放最后)→ ⑤ insert + 额度记账骨架(仅 log,非真扣费)。
- V15.0.0 game_aigc_task 加 level 列(TINYINT NOT NULL DEFAULT 1)+ AigcTaskDO.level;v0 统一落 L1(会员档未建,避孤儿)。
- 新建 AigcControlPlaneProperties(前缀 aigc.control-plane):enabled/queue-depth-limit/safety{timeout-ms,max-retry,fail-closed,
new-api base/key/model}/quota{L1/L2/L3 daily+concurrency}(数值占位待创始人)。
- ErrorCodeConstants 加 001 子段 5 码(配额/背压/降级 + UNSAFE_PROMPT/LLM_SAFETY_ERROR);均业务码,不产生 HTTP 429/503。
- AigcTaskMapper 加 3 计数查询(selectCount,零原生 SQL/零 DDL 索引);aigc-server pom 补 huijing-module-infra-api 依赖。
GP9 合规先行段:
- 新建服务层独立 SafetyCheckClient(不复用执行器 ExecutorLlmClient——被 aigc.executor.enabled 门控、服务层注入不到):
new-api 连接走 control-plane 配置(与执行器开关解耦,解 new-api 服务层可达性),装载 01-safety prompt,短超时 8s + 至多 1 重试。
- 接门④:safe=false 抛 AIGC_UNSAFE_PROMPT 同步拒绝不入队;超时/失败 fail-closed 抛中性 AIGC_LLM_SAFETY_ERROR(复用 FailureReasonEnum
语义不新增枚举)。pom copy-glob 加 01-safety/*.md(已验进 classpath)。
- 补 10 条违规负例集 contracts/prompts/eval/safety.prompt-check/(十类红线各 1 条,全 expectedSafe:false)+ README。
装配:AigcControlPlaneConfiguration @ConditionalOnProperty(aigc.control-plane.enabled) 注册 Bean;AigcTaskServiceImpl
经 ObjectProvider 软注入(enabled=false/Bean 缺席 → 全门+GP9 旁路 = 现行行为)。
零越界:门③ promptHash 缓存未做(promptHash 仍照算照落 provenance,v0 不读它做缓存);真实计费扣退/组B 落库/审核台/会员档数值均未触碰。
验证(mini-desktop):test-compile BUILD SUCCESS;AigcControlPlaneTest 16/16 + SafetyCheckClientTest 7/7 +
AigcTaskServiceImplTest 9/9(零回归)+ 全 aigc-server 99 run/0 fail;V15 SQL 真 MySQL 8.4.8 语法校验通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
contracts/ —— 绘境AI 八类契约单一事实源(Day-0 / M0)
定位:本目录是跨三仓(game-cloud 后端 / game-admin 管理端 / game-studio 产品端)与五工位(WS1-WS5)共享的契约单一事实源。 纪律:任何接口 / 数据结构 / 事件 / SDK 签名变更,先改本目录、再写代码,并通知相关方(见
.agents/skills/contract-first-development.md)。 里程碑:Day-0(6/9 上午)全员锁定下列契约并 git 提交 = M0。锁定后各工位 mock 对方接口并行开发,集中联调 Day11 起。
一、八类契约清单与 owner
| # | 契约 | 路径 | owner(主笔) | 消费方 |
|---|---|---|---|---|
| 1 | API OpenAPI | api-schemas/*.yaml |
WS1 lead(全员 review) | 前端 mock / 各模块互调 |
| 2 | DB 迁移 | db-schemas/V*.sql |
WS1 | 后端各模块 |
| 3 | SDK 接口 + postMessage 协议 | sdk-interface.d.ts |
WS3 SDK 负责人 | game-studio 宿主 / 游戏侧 |
| 4 | GamePackage 清单 | game-package.schema.json |
WS3 + WS2 | 生成→编译→预览→发布→运行全链路 |
| 5 | telemetry 事件 | events.schema.json |
WS5 | 前端埋点 / SDK 上报 / 看板 |
| 6 | dify-workflow-io.json(见 DEPRECATED-dify-workflow-io.md) |
WS2 | ||
| 7 | 广告位配置 | ad-slot.schema.json |
WS5 | ad 模块 / SDK Plugin.Ad |
| 8 | Prompt Registry | prompts/(独立目录) |
各 prompt owner 工位 | aigc / 生成链路(见 prompt-governance) |
M0 八类契约已锁(JSON/YAML/Schema 语法校验通过):#1 project.yaml · #2 V1.0.0__…sql · #3 sdk-interface.d.ts · #4 game-package · #5 events · #6 dify-workflow-io · #7 ad-slot · #8 prompts/。 Wave1 脊柱 4 模块契约已补并锁(aigc/runtime/feed/telemetry,2026-06-08):经契约先行起草 + 一致性评审 + 收口(§2.1)+ 主 agent 校验(YAML 语法/裸 select* 0/错误码段 101-104 独占/Flyway V2-5 唯一)。 Wave2 变现契约已补并锁(ad/trade,2026-06-08):
ad.yaml+trade.yaml(API #1)+V6.0.0/V7.0.0(DB #2),消费既有 #7 ad-slot / #5 events 不重造;经主 agent 校验(YAML 语法/错误码 111·106 独占/Flyway V6-7 唯一/金额用「分」/资金幂等键+状态机/ad↔trade Feign seam 一致);ad 计费uk_trace由主 agent 收紧为(trace_id,event_type,tenant_id)防 reward 被 impression 静默吞掉。pay=复用 huijing-pay 后置(收单 P1)。 Wave3 跨主线收口(进行中):新增studio(创作主链路最小版编排,错误码 112 / Flyway V8)+compliance(锁风门 Gate,发布前合规扫描)两模块契约。Phase A 已收口 project 侧:publish 唯一化(返回 admitted+gates 门禁聚合)、ProjectApi seam 定稿(getCurrentVersionId GAP-3 / createProject 写类 RPC)、GAP-4 把events.schema.json信封 envelope/user 由 snake_case 统一为 camelCase(与 telemetry.yaml/前端 SDK 对齐)。compliance gate 在 project.submitPublish 内仅留 Phase C 接入 seam(TODO 注释),尚未接 ComplianceGateApi。其余模块(community/ip/biz)待后续波次补。游戏宿主装载契约(指针登记,不折进上表跨仓 8 类):Runner v2 P1 新立 additive 第 9 类契约,落
game-runtime/src/core/game-host.d.ts(与api.d.ts同目录,非本目录)。理由:它是 game-runtime 内部「host↔游戏工厂」接线面,消费方只在 game-runtime(host boot + 生成 agent),落同目录 import 方向顺(./api.d.ts);落本目录会让跨仓 SSOT 反向相对 import../game-runtime/src(拆仓即断)。消费方=host boot(装游戏)+ 生成 agent(产出靶);与受控面 6 项 additive(受控面零改)。详见docs/agent-specs/2026-06-13-P1-王蓝莓上引擎-execution.md§5/§12-A1。
contracts/
├── README.md # 本文件
├── api-schemas/ # #1 OpenAPI 3.0(每模块一个 yaml)
│ ├── project.yaml # 黄金模块 project(已落地)
│ ├── aigc.yaml # Wave1 生成(已锁)
│ ├── runtime.yaml # Wave1 预览/试玩/包服务(已锁)
│ ├── feed.yaml # Wave1 游戏流/双轨专区(已锁)
│ ├── telemetry.yaml # Wave1 遥测/聚合回灌(已锁)
│ ├── ad.yaml # Wave2 广告引擎(已锁;含 ad↔trade Feign seam)
│ ├── trade.yaml # Wave2 分账/结算/提现(已锁)
│ └── studio.yaml # Wave3 创作主链路最小版(编排 project/aigc/runtime)
├── db-schemas/ # #2 Flyway 迁移(本目录=授权源;执行副本在 game-cloud/huijing-server/src/main/resources/db/migration/,Flyway 校验和敏感须保持 diff 一致)
│ ├── V1.0.0__create_game_project.sql
│ ├── V2.0.0__create_game_aigc.sql # aigc(每模块独占主版本号)
│ ├── V3.0.0__create_game_runtime.sql
│ ├── V4.0.0__create_game_feed.sql
│ ├── V5.0.0__create_game_telemetry.sql
│ ├── V6.0.0__create_game_ad.sql # ad(广告位 + 收入台账,Wave2)
│ ├── V7.0.0__create_game_trade.sql # trade(账户 + 流水 + 提现,Wave2)
│ └── V8.0.0__create_game_studio.sql # studio(创作主链路编排状态,Wave3)
├── game-package.schema.json # #4 GamePackage 清单(已落地)
├── events.schema.json # #5 telemetry 事件 v1(已落地)
├── sdk-interface.d.ts # #3 已锁(SDK API + postMessage 协议)
├── dify-workflow-io.json # #6 ⚠️ 降级远期未部署(见 DEPRECATED-dify-workflow-io.md;JSON 保留作历史,现行=new-api 网关)
├── ad-slot.schema.json # #7 已锁(广告位配置)
└── prompts/ # #8 已锁(README + registry.yaml + 01-safety 示例 + 8 阶段)
二、版本与兼容规则(硬约束,来自工程规范 §5)
- API:URL Path 版本,新增字段不算 breaking;删除/重命名字段 = 升版本;旧版本保留 ≥ 3 个月,废弃用
Deprecation: true+Sunset: <date>。 - 事件:每事件带
schema_version(如game_play_start.v2);新增字段给默认值、老消费者忽略未知字段;不兼容变更用新事件名并行消费。 - DB:
V{版本号}__{描述}.sql;已合入的迁移禁止修改,回滚写新补偿迁移;CI 跑flyway validate阻断不合规。 - 契约对齐顺序:后端先写
-api包的 VO/DTO,前端据此定义 TS 类型。
2.1 跨模块对齐约定(Phase A 评审收口,HJ-BUILD-FIX)
- 两个
qualityScore不同量纲、不可互相回灌:aigc=生成质量分(0-1,对齐 Dify #6);telemetry/feed=运营质量分(0-100)。两者来源与计算口径不同,禁止跨模块直接赋值或换算回填。 game_version.package_url/checksum/bundle_size权威写者=runtime(编译成功后回写);aigc 只回填version_id与生成元数据,不得写入编译产物字段。play_count权威源=telemetrygame_play_start事件聚合;runtime session 仅作时长/质量观测,不作为播放计数源;sessionId透传至 telemetrysession_id用于对账。
三、端与鉴权(API 契约共同前提,来自工程规范 §4)
/app-api/** → 产品端(game-studio),用户 Token + DataPermission(创作者只见自己数据)
/admin-api/** → 管理后台(game-admin),管理员 RBAC
URL 格式:/{端前缀}/{模块}/{资源}/{动作}。端前缀 /app-api·/admin-api 沿用 huijing 默认,由框架按 controller.app·controller.admin 包名自动添加(Controller 内 @RequestMapping 只写 /{模块},不含端前缀)。权限在网关 + 注解双重校验,前端不可作为唯一边界。
四、错误码段(每模块独占,来自工程规范 §1.3)
1-{模块段}-{业务}-{细分}:project=100 / aigc=101 / runtime=102 / feed=103 / telemetry=104 / pay=105 / trade=106 / community=107 / ip=108 / compliance=109 / biz=110 / ad=111 / studio=112。新增模块在 -api 错误码常量类登记,禁止重叠。