Add runtime request schemas

This commit is contained in:
Meta Vens 2026-07-09 11:44:48 +01:00
commit 14a2ea764b
10 changed files with 211 additions and 2 deletions

View file

@ -825,6 +825,11 @@ 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.
- 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
lifecycle manifests must name catalog-backed request schemas, so release and
capture status cannot hide a missing wire contract.
- Conformance export now carries a root `schemaCatalog` and copies schema
documents under `schemas/` in the export. Plugin owners can assert
`gamecult.eve.plugin_abi.request.v1` and

View file

@ -209,6 +209,9 @@
"versionSource",
"tagPattern",
"artifactKind",
"requestSchema",
"requestBuilder",
"artifactPattern",
"publishProof"
],
"properties": {
@ -394,6 +397,10 @@
"required": [
"ownerRepo",
"runtimeId",
"targetId",
"requestSchema",
"requestBuilder",
"advertisementPath",
"captureKind",
"artifactKind",
"artifactPattern",

View file

@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "gamecult.eve.runtime_capture_request.v1",
"title": "Eve Runtime Capture Request",
"type": "object",
"required": [
"schema",
"runtimeId",
"ownerRepo",
"providerId",
"surfaceId",
"targetId",
"captureKind",
"artifactKind",
"artifactPath",
"conformanceAttachment",
"authority",
"issuedAtUtc"
],
"properties": {
"schema": {
"const": "gamecult.eve.runtime_capture_request.v1"
},
"runtimeId": {
"type": "string",
"minLength": 1
},
"ownerRepo": {
"type": "string",
"minLength": 1
},
"providerId": {
"type": "string",
"minLength": 1
},
"surfaceId": {
"type": "string",
"minLength": 1
},
"surfaceKind": {
"type": "string"
},
"targetId": {
"type": "string",
"minLength": 1
},
"projectionKind": {
"type": "string"
},
"commandBoundary": {
"type": "string"
},
"receiptSchema": {
"type": "string"
},
"captureKind": {
"type": "string",
"minLength": 1
},
"artifactKind": {
"type": "string",
"minLength": 1
},
"artifactPath": {
"type": "string",
"minLength": 1
},
"conformanceAttachment": {
"type": "string",
"minLength": 1
},
"authority": {
"type": "string",
"minLength": 1
},
"sourceAdvertisementPath": {
"type": "string"
},
"sourceCapabilityManifestPath": {
"type": "string"
},
"issuedAtUtc": {
"type": "string",
"minLength": 1
}
},
"additionalProperties": true
}

View file

@ -0,0 +1,89 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "gamecult.eve.runtime_release_request.v1",
"title": "Eve Runtime Release Request",
"type": "object",
"required": [
"schema",
"ownerRepo",
"repository",
"packageName",
"version",
"packageRoot",
"versionSource",
"tagName",
"artifactKind",
"artifactPath",
"publishProof"
],
"properties": {
"schema": {
"const": "gamecult.eve.runtime_release_request.v1"
},
"ownerRepo": {
"type": "string",
"minLength": 1
},
"repository": {
"type": "string",
"minLength": 1
},
"packageName": {
"type": "string",
"minLength": 1
},
"displayName": {
"type": "string"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$"
},
"unity": {
"type": "string"
},
"packageRoot": {
"type": "string",
"minLength": 1
},
"versionSource": {
"type": "string",
"minLength": 1
},
"tagName": {
"type": "string",
"minLength": 1
},
"artifactKind": {
"type": "string",
"minLength": 1
},
"artifactPath": {
"type": "string",
"minLength": 1
},
"publishProof": {
"type": "string",
"minLength": 1
},
"sourceCapabilityManifestPath": {
"type": "string"
},
"sourcePackageManifestPath": {
"type": "string"
},
"main": {
"type": "string"
},
"scripts": {
"type": "object"
},
"dependencies": {
"type": "object"
},
"devDependencies": {
"type": "object"
}
},
"additionalProperties": true
}

View file

@ -35,6 +35,8 @@ try {
--expect-schema gamecult.eve.conformance_export.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 `
--expect-schema gamecult.eve.runtime_capture_request.v1 `
--expect-capability-gap runtime:Fensalir:direct2d:capture:missing `
--expect-world-lowering-coverage aetheria:aetheria.daemon.game:web-reference:claimed:Eve:web `
--expect-world-lowering-coverage aetheria:aetheria.daemon.game:unity-uitoolkit:claimed:EveUnity:unity-uitoolkit `

View file

@ -81,6 +81,8 @@ foreach ($contract in @(
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",
"gamecult.eve.plugin_abi.response.v1",
"gamecult.eve.runtime_release_request.v1",
"gamecult.eve.runtime_capture_request.v1",
"gamecult.eve.provider_advertisement.v1",
"gamecult.eve.runtime_capability.v1"
)) {
@ -116,7 +118,9 @@ if (Test-Path -LiteralPath (Join-Path $absoluteExportDirectory "index.json")) {
"gamecult.eve.plugin_advertisement.v1",
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",
"gamecult.eve.plugin_abi.response.v1"
"gamecult.eve.plugin_abi.response.v1",
"gamecult.eve.runtime_release_request.v1",
"gamecult.eve.runtime_capture_request.v1"
)) {
$schema = @($export.schemaCatalog) | Where-Object { $_.schemaId -eq $schemaId } | Select-Object -First 1
if (-not $schema) {

View file

@ -41,6 +41,8 @@ node $consumerScript $consumerExport `
--expect-runtime electron-shell `
--expect-runtime tui `
--expect-runtime direct2d `
--expect-schema gamecult.eve.runtime_release_request.v1 `
--expect-schema gamecult.eve.runtime_capture_request.v1 `
--expect-runtime-status web:active `
--expect-runtime-status windows-flutter:active `
--expect-runtime-status linux-flutter:active `

View file

@ -28,7 +28,9 @@
"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",
"schemas/gamecult.eve.plugin_abi.response.v1.schema.json"
"schemas/gamecult.eve.plugin_abi.response.v1.schema.json",
"schemas/gamecult.eve.runtime_release_request.v1.schema.json",
"schemas/gamecult.eve.runtime_capture_request.v1.schema.json"
],
"replacementProof": "EveConformance publishes the schema catalog and copied schema documents needed by conformance, plugin, provider, and runtime consumers."
},
@ -69,6 +71,8 @@
"gamecult.eve.plugin_abi_fixture.v1",
"gamecult.eve.plugin_abi.request.v1",
"gamecult.eve.plugin_abi.response.v1",
"gamecult.eve.runtime_release_request.v1",
"gamecult.eve.runtime_capture_request.v1",
"gamecult.eve.provider_advertisement.v1",
"gamecult.eve.runtime_capability.v1"
],

View file

@ -16,6 +16,8 @@
"gamecult.eve.plugin_abi_fixture.v1": "schemas/gamecult.eve.plugin_abi_fixture.v1.schema.json",
"gamecult.eve.plugin_advertisement.v1": "schemas/gamecult.eve.plugin_advertisement.v1.schema.json",
"gamecult.eve.runtime_capability.v1": "schemas/gamecult.eve.runtime_capability.v1.schema.json",
"gamecult.eve.runtime_release_request.v1": "schemas/gamecult.eve.runtime_release_request.v1.schema.json",
"gamecult.eve.runtime_capture_request.v1": "schemas/gamecult.eve.runtime_capture_request.v1.schema.json",
"gamecult.eve.provider_scenario.v1": "schemas/gamecult.eve.provider_scenario.v1.schema.json",
"gamecult.eve.provider_advertisement.v1": "schemas/gamecult.eve.provider_advertisement.v1.schema.json"
},

View file

@ -1321,6 +1321,9 @@ function compareCaptureContract(expected, actual, label) {
errors.push(`${label}.${key}:expected ${expected[key] || ""} got ${actual[key] || ""}`);
}
}
if (actual.requestSchema && !manifest.schemas?.[actual.requestSchema]) {
errors.push(`${label}.requestSchema:${actual.requestSchema}:missing-schema-catalog-entry`);
}
return errors;
}
@ -1363,6 +1366,9 @@ function compareReleaseContract(expected, actual, label) {
errors.push(`${label}.${key}:expected ${expected[key] || ""} got ${actual[key] || ""}`);
}
}
if (actual.requestSchema && !manifest.schemas?.[actual.requestSchema]) {
errors.push(`${label}.requestSchema:${actual.requestSchema}:missing-schema-catalog-entry`);
}
for (const key of ["packageRoot", "versionSource", "requestBuilder"]) {
if (actual[key] && !existsSync(path.join(repoRoot, actual[key]))) {
errors.push(`${label}.${key}:${actual[key]}:missing`);