{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://wanxiang.ai/contracts/play-loop/reference-asset-record.schema.json", "title": "ReferenceAssetRecordV1", "description": "ReferenceAssetRecord/1。可复用校准与参照资产的持久消费记录,字段定义权威源为金标 SoT docs/architecture/产品/游戏内容金标.md §7。分类以消费记录为互斥单位、不以物理目录为单位;消费者只接收 recordId,再从持久注册表读取并核验完整记录。role 与 lifecycleStatus 正交:candidate/migration_pending 不是第五种角色;同一物理资产新增第二个角色必须新建第二条记录,禁止就地改写 role。active 态必须补齐 consumerRef/signedBy/signedAt(SoT『active 时必填』);game_content_gold 升 active 还必须有已批准 designIntent(SoT §7 字段表 designRef 行)。candidate/migration_pending 处于补证阶段,允许这些字段暂为 null,但 artifactHash 等制品身份在建记录时即须补齐——迁移清单阶段的占位 hash 须在注册表 migrationNotes 中显式标注,active 前必须替换为真 hash。", "type": "object", "required": [ "schemaVersion", "recordId", "role", "lifecycleStatus", "assetRef", "assetVersion", "artifactHash", "evidenceRefs" ], "properties": { "schemaVersion": { "const": "ReferenceAssetRecord/1" }, "recordId": { "description": "稳定唯一的记录标识,创建后不可改;所有消费日志与证据引用它。允许下划线开头以兼容 _fewshot-*/_template-* 既有资产名。", "type": "string", "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*$" }, "role": { "description": "消费角色,四选一且互斥。harness_fixture=校工具(Actor/Judge/专项夹具);prompt_eval_gold=校裁判(rubric 正反例与校准卷);generation_exemplar=引导生成器(模板与范例);game_content_gold=完整内容参照(须九维人工签认,夹具不得冒充)。", "enum": ["harness_fixture", "prompt_eval_gold", "generation_exemplar", "game_content_gold"] }, "lifecycleStatus": { "description": "生命周期状态,与 role 正交。candidate=候选待补证;migration_pending=迁移清单已登记、制品身份待冻结绑定;active=责任人核对设计与证据后签认、可供 live 消费;retired=退休只读。候选与迁移状态不是第五种角色。", "enum": ["candidate", "migration_pending", "active", "retired"] }, "assetRef": { "description": "指向唯一冻结制品的引用(仓内路径或稳定标识)。hash 漂移必须新建版本或记录,不得覆盖旧证据。migration_pending 阶段可为占位引用,active 前必须绑定真制品。", "type": "string", "minLength": 1 }, "assetVersion": { "description": "制品版本(如夹具 r3、组件 1.0.0)。迁移时冻结;未冻结资产以占位值登记并在注册表 migrationNotes 标注。", "type": "string", "minLength": 1 }, "artifactHash": { "description": "冻结制品的 SHA-256(play-loop 惯例 64 位小写十六进制、无算法前缀)。迁移清单阶段允许占位 hash(须标注),active 前必须替换为真 hash;不得以覆盖旧 hash 的方式『更新』证据。", "$ref": "#/$defs/sha256" }, "consumerRef": { "description": "具体消费者身份:runner/profile、Actor/Judge/rubric 版本、prompt id@version 或内容评测版本。active 时必填(见 allOf 条件);非 active 态为 null 表示尚未接线消费。", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }, "designRef": { "description": "已批准 designIntent 的引用列表(设计文档仓内路径或 recordId/ref)。game_content_gold 升 active 必须指向已批准 designIntent(见 allOf 条件);完整游戏来源的 generation_exemplar 同理;其它角色不适用时置 null,理由写入注册表 migrationNotes。candidate 阶段允许已批 designIntent 先行登记(如《山海行纪》2026-07-23 契约追认)。", "anyOf": [ { "type": "array", "items": { "type": "string", "minLength": 1 }, "minItems": 1 }, { "type": "null" } ] }, "evidenceRefs": { "description": "角色对应的校准、真玩、审计或内容证据引用;不得只写自然语言结论。建记录时必须存在本字段;暂无证据引用时以空数组显式表达『待补』,不允许省略字段。", "type": "array", "items": { "type": "string", "minLength": 1 } }, "signedBy": { "description": "角色责任人签认身份。active 时必填;内容金标须满足金标 SoT §6 人工终审。candidate/migration_pending 为 null。", "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }, "signedAt": { "description": "签认时间(ISO 8601 日期或日期时间)。active 时必填;candidate/migration_pending 为 null。", "anyOf": [ { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2})?(Z|[+-]\\d{2}:?\\d{2})?)?$" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "if": { "properties": { "lifecycleStatus": { "const": "active" } }, "required": ["lifecycleStatus"] }, "then": { "properties": { "consumerRef": { "type": "string", "minLength": 1 }, "signedBy": { "type": "string", "minLength": 1 }, "signedAt": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2})?(Z|[+-]\\d{2}:?\\d{2})?)?$" } }, "required": ["consumerRef", "signedBy", "signedAt"] } }, { "if": { "properties": { "role": { "const": "game_content_gold" }, "lifecycleStatus": { "const": "active" } }, "required": ["role", "lifecycleStatus"] }, "then": { "properties": { "designRef": { "type": "array", "items": { "type": "string", "minLength": 1 }, "minItems": 1 } }, "required": ["designRef"] } } ], "$defs": { "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" } } }