Add runtime split handoff schema
This commit is contained in:
parent
73deb9d46e
commit
8de1dced44
10 changed files with 171 additions and 2 deletions
|
|
@ -418,6 +418,11 @@ Recently cut:
|
|||
and command transport, does not treat Aetheria product paths as generic
|
||||
runtime source, names the required Eve contracts, and keeps capture as an
|
||||
external proof until EveUnity owns it.
|
||||
- Runtime split handoff documents now have a catalog-backed schema,
|
||||
`gamecult.eve.runtime_split_handoff.v1`. EveConformance exports that schema
|
||||
so runtime owner repos can consume split target, move set, contract input,
|
||||
forbidden import, and external proof shape without trusting only ad hoc smoke
|
||||
script checks.
|
||||
- EveElectron now has a pending split target and handoff at
|
||||
`runtimes/incubating/eve-electron/eveelectron-split-handoff.json`. It does
|
||||
claim a provider-agnostic Electron shell surface-tree projection and command
|
||||
|
|
|
|||
|
|
@ -216,6 +216,10 @@ Aetheria's current Electron client, and `replacement-required` records mark
|
|||
move sets where no generic runtime source exists yet. Consumer smokes can
|
||||
assert them with
|
||||
`--expect-split-handoff-move <splitTarget:runtimeId:moveSetId:pathKind:status:path-substring>`.
|
||||
Runtime split handoff documents themselves use
|
||||
`gamecult.eve.runtime_split_handoff.v1`; the parity runner validates the
|
||||
handoff document shape and exports any `splitHandoffErrors` on the runtime
|
||||
record.
|
||||
|
||||
After generating the parity report, `run-parity-harness.ps1` copies
|
||||
`artifacts/conformance/latest` into
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,9 @@
|
|||
"splitHandoffPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"splitHandoffErrors": {
|
||||
"type": "array"
|
||||
},
|
||||
"splitHandoffExportPath": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
133
schemas/gamecult.eve.runtime_split_handoff.v1.schema.json
Normal file
133
schemas/gamecult.eve.runtime_split_handoff.v1.schema.json
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "gamecult.eve.runtime_split_handoff.v1",
|
||||
"title": "Eve Runtime Split Handoff",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"schema",
|
||||
"splitTarget",
|
||||
"ownerRepo",
|
||||
"currentHostRepo",
|
||||
"runtimeId",
|
||||
"sourcePackageRoot",
|
||||
"destinationPackageRoot",
|
||||
"authorityBoundary",
|
||||
"moveSets",
|
||||
"contractInputs",
|
||||
"forbiddenImports",
|
||||
"requiredExternalProofs"
|
||||
],
|
||||
"properties": {
|
||||
"schema": {
|
||||
"const": "gamecult.eve.runtime_split_handoff.v1"
|
||||
},
|
||||
"splitTarget": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ownerRepo": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"currentHostRepo": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"runtimeId": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"packageName": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourcePackageRoot": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"destinationPackageRoot": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"authorityBoundary": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"moveSets": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"stage",
|
||||
"destinationOwner",
|
||||
"replacementProof"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"stage": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"currentPaths": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"observedProviderPaths": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"replacementRequired": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"destinationOwner": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"replacementProof": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"contractInputs": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"forbiddenImports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"requiredExternalProofs": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@ try {
|
|||
--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-schema gamecult.eve.runtime_split_handoff.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 `
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ foreach ($contract in @(
|
|||
"gamecult.eve.runtime_release_request.v1",
|
||||
"gamecult.eve.runtime_capture_request.v1",
|
||||
"gamecult.eve.provider_advertisement.v1",
|
||||
"gamecult.eve.runtime_capability.v1"
|
||||
"gamecult.eve.runtime_capability.v1",
|
||||
"gamecult.eve.runtime_split_handoff.v1"
|
||||
)) {
|
||||
if (-not (@($handoff.contractInputs) -contains $contract)) {
|
||||
throw "EveConformance handoff missing contract input: $contract"
|
||||
|
|
@ -118,6 +119,7 @@ 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.runtime_split_handoff.v1",
|
||||
"gamecult.eve.command_receipt.v1",
|
||||
"gamecult.eve.plugin.v1",
|
||||
"gamecult.eve.plugin_receipt.v1",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ node $consumerScript $consumerExport `
|
|||
--expect-runtime direct2d `
|
||||
--expect-schema gamecult.eve.runtime_release_request.v1 `
|
||||
--expect-schema gamecult.eve.runtime_capture_request.v1 `
|
||||
--expect-schema gamecult.eve.runtime_split_handoff.v1 `
|
||||
--expect-runtime-status web:active `
|
||||
--expect-runtime-status windows-flutter:active `
|
||||
--expect-runtime-status linux-flutter:active `
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
"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.runtime_split_handoff.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",
|
||||
|
|
@ -80,7 +81,8 @@
|
|||
"gamecult.eve.runtime_release_request.v1",
|
||||
"gamecult.eve.runtime_capture_request.v1",
|
||||
"gamecult.eve.provider_advertisement.v1",
|
||||
"gamecult.eve.runtime_capability.v1"
|
||||
"gamecult.eve.runtime_capability.v1",
|
||||
"gamecult.eve.runtime_split_handoff.v1"
|
||||
],
|
||||
"forbiddenImports": [
|
||||
"provider internals as conformance truth",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
"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_split_handoff.v1": "schemas/gamecult.eve.runtime_split_handoff.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",
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ async function evaluateRuntime(runtime, fixtureResults) {
|
|||
const capabilityManifestErrors = await validateRuntimeCapabilityManifest(runtime);
|
||||
const capabilityManifestDocument = await readRuntimeCapabilityManifestDocument(runtime);
|
||||
const splitHandoffPath = await readRuntimeSplitHandoffPath(runtime);
|
||||
const splitHandoffErrors = await validateRuntimeSplitHandoff(runtime, splitHandoffPath);
|
||||
const localProviderCatalogErrors = await validateRuntimeLocalProviderCatalog(runtime);
|
||||
const missingIncubationFields = requiredIncubationFields(runtime).filter(field => !runtime[field]);
|
||||
const pluginCapabilityGaps = collectPluginCapabilityGaps(runtime, fixtureResults);
|
||||
|
|
@ -316,6 +317,7 @@ async function evaluateRuntime(runtime, fixtureResults) {
|
|||
if (runtime.kind === "active" && missingRequiredFeatures.length) status = "missing-required-feature";
|
||||
if (runtime.kind === "active" && commandTransportSmokeErrors.length) status = "missing-command-transport-smoke";
|
||||
if (runtime.kind === "active" && capabilityManifestErrors.length) status = "invalid-runtime-capability";
|
||||
if (runtime.kind === "active" && splitHandoffErrors.length) status = "invalid-runtime-split-handoff";
|
||||
if (runtime.kind === "active" && localProviderCatalogErrors.length) status = "invalid-local-provider-catalog";
|
||||
if (runtime.kind === "active" && missingIncubationFields.length) status = "missing-incubation-metadata";
|
||||
if (runtime.kind === "active" && pluginCapabilityGaps.length && status === "active") status = "active-with-capability-gaps";
|
||||
|
|
@ -354,6 +356,7 @@ async function evaluateRuntime(runtime, fixtureResults) {
|
|||
capabilityManifest: runtime.capabilityManifest || null,
|
||||
capabilityManifestErrors,
|
||||
splitHandoffPath,
|
||||
splitHandoffErrors,
|
||||
localProviderCatalog: runtime.localProviderCatalog || null,
|
||||
localProviderCatalogErrors,
|
||||
lifecycle: runtime.lifecycle || capabilityManifestDocument?.lifecycle || null,
|
||||
|
|
@ -437,6 +440,18 @@ async function readRuntimeSplitHandoffPath(runtime) {
|
|||
}
|
||||
}
|
||||
|
||||
async function validateRuntimeSplitHandoff(runtime, splitHandoffPath) {
|
||||
if (!splitHandoffPath) return [];
|
||||
return validateJsonDocument(
|
||||
manifest.schemas?.["gamecult.eve.runtime_split_handoff.v1"],
|
||||
splitHandoffPath,
|
||||
{
|
||||
schema: "gamecult.eve.runtime_split_handoff.v1",
|
||||
runtimeId: runtime.id,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function normalizePath(candidate) {
|
||||
return candidate.replaceAll("\\", "/").replace(/^\.\//, "");
|
||||
}
|
||||
|
|
@ -1804,6 +1819,7 @@ function buildConformanceExport(report) {
|
|||
capabilityManifestPath: runtime.capabilityManifest?.manifestPath || "",
|
||||
capabilityManifestErrors: runtime.capabilityManifestErrors || [],
|
||||
splitHandoffPath: runtime.splitHandoffPath || "",
|
||||
splitHandoffErrors: runtime.splitHandoffErrors || [],
|
||||
splitHandoffExportPath: makeHandoffExportPath("runtime", runtime.id, runtime.splitHandoffPath || ""),
|
||||
commandTransportSchema: runtimeCommandTransportSchema(runtime),
|
||||
captureStatus: runtime.capture?.status || "",
|
||||
|
|
@ -1975,6 +1991,7 @@ function collectCapabilityGaps(report) {
|
|||
...(runtime.missingRequiredFeatures || []).map(id => `feature:${id}`),
|
||||
...(runtime.commandTransportSmokeErrors || []).map(id => `command-smoke:${id}`),
|
||||
...(runtime.capabilityManifestErrors || []).map(id => `runtime-capability:${id}`),
|
||||
...(runtime.splitHandoffErrors || []).map(id => `runtime-split-handoff:${id}`),
|
||||
...(runtime.localProviderCatalogErrors || []).map(id => `local-provider-catalog:${id}`),
|
||||
...(runtime.pluginCapabilityGaps || []).map(id => `plugin-capability:${id}`),
|
||||
]) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue