Captured-bytes case in cultnet-rs error_message.rs, asserted byte-for-byte by the C# schema contract test; the cultnet-distributed-database contract and the Networking README state the remote write authority invariant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
2.9 KiB
JSON
46 lines
2.9 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://github.com/GameCult/CultLib/contracts/cultnet/cultnet.error.schema.json",
|
|
"title": "CultNet Error Message",
|
|
"description": "R-X (docs/cultnet-selection-cut.md, fix batch 4): CultNetErrorMessage is a MessagePack-CSharp map-mode object, so every declared key is written on the wire, nil included - routingHint, code and details are `required` here the same as cultnet.raw-document-header.schema.json's nullable fields, not optional just because a given refusal leaves them null.",
|
|
"type": "object",
|
|
"required": [
|
|
"schemaVersion",
|
|
"error",
|
|
"routingHint",
|
|
"code",
|
|
"details"
|
|
],
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"schemaVersion": { "const": "cultnet.error.v0" },
|
|
"error": { "type": "string", "minLength": 1 },
|
|
"routingHint": {
|
|
"description": "Optional shard routing detail for an authority failure. Null for every selection/cursor refusal code (R-N).",
|
|
"type": ["object", "null"],
|
|
"additionalProperties": false,
|
|
"required": ["shard", "reason"],
|
|
"properties": {
|
|
"shard": { "type": ["object", "null"] },
|
|
"reason": { "type": "string" }
|
|
}
|
|
},
|
|
"code": {
|
|
"description": "Machine-readable refusal code (R-N). Additive: a v0 peer that does not know this field ignores it. The set is a closed enum: Rust and TypeScript refuse a message whose code is not listed, so adding a code is one coordinated change across every runtime (this schema, the C# factory, the Rust CultNetErrorCode, and a captured-bytes case for each).",
|
|
"type": ["string", "null"],
|
|
"enum": [null, "selection_invalid", "cursor_stale", "cursor_invalid", "reference_outside_target", "variant_unsupported", "unowned_schema", "write_not_authorized"]
|
|
},
|
|
"details": {
|
|
"description": "Code-specific structured detail (R-N). Every field is populated only for the code that defines it; the others are null, not omitted.",
|
|
"type": ["object", "null"],
|
|
"additionalProperties": false,
|
|
"required": ["field", "value", "asOf", "current"],
|
|
"properties": {
|
|
"field": { "description": "selection_invalid: the selection field that failed. variant_unsupported: \"subscriptionId\", when a subscription was ended. unowned_schema: \"schemaId\". write_not_authorized: \"recordKey\".", "type": ["string", "null"] },
|
|
"value": { "description": "selection_invalid: the offending value, when there is one string worth naming. variant_unsupported: the id of the subscription that ended. unowned_schema: the schema id no shard owns. write_not_authorized: the key of the refused write.", "type": ["string", "null"] },
|
|
"asOf": { "description": "cursor_stale: the cursor's own minted asOf.", "type": ["integer", "null"], "minimum": 0 },
|
|
"current": { "description": "cursor_stale: the answering server's current asOf.", "type": ["integer", "null"], "minimum": 0 }
|
|
}
|
|
}
|
|
}
|
|
}
|