Add Eve receipt schemas

This commit is contained in:
Meta Vens 2026-07-09 11:47:43 +01:00
commit 4ed1359e04
9 changed files with 170 additions and 2 deletions

View file

@ -825,6 +825,13 @@ Recently cut:
TeX ABI fixtures must name those same schemas, and parity fails if a sidecar
advertises a request/response schema that is missing from the contract
catalog.
- Plugin sidecar receipt schema names are now backed by Eve contract
documents. `gamecult.eve.command_receipt.v1` is the generic command receipt
envelope for provider-owned acceptance/reconciliation, while
`gamecult.eve.plugin_receipt.v1` is the plugin-runtime diagnostic/proposed
state receipt envelope. Plugin ABI fixtures must match the sidecar-advertised
receipt schema, and parity fails if that schema is missing from the contract
catalog.
- Runtime release/capture request schema names are now backed by Eve contract
documents. `gamecult.eve.runtime_release_request.v1` and
`gamecult.eve.runtime_capture_request.v1` live under `schemas/`; runtime

View file

@ -0,0 +1,66 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "gamecult.eve.command_receipt.v1",
"title": "Eve Command Receipt",
"type": "object",
"required": [
"schema",
"receiptId",
"command",
"state",
"ownerRepo",
"authority"
],
"properties": {
"schema": {
"const": "gamecult.eve.command_receipt.v1"
},
"receiptId": {
"type": "string",
"minLength": 1
},
"commandId": {
"type": "string"
},
"command": {
"type": "string",
"minLength": 1
},
"state": {
"type": "string",
"enum": [
"accepted",
"denied",
"pending",
"reconciled"
]
},
"ownerRepo": {
"type": "string",
"minLength": 1
},
"authority": {
"type": "string",
"minLength": 1
},
"providerId": {
"type": "string"
},
"surfaceId": {
"type": "string"
},
"message": {
"type": "string"
},
"diagnostics": {
"type": "array",
"items": {
"type": "object"
}
},
"issuedAtUtc": {
"type": "string"
}
},
"additionalProperties": true
}

View file

@ -0,0 +1,72 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "gamecult.eve.plugin_receipt.v1",
"title": "Eve Plugin Receipt",
"type": "object",
"required": [
"schema",
"receiptId",
"pluginId",
"operation",
"state",
"ownerRepo",
"authority"
],
"properties": {
"schema": {
"const": "gamecult.eve.plugin_receipt.v1"
},
"receiptId": {
"type": "string",
"minLength": 1
},
"pluginId": {
"type": "string",
"minLength": 1
},
"operation": {
"type": "string",
"minLength": 1
},
"state": {
"type": "string",
"enum": [
"accepted",
"denied",
"pending",
"reconciled",
"diagnostic",
"cached",
"failed"
]
},
"ownerRepo": {
"type": "string",
"minLength": 1
},
"authority": {
"type": "string",
"minLength": 1
},
"requestId": {
"type": "string"
},
"stateEffects": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"diagnostics": {
"type": "array",
"items": {
"type": "object"
}
},
"issuedAtUtc": {
"type": "string"
}
},
"additionalProperties": true
}

View file

@ -33,6 +33,8 @@ try {
node .\tools\conformance\consume-export.mjs $consumerExport `
--expect-capability-matrix `
--expect-schema gamecult.eve.conformance_export.v1 `
--expect-schema gamecult.eve.command_receipt.v1 `
--expect-schema gamecult.eve.plugin_receipt.v1 `
--expect-schema gamecult.eve.plugin_abi.request.v1 `
--expect-schema gamecult.eve.plugin_abi.response.v1 `
--expect-schema gamecult.eve.runtime_release_request.v1 `

View file

@ -73,10 +73,12 @@ foreach ($id in @("conformance-runner", "conformance-schemas", "consumer-smokes"
foreach ($contract in @(
"gamecult.eve.surface.v1",
"gamecult.eve.command.v1",
"gamecult.eve.command_receipt.v1",
"gamecult.eve.conformance_export.v1",
"gamecult.eve.conformance_fixture.v1",
"gamecult.eve.provider_scenario.v1",
"gamecult.eve.plugin.v1",
"gamecult.eve.plugin_receipt.v1",
"gamecult.eve.plugin_advertisement.v1",
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",
@ -114,7 +116,9 @@ if (Test-Path -LiteralPath (Join-Path $absoluteExportDirectory "index.json")) {
"gamecult.eve.provider_scenario.v1",
"gamecult.eve.provider_advertisement.v1",
"gamecult.eve.runtime_capability.v1",
"gamecult.eve.command_receipt.v1",
"gamecult.eve.plugin.v1",
"gamecult.eve.plugin_receipt.v1",
"gamecult.eve.plugin_advertisement.v1",
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",

View file

@ -37,6 +37,8 @@ node $consumerScript $consumerExport `
--expect-schema gamecult.eve.plugin_abi_fixture.v1 `
--expect-schema gamecult.eve.plugin_abi.request.v1 `
--expect-schema gamecult.eve.plugin_abi.response.v1 `
--expect-schema gamecult.eve.command_receipt.v1 `
--expect-schema gamecult.eve.plugin_receipt.v1 `
--expect-fixture sai-vn `
--expect-plugin sai.vn `
--expect-plugin norn.graph `

View file

@ -24,7 +24,9 @@
"schemas/gamecult.eve.provider_scenario.v1.schema.json",
"schemas/gamecult.eve.provider_advertisement.v1.schema.json",
"schemas/gamecult.eve.runtime_capability.v1.schema.json",
"schemas/gamecult.eve.command_receipt.v1.schema.json",
"schemas/gamecult.eve.plugin.v1.schema.json",
"schemas/gamecult.eve.plugin_receipt.v1.schema.json",
"schemas/gamecult.eve.plugin_advertisement.v1.schema.json",
"schemas/gamecult.eve.plugin_abi_fixture.v1.schema.json",
"schemas/gamecult.eve.plugin_abi.request.v1.schema.json",
@ -63,10 +65,12 @@
"contractInputs": [
"gamecult.eve.surface.v1",
"gamecult.eve.command.v1",
"gamecult.eve.command_receipt.v1",
"gamecult.eve.conformance_export.v1",
"gamecult.eve.conformance_fixture.v1",
"gamecult.eve.provider_scenario.v1",
"gamecult.eve.plugin.v1",
"gamecult.eve.plugin_receipt.v1",
"gamecult.eve.plugin_advertisement.v1",
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",

View file

@ -10,7 +10,9 @@
"gamecult.eve.conformance_fixture.v1": "schemas/gamecult.eve.conformance_fixture.v1.schema.json",
"gamecult.eve.conformance_export.v1": "schemas/gamecult.eve.conformance_export.v1.schema.json",
"gamecult.eve.command.v1": "schemas/gamecult.eve.command.v1.schema.json",
"gamecult.eve.command_receipt.v1": "schemas/gamecult.eve.command_receipt.v1.schema.json",
"gamecult.eve.plugin.v1": "schemas/gamecult.eve.plugin.v1.schema.json",
"gamecult.eve.plugin_receipt.v1": "schemas/gamecult.eve.plugin_receipt.v1.schema.json",
"gamecult.eve.plugin_abi.request.v1": "schemas/gamecult.eve.plugin_abi.request.v1.schema.json",
"gamecult.eve.plugin_abi.response.v1": "schemas/gamecult.eve.plugin_abi.response.v1.schema.json",
"gamecult.eve.plugin_abi_fixture.v1": "schemas/gamecult.eve.plugin_abi_fixture.v1.schema.json",

View file

@ -604,7 +604,12 @@ function validatePluginRuntimeBoundary(plugin, runtimeBoundary) {
errors.push(...missingMembers(expectedRuntime.authority || [], runtimeBoundary.advertisementAuthority || [], "runtime.advertisementAuthority"));
errors.push(...comparePluginSidecar(expectedRuntime.sidecar || {}, runtimeBoundary.sidecar || {}, "runtime.sidecar"));
errors.push(...comparePluginSidecar(runtimeBoundary.sidecar || {}, runtimeBoundary.advertisementSidecar || {}, "runtime.advertisementSidecar"));
for (const schemaId of [runtimeBoundary.sidecar?.requestSchema, runtimeBoundary.sidecar?.responseSchema].filter(Boolean)) {
for (const schemaId of [
runtimeBoundary.sidecar?.requestSchema,
runtimeBoundary.sidecar?.responseSchema,
runtimeBoundary.sidecar?.commandEnvelope,
runtimeBoundary.sidecar?.receiptSchema,
].filter(Boolean)) {
if (!manifest.schemas?.[schemaId]) {
errors.push(`runtime.sidecar.schemaCatalog:${schemaId}:missing`);
}
@ -937,7 +942,8 @@ async function validatePluginAbiFixture(plugin) {
if (abiFixture.responseSchema !== pluginManifest.runtime?.sidecar?.responseSchema) {
errors.push(`${plugin.abiFixturePath}:responseSchema:expected ${pluginManifest.runtime?.sidecar?.responseSchema || ""} got ${abiFixture.responseSchema || ""}`);
}
for (const schemaId of [abiFixture.requestSchema, abiFixture.responseSchema].filter(Boolean)) {
const sidecarReceiptSchema = pluginManifest.runtime?.sidecar?.receiptSchema || "";
for (const schemaId of [abiFixture.requestSchema, abiFixture.responseSchema, sidecarReceiptSchema].filter(Boolean)) {
if (!manifest.schemas?.[schemaId]) {
errors.push(`${plugin.abiFixturePath}:schemaCatalog:${schemaId}:missing`);
}
@ -985,6 +991,9 @@ async function validatePluginAbiFixture(plugin) {
if (measure.preservesProviderAuthority !== true) errors.push(`${plugin.abiFixturePath}:measure.preservesProviderAuthority:expected true`);
const apply = operations.get("apply")?.expect || {};
if (apply.receiptSchema !== sidecarReceiptSchema) {
errors.push(`${plugin.abiFixturePath}:apply.receiptSchema:expected ${sidecarReceiptSchema} got ${apply.receiptSchema || ""}`);
}
if (manifestCommands.length) {
const commandEffects = apply.commandEffects || {};
for (const command of manifestCommands) {