固化 Match-3 生产者、视觉、音频与双 Judge 证据闭包。 将《山海行纪》r1.1 绑定新的不可变 release,并以生产预检现场核验 bundle、Registry/2 和 25 项 Writer 快照。 同步地图1平衡锁值、跨游戏回归修复、验收契约与 SoT 证据。
799 lines
27 KiB
JSON
799 lines
27 KiB
JSON
{
|
||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
"$id": "https://wanxiang.ai/contracts/play-loop/playtest-evidence.schema.json",
|
||
"title": "PlaytestEvidence",
|
||
"description": "便宜档生成验收 v3 的 playtest/2 权威证据契约。phase 与 outcome 正交;decision.accepted 永远等价 outcome=accept,而发布仅允许 active v3 accept。v3_shadow 即使终裁接受也必须 publishFrozen=true 且 compatibility.accepted/ok=false。Actor 只有动作权限,Judge 只读封存后的 JudgePackage,rollGuard 只产 rollOutcome,merge 只产 mergeCandidate,只有 finalPostguard 能写 decision 与唯一 compatibility 投影。",
|
||
"type": "object",
|
||
"required": [
|
||
"schemaVersion", "runId", "parentRunId", "gameId", "genre", "templateRoute", "proofProfileId",
|
||
"proofRegistryVersion", "taskBindingHash", "acceptanceRequestHash", "artifactHash", "briefHash",
|
||
"acceptanceMode", "evidenceMode", "phase", "environment", "floor", "actor", "actions", "events",
|
||
"briefRuleMatches", "proofObligations", "firstPlay", "rolls",
|
||
"merge", "judge", "repair", "costRmb"
|
||
],
|
||
"properties": {
|
||
"schemaVersion": {
|
||
"type": "string",
|
||
"const": "playtest/2"
|
||
},
|
||
"runId": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"parentRunId": {
|
||
"type": ["string", "null"]
|
||
},
|
||
"gameId": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"genre": {
|
||
"type": "string",
|
||
"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": "#/$defs/sha256"
|
||
},
|
||
"acceptanceRequestHash": {
|
||
"$ref": "#/$defs/sha256"
|
||
},
|
||
"artifactHash": {
|
||
"$ref": "#/$defs/sha256"
|
||
},
|
||
"briefHash": {
|
||
"$ref": "#/$defs/sha256"
|
||
},
|
||
"acceptanceMode": {
|
||
"type": "string",
|
||
"enum": ["v3_shadow", "v3", "historical_replay"]
|
||
},
|
||
"evidenceMode": {
|
||
"type": "string",
|
||
"enum": ["native", "legacy-adapted"]
|
||
},
|
||
"phase": {
|
||
"type": "string",
|
||
"enum": ["PRECHECK", "COLLECTING", "JUDGING", "DECIDED"]
|
||
},
|
||
"outcome": {
|
||
"$ref": "#/$defs/outcome"
|
||
},
|
||
"environment": {
|
||
"$ref": "#/$defs/environment"
|
||
},
|
||
"floor": {
|
||
"$ref": "#/$defs/floor"
|
||
},
|
||
"actor": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/actor" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"actions": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/actionRecord" }
|
||
},
|
||
"events": {
|
||
"type": "array",
|
||
"items": { "$ref": "game-event.schema.json" }
|
||
},
|
||
"briefRuleMatches": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"proofObligations": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/proofObligation" }
|
||
},
|
||
"firstPlay": {
|
||
"$ref": "#/$defs/firstPlay"
|
||
},
|
||
"rolls": {
|
||
"type": "array",
|
||
"maxItems": 2,
|
||
"items": { "$ref": "#/$defs/roll" }
|
||
},
|
||
"merge": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/merge" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"judge": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/judge" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"repair": {
|
||
"$ref": "#/$defs/repair"
|
||
},
|
||
"costRmb": {
|
||
"type": "number",
|
||
"minimum": 0
|
||
},
|
||
"finalPostguard": {
|
||
"$ref": "#/$defs/finalPostguard"
|
||
},
|
||
"decision": {
|
||
"$ref": "#/$defs/decision"
|
||
},
|
||
"compatibility": {
|
||
"$ref": "#/$defs/compatibility"
|
||
}
|
||
},
|
||
"patternProperties": {
|
||
"^_": {}
|
||
},
|
||
"additionalProperties": false,
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "phase": { "const": "DECIDED" } },
|
||
"required": ["phase"]
|
||
},
|
||
"then": {
|
||
"required": ["outcome", "finalPostguard", "decision", "compatibility"]
|
||
},
|
||
"else": {
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["outcome"] },
|
||
{ "required": ["finalPostguard"] },
|
||
{ "required": ["decision"] },
|
||
{ "required": ["compatibility"] }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"$defs": {
|
||
"sha256": {
|
||
"type": "string",
|
||
"pattern": "^[0-9a-f]{64}$"
|
||
},
|
||
"outcome": {
|
||
"type": "string",
|
||
"enum": ["accept", "reject", "inconclusive", "tester_error"]
|
||
},
|
||
"environment": {
|
||
"type": "object",
|
||
"required": ["host", "chromeVersion", "viewport", "buildRef", "virtualTime"],
|
||
"properties": {
|
||
"host": { "type": "string", "minLength": 1 },
|
||
"chromeVersion": { "type": "string", "minLength": 1 },
|
||
"viewport": {
|
||
"type": "object",
|
||
"required": ["width", "height", "dpr"],
|
||
"properties": {
|
||
"width": { "const": 390 },
|
||
"height": { "const": 844 },
|
||
"dpr": { "const": 1 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"buildRef": { "$ref": "#/$defs/sha256" },
|
||
"virtualTime": {
|
||
"type": "object",
|
||
"required": ["mode", "actionQuantumMs", "waitMinMs", "waitMaxMs"],
|
||
"properties": {
|
||
"mode": { "const": "cdp" },
|
||
"actionQuantumMs": { "const": 600 },
|
||
"waitMinMs": { "const": 100 },
|
||
"waitMaxMs": { "const": 3000 },
|
||
"rafFrameMs": { "type": "number", "minimum": 1 },
|
||
"bootBoundary": { "type": "object" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"timings": {
|
||
"type": "object",
|
||
"required": [
|
||
"chromeProcessReadyWallMs", "cdpConnectedWallMs", "browserContextCreatedWallMs",
|
||
"navigationSubmittedWallMs", "runtimeBootedWallMs", "gameInteractiveWallMs"
|
||
],
|
||
"properties": {
|
||
"chromeProcessReadyWallMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"cdpConnectedWallMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"browserContextCreatedWallMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"navigationSubmittedWallMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"runtimeBootedWallMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"gameInteractiveWallMs": { "type": ["integer", "null"], "minimum": 0 }
|
||
},
|
||
"additionalProperties": false
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"floor": {
|
||
"type": "object",
|
||
"required": ["pass", "gates"],
|
||
"properties": {
|
||
"pass": { "type": "boolean" },
|
||
"gates": {
|
||
"type": "object",
|
||
"required": ["A_boot", "B_uncaught", "C_frame", "D_render"],
|
||
"properties": {
|
||
"A_boot": { "$ref": "#/$defs/gateResult" },
|
||
"B_uncaught": { "$ref": "#/$defs/gateResult" },
|
||
"C_frame": { "$ref": "#/$defs/gateResult" },
|
||
"D_render": { "$ref": "#/$defs/gateResult" }
|
||
},
|
||
"additionalProperties": false
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"gateResult": {
|
||
"type": "object",
|
||
"required": ["pass", "evidenceRef"],
|
||
"properties": {
|
||
"pass": { "type": "boolean" },
|
||
"evidenceRef": { "type": "string", "minLength": 1 },
|
||
"measurement": {}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"actor": {
|
||
"type": "object",
|
||
"required": [
|
||
"model", "apiClientId", "sessionId", "systemPromptVersion", "contextProjectionVersion",
|
||
"evidenceDir", "requestedGameSeed", "actualGameSeed", "policySeed"
|
||
],
|
||
"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 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"actionRecord": {
|
||
"type": "object",
|
||
"required": [
|
||
"actionId", "request", "normalized", "valid", "retryCount", "preFrameRef", "preEventSeq",
|
||
"dispatchReceipt", "virtualTimeBudgetMs", "timeAdvance", "postFrameRef", "postEventSeq", "protocolErrors"
|
||
],
|
||
"properties": {
|
||
"actionId": { "type": "string", "pattern": "^action-[1-9][0-9]*$" },
|
||
"request": {
|
||
"type": "object",
|
||
"required": ["raw", "parsed"],
|
||
"properties": {
|
||
"raw": { "type": "string" },
|
||
"parsed": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/action" },
|
||
{ "type": "null" }
|
||
]
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"normalized": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/action" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"valid": { "type": "boolean" },
|
||
"retryCount": { "type": "integer", "minimum": 0, "maximum": 2 },
|
||
"preFrameRef": { "$ref": "#/$defs/frameRef" },
|
||
"preEventSeq": { "type": "integer", "minimum": 0 },
|
||
"dispatchReceipt": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/dispatchReceipt" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"virtualTimeBudgetMs": { "type": "integer", "minimum": 0, "maximum": 3000 },
|
||
"timeAdvance": {
|
||
"anyOf": [
|
||
{ "$ref": "#/$defs/timeAdvance" },
|
||
{ "type": "null" }
|
||
]
|
||
},
|
||
"postFrameRef": { "$ref": "#/$defs/frameRef" },
|
||
"postEventSeq": { "type": "integer", "minimum": 0 },
|
||
"protocolErrors": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"additionalProperties": false,
|
||
"allOf": [
|
||
{
|
||
"if": { "properties": { "valid": { "const": true } }, "required": ["valid"] },
|
||
"then": { "properties": { "timeAdvance": { "$ref": "#/$defs/timeAdvance" } } },
|
||
"else": { "properties": { "timeAdvance": { "type": "null" } } }
|
||
}
|
||
]
|
||
},
|
||
"action": {
|
||
"type": "object",
|
||
"required": ["type"],
|
||
"properties": {
|
||
"type": { "type": "string", "enum": ["tap", "key", "wait", "drag"] },
|
||
"x": { "type": "number", "minimum": 0 },
|
||
"y": { "type": "number", "minimum": 0 },
|
||
"key": { "type": "string", "minLength": 1 },
|
||
"ms": { "type": "integer", "minimum": 100, "maximum": 3000 },
|
||
"from": { "$ref": "#/$defs/point" },
|
||
"to": { "$ref": "#/$defs/point" }
|
||
},
|
||
"additionalProperties": false,
|
||
"allOf": [
|
||
{
|
||
"if": { "properties": { "type": { "const": "tap" } }, "required": ["type"] },
|
||
"then": { "required": ["x", "y"] }
|
||
},
|
||
{
|
||
"if": { "properties": { "type": { "const": "key" } }, "required": ["type"] },
|
||
"then": { "required": ["key"] }
|
||
},
|
||
{
|
||
"if": { "properties": { "type": { "const": "wait" } }, "required": ["type"] },
|
||
"then": { "required": ["ms"] }
|
||
},
|
||
{
|
||
"if": { "properties": { "type": { "const": "drag" } }, "required": ["type"] },
|
||
"then": { "required": ["from", "to", "ms"] }
|
||
}
|
||
]
|
||
},
|
||
"point": {
|
||
"type": "object",
|
||
"required": ["x", "y"],
|
||
"properties": {
|
||
"x": { "type": "number", "minimum": 0 },
|
||
"y": { "type": "number", "minimum": 0 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"frameRef": {
|
||
"type": "object",
|
||
"required": ["path", "hash"],
|
||
"properties": {
|
||
"path": { "type": "string", "minLength": 1 },
|
||
"hash": { "$ref": "#/$defs/sha256" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"dispatchReceipt": {
|
||
"type": "object",
|
||
"required": ["accepted", "wallTimeMs"],
|
||
"properties": {
|
||
"accepted": { "const": true },
|
||
"wallTimeMs": { "type": "integer", "minimum": 0 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"timeAdvance": {
|
||
"type": "object",
|
||
"required": [
|
||
"requestedBudgetMs", "plannedFrames", "executedFrames", "callbacksRun", "carryMs", "ok"
|
||
],
|
||
"properties": {
|
||
"requestedBudgetMs": { "type": "integer", "minimum": 100, "maximum": 3000 },
|
||
"plannedFrames": { "type": "integer", "minimum": 0 },
|
||
"executedFrames": { "type": "integer", "minimum": 0 },
|
||
"callbacksRun": { "type": "integer", "minimum": 0 },
|
||
"carryMs": { "type": "number", "minimum": 0 },
|
||
"ok": { "const": true }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"proofObligation": {
|
||
"type": "object",
|
||
"required": [
|
||
"id", "required", "status", "sequenceRefs", "actionRefs", "postFrameRefs", "eventRefs",
|
||
"contradictions", "blockingProblems"
|
||
],
|
||
"properties": {
|
||
"id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" },
|
||
"required": { "type": "boolean" },
|
||
"status": {
|
||
"type": "string",
|
||
"enum": ["satisfied", "failed", "missing", "contradicted", "not-required"]
|
||
},
|
||
"sequenceRefs": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/sequenceRef" }
|
||
},
|
||
"actionRefs": {
|
||
"type": "array",
|
||
"items": { "type": "string", "pattern": "^action-[1-9][0-9]*$" }
|
||
},
|
||
"postFrameRefs": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"eventRefs": {
|
||
"type": "array",
|
||
"items": { "type": "integer", "minimum": 1 }
|
||
},
|
||
"contradictions": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"blockingProblems": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"additionalProperties": false,
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "status": { "const": "satisfied" } },
|
||
"required": ["status"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"sequenceRefs": { "minItems": 1 },
|
||
"actionRefs": { "minItems": 1 },
|
||
"postFrameRefs": { "minItems": 1 },
|
||
"eventRefs": { "minItems": 1 },
|
||
"contradictions": { "maxItems": 0 },
|
||
"blockingProblems": { "maxItems": 0 }
|
||
}
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"sequenceRef": {
|
||
"type": "object",
|
||
"required": ["stepId", "eventRef", "actionRef", "postFrameRef"],
|
||
"properties": {
|
||
"stepId": { "type": "string", "pattern": "^[a-z][a-z0-9-]*(?::[1-9][0-9]*)?$" },
|
||
"eventRef": { "type": "integer", "minimum": 1 },
|
||
"actionRef": { "type": "string", "pattern": "^action-[1-9][0-9]*$" },
|
||
"postFrameRef": { "type": "string", "minLength": 1 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"firstPlay": {
|
||
"type": "object",
|
||
"required": [
|
||
"interactiveAtVirtualMs", "firstFeedbackAtVirtualMs", "loopClosedAtVirtualMs",
|
||
"loopClosed", "proofObligationRefs"
|
||
],
|
||
"properties": {
|
||
"interactiveAtVirtualMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"firstFeedbackAtVirtualMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"loopClosedAtVirtualMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"loopClosed": { "type": "boolean" },
|
||
"proofObligationRefs": {
|
||
"type": "array",
|
||
"items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" }
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"roll": {
|
||
"type": "object",
|
||
"required": [
|
||
"rollId", "roll", "requestedGameSeed", "actualGameSeed", "policySeed", "actorSessionId",
|
||
"proofPackageRef", "judgePackageRef", "rollGuard", "rollOutcome", "errors", "costRmb"
|
||
],
|
||
"properties": {
|
||
"rollId": { "type": "string", "pattern": "^roll-[12]$" },
|
||
"roll": { "type": "integer", "minimum": 1, "maximum": 2 },
|
||
"requestedGameSeed": { "type": "integer", "minimum": 0 },
|
||
"actualGameSeed": { "type": "integer", "minimum": 0 },
|
||
"policySeed": { "type": "integer", "minimum": 0 },
|
||
"actorSessionId": { "type": "string", "minLength": 1 },
|
||
"proofPackageRef": { "type": "string", "minLength": 1 },
|
||
"judgePackageRef": { "type": ["string", "null"] },
|
||
"rollGuard": { "$ref": "#/$defs/guard" },
|
||
"rollOutcome": { "$ref": "#/$defs/outcome" },
|
||
"errors": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"costRmb": { "type": "number", "minimum": 0 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"guard": {
|
||
"type": "object",
|
||
"required": ["pass", "checks", "blockingProblems", "contradictions", "reason"],
|
||
"properties": {
|
||
"pass": { "type": "boolean" },
|
||
"checks": {
|
||
"$ref": "#/$defs/guardChecks"
|
||
},
|
||
"blockingProblems": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"contradictions": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"reason": { "type": "string" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"guardChecks": {
|
||
"type": "object",
|
||
"required": [
|
||
"floorPass", "requiredObligationsSatisfied", "referencesValid", "sameActionEvidence",
|
||
"noContradictions", "noBlockingProblems", "actorHealthy", "runnerHealthy", "judgeHealthy",
|
||
"judgeAccept"
|
||
],
|
||
"properties": {
|
||
"floorPass": { "type": "boolean" },
|
||
"requiredObligationsSatisfied": { "type": "boolean" },
|
||
"referencesValid": { "type": "boolean" },
|
||
"sameActionEvidence": { "type": "boolean" },
|
||
"noContradictions": { "type": "boolean" },
|
||
"noBlockingProblems": { "type": "boolean" },
|
||
"actorHealthy": { "type": "boolean" },
|
||
"runnerHealthy": { "type": "boolean" },
|
||
"judgeHealthy": { "type": "boolean" },
|
||
"judgeAccept": { "type": "boolean" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"merge": {
|
||
"type": "object",
|
||
"required": ["triggered", "rollRefs", "mergeCandidate", "conflicts", "rescuedByRoll", "reason"],
|
||
"properties": {
|
||
"triggered": { "type": "boolean" },
|
||
"rollRefs": {
|
||
"type": "array",
|
||
"maxItems": 2,
|
||
"items": { "type": "string", "pattern": "^roll-[12]$" }
|
||
},
|
||
"mergeCandidate": { "$ref": "#/$defs/outcome" },
|
||
"conflicts": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"rescuedByRoll": { "type": ["integer", "null"], "minimum": 1, "maximum": 2 },
|
||
"reason": { "type": "string", "minLength": 1 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"judge": {
|
||
"type": "object",
|
||
"required": [
|
||
"model", "apiClientId", "sessionId", "systemPromptVersion", "contextProjectionVersion",
|
||
"evidenceDir", "packageHash", "decision", "degraded", "obligationResults",
|
||
"contradictions", "blockingProblems"
|
||
],
|
||
"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": "#/$defs/sha256" },
|
||
"decision": { "$ref": "#/$defs/outcome" },
|
||
"degraded": { "type": "boolean" },
|
||
"obligationResults": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "object",
|
||
"required": ["id", "status", "sequenceRefs", "evidenceRefs"],
|
||
"properties": {
|
||
"id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" },
|
||
"status": { "type": "string", "enum": ["satisfied", "failed", "missing", "contradicted"] },
|
||
"sequenceRefs": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/sequenceRef" }
|
||
},
|
||
"evidenceRefs": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
}
|
||
},
|
||
"contradictions": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"blockingProblems": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"finalPostguard": {
|
||
"type": "object",
|
||
"required": [
|
||
"pass", "mergeCandidate", "checks", "blockingProblems", "contradictions",
|
||
"writeAuthority", "reason"
|
||
],
|
||
"properties": {
|
||
"pass": { "type": "boolean" },
|
||
"mergeCandidate": { "$ref": "#/$defs/outcome" },
|
||
"checks": { "$ref": "#/$defs/guardChecks" },
|
||
"blockingProblems": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"contradictions": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
},
|
||
"writeAuthority": { "const": true },
|
||
"reason": { "type": "string" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"repair": {
|
||
"type": "object",
|
||
"required": ["countAcrossParentChain", "eligible", "attempted", "reason"],
|
||
"properties": {
|
||
"countAcrossParentChain": { "type": "integer", "minimum": 0, "maximum": 1 },
|
||
"eligible": { "type": "boolean" },
|
||
"attempted": { "type": "boolean" },
|
||
"reason": { "type": "string" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"decision": {
|
||
"type": "object",
|
||
"required": [
|
||
"outcome", "accepted", "shadowAccepted", "publishFrozen", "failure",
|
||
"repairCountAcrossParentChain", "repairEligible", "repairFeedback",
|
||
"rescuedByRoll", "costRmb", "parentChainCostRmb"
|
||
],
|
||
"properties": {
|
||
"outcome": { "$ref": "#/$defs/outcome" },
|
||
"accepted": { "type": "boolean" },
|
||
"shadowAccepted": { "type": ["boolean", "null"] },
|
||
"publishFrozen": { "type": "boolean" },
|
||
"failure": { "$ref": "#/$defs/decisionFailure" },
|
||
"repairCountAcrossParentChain": { "type": "integer", "minimum": 0, "maximum": 1 },
|
||
"repairEligible": { "type": "boolean" },
|
||
"repairFeedback": { "type": ["string", "null"] },
|
||
"rescuedByRoll": { "type": ["integer", "null"], "minimum": 1, "maximum": 2 },
|
||
"costRmb": { "type": "number", "minimum": 0 },
|
||
"parentChainCostRmb": { "type": "number", "minimum": 0 }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"decisionFailure": {
|
||
"type": "object",
|
||
"required": ["layer", "subtype", "reason"],
|
||
"properties": {
|
||
"layer": {
|
||
"type": "string",
|
||
"enum": ["none", "mechanical", "gameplay", "tester_degraded"]
|
||
},
|
||
"subtype": { "type": ["string", "null"] },
|
||
"reason": { "type": ["string", "null"] }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibility": {
|
||
"type": "object",
|
||
"required": [
|
||
"accepted", "ok", "acceptanceVersion", "publishFrozen", "playtest", "judge",
|
||
"failureLayer", "failureReason", "trace"
|
||
],
|
||
"properties": {
|
||
"accepted": { "type": "boolean" },
|
||
"ok": { "type": "boolean" },
|
||
"acceptanceVersion": { "type": "string", "enum": ["v3_shadow", "v3", "historical_replay"] },
|
||
"publishFrozen": { "type": "boolean" },
|
||
"playtest": { "$ref": "#/$defs/compatibilityPlaytest" },
|
||
"judge": { "$ref": "#/$defs/compatibilityJudge" },
|
||
"failureLayer": { "$ref": "#/$defs/failureProjection" },
|
||
"failureReason": { "type": ["string", "null"] },
|
||
"trace": { "$ref": "#/$defs/compatibilityTrace" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibilityPlaytest": {
|
||
"type": "object",
|
||
"required": [
|
||
"schemaVersion", "outcome", "accepted", "rollCount", "rescuedByRoll", "costRmb",
|
||
"proofComplete", "firstPlay", "evidenceRefs"
|
||
],
|
||
"properties": {
|
||
"schemaVersion": { "const": "playtest/2" },
|
||
"outcome": { "$ref": "#/$defs/outcome" },
|
||
"accepted": { "type": "boolean" },
|
||
"rollCount": { "type": "integer", "minimum": 0, "maximum": 2 },
|
||
"rescuedByRoll": { "type": ["integer", "null"], "minimum": 1, "maximum": 2 },
|
||
"costRmb": { "type": "number", "minimum": 0 },
|
||
"proofComplete": { "type": "boolean" },
|
||
"firstPlay": { "$ref": "#/$defs/compatibilityFirstPlay" },
|
||
"evidenceRefs": { "$ref": "#/$defs/compatibilityEvidenceRefs" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibilityFirstPlay": {
|
||
"type": "object",
|
||
"required": ["playableAtMs", "firstFeedbackMs", "loopClosed", "proofRefs"],
|
||
"properties": {
|
||
"playableAtMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"firstFeedbackMs": { "type": ["integer", "null"], "minimum": 0 },
|
||
"loopClosed": { "type": "boolean" },
|
||
"proofRefs": {
|
||
"type": "array",
|
||
"items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$" }
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibilityEvidenceRefs": {
|
||
"type": "object",
|
||
"required": ["actions", "frames", "events"],
|
||
"properties": {
|
||
"actions": { "type": "array", "items": { "type": "string", "pattern": "^action-[1-9][0-9]*$" } },
|
||
"frames": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
||
"events": { "type": "array", "items": { "type": "string", "pattern": "^[1-9][0-9]*$" } }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibilityJudge": {
|
||
"type": "object",
|
||
"required": [
|
||
"ran", "verdict", "accepted", "degraded", "reason", "acceptanceVersion", "schemaVersion"
|
||
],
|
||
"properties": {
|
||
"ran": { "type": "boolean" },
|
||
"verdict": { "$ref": "#/$defs/outcome" },
|
||
"accepted": { "type": "boolean" },
|
||
"degraded": { "type": "boolean" },
|
||
"reason": { "type": ["string", "null"] },
|
||
"acceptanceVersion": { "type": "string", "enum": ["v3_shadow", "v3", "historical_replay"] },
|
||
"schemaVersion": { "const": "playtest/2" }
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"failureProjection": {
|
||
"type": "object",
|
||
"required": ["layer", "reason", "failedGates"],
|
||
"properties": {
|
||
"layer": {
|
||
"type": "string",
|
||
"enum": ["none", "mechanical", "gameplay", "tester_degraded"]
|
||
},
|
||
"reason": { "type": ["string", "null"] },
|
||
"failedGates": {
|
||
"type": "array",
|
||
"items": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"additionalProperties": false
|
||
},
|
||
"compatibilityTrace": {
|
||
"type": "object",
|
||
"required": ["playtest", "gameplayJudge"],
|
||
"properties": {
|
||
"playtest": { "$ref": "#/$defs/compatibilityPlaytest" },
|
||
"gameplayJudge": { "$ref": "#/$defs/compatibilityJudge" }
|
||
},
|
||
"additionalProperties": false
|
||
}
|
||
}
|
||
}
|