From 4ed1359e045ae2be5f8677555173bcc98ae8d331 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 9 Jul 2026 11:47:43 +0100 Subject: [PATCH] Add Eve receipt schemas --- docs/eve-migration-roadmap.md | 7 ++ ...amecult.eve.command_receipt.v1.schema.json | 66 +++++++++++++++++ ...gamecult.eve.plugin_receipt.v1.schema.json | 72 +++++++++++++++++++ scripts/run-conformance-consumer-smoke.ps1 | 2 + scripts/run-eveconformance-handoff-smoke.ps1 | 4 ++ ...lugin-owner-conformance-consumer-smoke.ps1 | 2 + tools/conformance/eveconformance-handoff.json | 4 ++ tools/parity/parity-manifest.json | 2 + tools/parity/run-parity.mjs | 13 +++- 9 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 schemas/gamecult.eve.command_receipt.v1.schema.json create mode 100644 schemas/gamecult.eve.plugin_receipt.v1.schema.json diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 2579a53..0128ea0 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -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 diff --git a/schemas/gamecult.eve.command_receipt.v1.schema.json b/schemas/gamecult.eve.command_receipt.v1.schema.json new file mode 100644 index 0000000..161cd27 --- /dev/null +++ b/schemas/gamecult.eve.command_receipt.v1.schema.json @@ -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 +} diff --git a/schemas/gamecult.eve.plugin_receipt.v1.schema.json b/schemas/gamecult.eve.plugin_receipt.v1.schema.json new file mode 100644 index 0000000..7f412ca --- /dev/null +++ b/schemas/gamecult.eve.plugin_receipt.v1.schema.json @@ -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 +} diff --git a/scripts/run-conformance-consumer-smoke.ps1 b/scripts/run-conformance-consumer-smoke.ps1 index fffdd59..ecbecb8 100644 --- a/scripts/run-conformance-consumer-smoke.ps1 +++ b/scripts/run-conformance-consumer-smoke.ps1 @@ -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 ` diff --git a/scripts/run-eveconformance-handoff-smoke.ps1 b/scripts/run-eveconformance-handoff-smoke.ps1 index 1502f51..ade1a23 100644 --- a/scripts/run-eveconformance-handoff-smoke.ps1 +++ b/scripts/run-eveconformance-handoff-smoke.ps1 @@ -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", diff --git a/scripts/run-plugin-owner-conformance-consumer-smoke.ps1 b/scripts/run-plugin-owner-conformance-consumer-smoke.ps1 index a7fdbf8..9356b91 100644 --- a/scripts/run-plugin-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-plugin-owner-conformance-consumer-smoke.ps1 @@ -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 ` diff --git a/tools/conformance/eveconformance-handoff.json b/tools/conformance/eveconformance-handoff.json index 482864f..8029ee2 100644 --- a/tools/conformance/eveconformance-handoff.json +++ b/tools/conformance/eveconformance-handoff.json @@ -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", diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index 41e3a80..f30b525 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -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", diff --git a/tools/parity/run-parity.mjs b/tools/parity/run-parity.mjs index 0c56d53..05e2e0e 100644 --- a/tools/parity/run-parity.mjs +++ b/tools/parity/run-parity.mjs @@ -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) {