games-development-ai/contracts/play-loop/single-roll-fact.schema.json
lili cbfd4d871b
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
feat(acceptance): 闭合 playtest v3 与 A+ 可信消费链
固化 Match-3 生产者、视觉、音频与双 Judge 证据闭包。

将《山海行纪》r1.1 绑定新的不可变 release,并以生产预检现场核验 bundle、Registry/2 和 25 项 Writer 快照。

同步地图1平衡锁值、跨游戏回归修复、验收契约与 SoT 证据。
2026-07-28 20:16:13 -07:00

195 lines
8.9 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://wanxiang.ai/contracts/play-loop/single-roll-fact.schema.json",
"title": "SingleRollFact",
"description": "Node runner 交给 Python rollGuard 的 playtest/2 单掷事实。它没有终裁写权,但必须完整携带 profile、动作时间推进、版本化事件、有序义务引用和 Judge 封存事实。",
"type": "object",
"required": [
"schemaVersion", "packageType", "runId", "roll", "gameId", "genre", "templateRoute", "proofProfileId",
"proofRegistryVersion", "taskBindingHash", "acceptanceRequestHash", "evidenceMode", "artifactHash", "briefHash",
"requestedSeed", "actualSeed", "policySeed", "seedOptionSource", "environment", "actor",
"actions", "frames", "events", "briefRuleMatches", "proofObligations", "firstPlay",
"proofPackageRef", "proofPackageHash", "judgePackageRef", "judgePackageHash", "judge",
"errors", "costRmb", "cost"
],
"properties": {
"schemaVersion": { "const": "playtest/2" },
"packageType": { "const": "SingleRollFact" },
"runId": { "type": "string", "minLength": 1 },
"roll": { "type": "integer", "minimum": 1, "maximum": 2 },
"gameId": { "type": "string", "minLength": 1 },
"genre": { "enum": ["narrative", "trpg", "heritage", "puzzle", "sim-business"] },
"templateRoute": { "type": "string", "pattern": "^_template-[a-z0-9-]+$" },
"proofProfileId": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" },
"proofRegistryVersion": { "type": "string", "minLength": 1 },
"taskBindingHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"acceptanceRequestHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"evidenceMode": { "enum": ["native", "legacy-adapted"] },
"artifactHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"briefHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"requestedSeed": { "type": "integer", "minimum": 0 },
"actualSeed": { "type": "integer", "minimum": 0 },
"policySeed": { "type": "integer", "minimum": 0 },
"seedOptionSource": { "type": "string", "minLength": 1 },
"environment": { "$ref": "playtest-evidence.schema.json#/$defs/environment" },
"actor": { "$ref": "#/$defs/runnerActor" },
"actions": {
"type": "array",
"items": { "$ref": "playtest-evidence.schema.json#/$defs/actionRecord" }
},
"frames": {
"type": "array",
"items": { "$ref": "#/$defs/evidenceFrame" }
},
"events": {
"type": "array",
"items": { "$ref": "game-event.schema.json" }
},
"briefRuleMatches": {
"type": "array",
"items": { "type": "string", "minLength": 1 }
},
"proofObligations": {
"type": "array",
"items": { "$ref": "playtest-evidence.schema.json#/$defs/proofObligation" }
},
"firstPlay": { "$ref": "playtest-evidence.schema.json#/$defs/firstPlay" },
"proofPackageRef": { "type": "string", "minLength": 1 },
"proofPackageHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"judgePackageRef": { "type": "string", "minLength": 1 },
"judgePackageHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"judge": { "$ref": "#/$defs/runnerJudge" },
"errors": {
"type": "array",
"items": { "type": "string", "minLength": 1 }
},
"costRmb": { "type": "number", "minimum": 0 },
"cost": { "$ref": "#/$defs/costLedger" }
},
"patternProperties": { "^_": {} },
"additionalProperties": false,
"$defs": {
"promptIdentity": {
"type": "object",
"required": ["id", "version", "hash"],
"properties": {
"id": { "type": "string", "minLength": 1 },
"version": { "type": "string", "minLength": 1 },
"hash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" }
},
"additionalProperties": false
},
"runnerActor": {
"type": "object",
"required": [
"model", "apiClientId", "sessionId", "systemPromptVersion", "contextProjectionVersion",
"evidenceDir", "requestedGameSeed", "actualGameSeed", "policySeed", "prompt", "usage"
],
"properties": {
"model": { "type": "string", "minLength": 1 },
"apiClientId": { "type": "string", "minLength": 1 },
"sessionId": { "type": "string", "minLength": 1 },
"systemPromptVersion": { "type": "string", "minLength": 1 },
"contextProjectionVersion": { "type": "string", "minLength": 1 },
"evidenceDir": { "type": "string", "minLength": 1 },
"requestedGameSeed": { "type": "integer", "minimum": 0 },
"actualGameSeed": { "type": "integer", "minimum": 0 },
"policySeed": { "type": "integer", "minimum": 0 },
"prompt": { "$ref": "#/$defs/promptIdentity" },
"usage": { "type": "array", "items": { "type": "object" } }
},
"additionalProperties": false
},
"runnerJudge": {
"type": "object",
"required": [
"model", "apiClientId", "sessionId", "systemPromptVersion", "contextProjectionVersion",
"evidenceDir", "packageHash", "decision", "degraded", "obligationResults",
"contradictions", "blockingProblems", "problems", "failureClass", "summary", "reason",
"failureSignature", "prompt", "usage"
],
"properties": {
"model": { "type": "string", "minLength": 1 },
"apiClientId": { "type": "string", "minLength": 1 },
"sessionId": { "type": "string", "minLength": 1 },
"systemPromptVersion": { "type": "string", "minLength": 1 },
"contextProjectionVersion": { "type": "string", "minLength": 1 },
"evidenceDir": { "type": "string", "minLength": 1 },
"packageHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"decision": { "$ref": "playtest-evidence.schema.json#/$defs/outcome" },
"degraded": { "type": "boolean" },
"obligationResults": {
"type": "array",
"items": { "$ref": "#/$defs/judgeObligationResult" }
},
"contradictions": { "type": "array", "items": { "type": "string", "minLength": 1 } },
"blockingProblems": { "type": "array", "items": { "type": "string", "minLength": 1 } },
"problems": { "type": "array", "items": { "type": "string", "minLength": 1 } },
"failureClass": { "enum": ["none", "broken", "hollow", "off_brief"] },
"summary": { "type": "string" },
"reason": { "type": "string" },
"failureSignature": { "type": ["string", "null"] },
"prompt": { "$ref": "#/$defs/promptIdentity" },
"usage": { "type": "object" }
},
"additionalProperties": false
},
"judgeObligationResult": {
"type": "object",
"required": ["id", "status", "sequenceRefs", "evidenceRefs"],
"properties": {
"id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" },
"status": { "enum": ["satisfied", "failed", "missing", "contradicted"] },
"sequenceRefs": {
"type": "array",
"items": { "$ref": "playtest-evidence.schema.json#/$defs/sequenceRef" }
},
"evidenceRefs": { "type": "array", "items": { "type": "string", "minLength": 1 } }
},
"additionalProperties": false
},
"evidenceFrame": {
"type": "object",
"required": ["actionId", "kind", "ref", "hash", "artifactHash"],
"properties": {
"actionId": { "type": ["string", "null"] },
"kind": { "enum": ["pre", "post"] },
"ref": { "type": "string", "minLength": 1 },
"hash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"artifactHash": { "$ref": "playtest-evidence.schema.json#/$defs/sha256" },
"frameId": { "type": "string", "minLength": 1 }
},
"additionalProperties": false
},
"costLedger": {
"type": "object",
"required": ["costRmb", "entries"],
"properties": {
"costRmb": { "type": "number", "minimum": 0 },
"entries": { "type": "array", "items": { "$ref": "#/$defs/costEntry" } }
},
"additionalProperties": false
},
"costEntry": {
"type": "object",
"required": [
"role", "model", "promptTokens", "completionTokens", "cachedTokens",
"modelRatio", "completionRatio", "cacheRatio", "quota", "rmb"
],
"properties": {
"role": { "enum": ["Actor", "Judge"] },
"model": { "type": "string", "minLength": 1 },
"promptTokens": { "type": "integer", "minimum": 0 },
"completionTokens": { "type": "integer", "minimum": 0 },
"cachedTokens": { "type": "integer", "minimum": 0 },
"modelRatio": { "type": "number", "minimum": 0 },
"completionRatio": { "type": "number", "minimum": 0 },
"cacheRatio": { "type": "number", "minimum": 0 },
"quota": { "type": "number", "minimum": 0 },
"rmb": { "type": "number", "minimum": 0 }
},
"additionalProperties": false
}
}
}