Add generic runtime capture controls

This commit is contained in:
Meta Vens 2026-07-09 17:00:58 +01:00
commit 7c7cfcde8e
25 changed files with 486 additions and 52 deletions

View file

@ -1007,6 +1007,12 @@ Recently cut:
accepted and denied command receipts through
`eve.world_smoke.command_receipt.v1`, so replay proof is no longer only an
Aetheria product concern.
- Runtime semantic capture now uses the same generic world control. UI Toolkit,
Unity scene, Electron shell, and TUI capture contracts keep Aetheria as the
primary pressure fixture while declaring `eve.world-smoke` as an additional
accepted provider surface. The parity harness emits separate
`eve-world-smoke` JSON projection/grid artifacts for those runtimes, and the
runtime-owner conformance smoke asserts them from the exported pack.
- Sai, Norn, and TeX now have plugin ABI fixtures for describe, validate,
project, lower, measure, and apply behavior. The parity harness validates
those fixtures against plugin manifests, so Eve proves the ABI shape without

View file

@ -61,7 +61,8 @@
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs",
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/TeXMathUiToolkitProjectionAdapter.cs",
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -199,6 +200,13 @@
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"additionalProviderSurfaces": [
{
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"purpose": "Generic non-product interactive-world capture control."
}
],
"authority": "Capture observes runtime projection only; provider state, command acceptance, and receipts stay provider-owned.",
"publishProof": "Unity editor or batchmode capture artifact is attached to the runtime conformance report from EveUnity."
},

View file

@ -60,7 +60,8 @@
"runtimes/incubating/eve-electron/src/eve-electron-shell.mjs",
"runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs",
"web/fixtures/sai-vn-surface.json",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -143,6 +144,13 @@
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"additionalProviderSurfaces": [
{
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"purpose": "Generic non-product interactive-world capture control."
}
],
"authority": "Capture observes Electron projection only; provider state, command acceptance, and receipts stay provider-owned.",
"publishProof": "Electron window capture artifact is attached to the runtime conformance report from EveElectron."
},

View file

@ -65,7 +65,8 @@
"runtimes/incubating/eve-tui/src/eve-tui-shell.mjs",
"runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs",
"web/fixtures/sai-vn-surface.json",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -148,6 +149,13 @@
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"additionalProviderSurfaces": [
{
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"purpose": "Generic non-product interactive-world capture control."
}
],
"authority": "Capture observes terminal projection only; provider state, command acceptance, and receipts stay provider-owned.",
"publishProof": "Terminal cell-grid JSON capture artifact is attached to the runtime conformance report from EveTui."
},

View file

@ -62,7 +62,8 @@
"runtimes/incubating/eve-unity-scene/Runtime/NornGraphUnitySceneProjectionAdapter.cs",
"runtimes/incubating/eve-unity-scene/Runtime/TeXMathUnitySceneProjectionAdapter.cs",
"runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -163,6 +164,13 @@
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"additionalProviderSurfaces": [
{
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"purpose": "Generic non-product interactive-world capture control."
}
],
"authority": "Capture observes Unity scene projection only; provider state, command acceptance, and receipts stay provider-owned.",
"publishProof": "Unity scene screenshot or frame-capture PNG artifact is attached to the runtime conformance report from EveUnity."
},

View file

@ -893,6 +893,27 @@
"requiredSurface": {
"type": "string"
},
"additionalProviderSurfaces": {
"type": "array",
"items": {
"type": "object",
"required": ["providerId", "surfaceId"],
"properties": {
"providerId": {
"type": "string",
"minLength": 1
},
"surfaceId": {
"type": "string",
"minLength": 1
},
"purpose": {
"type": "string"
}
},
"additionalProperties": true
}
},
"authority": {
"type": "string"
},

View file

@ -573,6 +573,27 @@
"type": "string",
"minLength": 1
},
"additionalProviderSurfaces": {
"type": "array",
"items": {
"type": "object",
"required": ["providerId", "surfaceId"],
"properties": {
"providerId": {
"type": "string",
"minLength": 1
},
"surfaceId": {
"type": "string",
"minLength": 1
},
"purpose": {
"type": "string"
}
},
"additionalProperties": true
}
},
"authority": {
"type": "string",
"minLength": 1

View file

@ -4,7 +4,11 @@ param(
[string] $SurfacePath = "web\fixtures\aetheria-world-surface.json",
[string] $OutputPath = "artifacts\eveelectron-capture\latest\electron-shell-projection.json",
[string] $RequestOutputPath = "artifacts\eveelectron-capture\latest\capture-request.json",
[string] $Stamp = "latest"
[string] $Stamp = "latest",
[string] $ExpectedProviderId = "aetheria",
[string] $ExpectedSurfaceId = "aetheria.daemon.game",
[string] $ExpectedCommandBoundary = "aetheria.daemon.commands",
[string] $ExpectedReceiptSchema = "aetheria.eve_command_acceptance_status.v1"
)
$ErrorActionPreference = "Stop"
@ -55,10 +59,10 @@ $projection = Get-Content -LiteralPath $absoluteOutputPath -Raw | ConvertFrom-Js
foreach ($expectation in @(
@{ field = "schema"; value = "gamecult.eve.electron_shell_projection.v1" },
@{ field = "runtimeId"; value = "electron-shell" },
@{ field = "providerId"; value = "aetheria" },
@{ field = "surfaceId"; value = "aetheria.daemon.game" },
@{ field = "commandBoundary"; value = "aetheria.daemon.commands" },
@{ field = "receiptSchema"; value = "aetheria.eve_command_acceptance_status.v1" },
@{ field = "providerId"; value = $ExpectedProviderId },
@{ field = "surfaceId"; value = $ExpectedSurfaceId },
@{ field = "commandBoundary"; value = $ExpectedCommandBoundary },
@{ field = "receiptSchema"; value = $ExpectedReceiptSchema },
@{ field = "artifactKind"; value = "json-projection" },
@{ field = "captureKind"; value = "electron-shell-projection-json" }
)) {

View file

@ -4,7 +4,11 @@ param(
[string] $SurfacePath = "web\fixtures\aetheria-world-surface.json",
[string] $OutputPath = "artifacts\evetui-capture\latest\tui-grid.json",
[string] $RequestOutputPath = "artifacts\evetui-capture\latest\capture-request.json",
[string] $Stamp = "latest"
[string] $Stamp = "latest",
[string] $ExpectedProviderId = "aetheria",
[string] $ExpectedSurfaceId = "aetheria.daemon.game",
[string] $ExpectedCommandBoundary = "aetheria.daemon.commands",
[string] $ExpectedReceiptSchema = "aetheria.eve_command_acceptance_status.v1"
)
$ErrorActionPreference = "Stop"
@ -55,10 +59,10 @@ $grid = Get-Content -LiteralPath $absoluteOutputPath -Raw | ConvertFrom-Json
foreach ($expectation in @(
@{ field = "schema"; value = "gamecult.eve.tui_grid.v1" },
@{ field = "runtimeId"; value = "tui" },
@{ field = "providerId"; value = "aetheria" },
@{ field = "surfaceId"; value = "aetheria.daemon.game" },
@{ field = "commandBoundary"; value = "aetheria.daemon.commands" },
@{ field = "receiptSchema"; value = "aetheria.eve_command_acceptance_status.v1" },
@{ field = "providerId"; value = $ExpectedProviderId },
@{ field = "surfaceId"; value = $ExpectedSurfaceId },
@{ field = "commandBoundary"; value = $ExpectedCommandBoundary },
@{ field = "receiptSchema"; value = $ExpectedReceiptSchema },
@{ field = "artifactKind"; value = "json-grid" },
@{ field = "captureKind"; value = "terminal-cell-grid" }
)) {

View file

@ -4,7 +4,11 @@ param(
[string] $SurfacePath = "web\fixtures\aetheria-world-surface.json",
[string] $OutputPath = "artifacts\eveunity-scene-capture\latest\unity-scene-projection.json",
[string] $RequestOutputPath = "artifacts\eveunity-scene-capture\latest\capture-request.json",
[string] $Stamp = "latest"
[string] $Stamp = "latest",
[string] $ExpectedProviderId = "aetheria",
[string] $ExpectedSurfaceId = "aetheria.daemon.game",
[string] $ExpectedCommandBoundary = "aetheria.daemon.commands",
[string] $ExpectedReceiptSchema = "aetheria.eve_command_acceptance_status.v1"
)
$ErrorActionPreference = "Stop"
@ -55,10 +59,10 @@ $projection = Get-Content -LiteralPath $absoluteOutputPath -Raw | ConvertFrom-Js
foreach ($expectation in @(
@{ field = "schema"; value = "gamecult.eve.unity_scene_projection.v1" },
@{ field = "runtimeId"; value = "unity-scene" },
@{ field = "providerId"; value = "aetheria" },
@{ field = "surfaceId"; value = "aetheria.daemon.game" },
@{ field = "commandBoundary"; value = "aetheria.daemon.commands" },
@{ field = "receiptSchema"; value = "aetheria.eve_command_acceptance_status.v1" },
@{ field = "providerId"; value = $ExpectedProviderId },
@{ field = "surfaceId"; value = $ExpectedSurfaceId },
@{ field = "commandBoundary"; value = $ExpectedCommandBoundary },
@{ field = "receiptSchema"; value = $ExpectedReceiptSchema },
@{ field = "artifactKind"; value = "json-projection" },
@{ field = "captureKind"; value = "unity-scene-projection-json" }
)) {

View file

@ -4,7 +4,11 @@ param(
[string] $SurfacePath = "web\fixtures\aetheria-world-surface.json",
[string] $OutputPath = "artifacts\eveunity-uitoolkit-capture\latest\unity-uitoolkit-projection.json",
[string] $RequestOutputPath = "artifacts\eveunity-uitoolkit-capture\latest\capture-request.json",
[string] $Stamp = "latest"
[string] $Stamp = "latest",
[string] $ExpectedProviderId = "aetheria",
[string] $ExpectedSurfaceId = "aetheria.daemon.game",
[string] $ExpectedCommandBoundary = "aetheria.daemon.commands",
[string] $ExpectedReceiptSchema = "aetheria.eve_command_acceptance_status.v1"
)
$ErrorActionPreference = "Stop"
@ -55,10 +59,10 @@ $projection = Get-Content -LiteralPath $absoluteOutputPath -Raw | ConvertFrom-Js
foreach ($expectation in @(
@{ field = "schema"; value = "gamecult.eve.unity_uitoolkit_projection.v1" },
@{ field = "runtimeId"; value = "unity-uitoolkit" },
@{ field = "providerId"; value = "aetheria" },
@{ field = "surfaceId"; value = "aetheria.daemon.game" },
@{ field = "commandBoundary"; value = "aetheria.daemon.commands" },
@{ field = "receiptSchema"; value = "aetheria.eve_command_acceptance_status.v1" },
@{ field = "providerId"; value = $ExpectedProviderId },
@{ field = "surfaceId"; value = $ExpectedSurfaceId },
@{ field = "commandBoundary"; value = $ExpectedCommandBoundary },
@{ field = "receiptSchema"; value = $ExpectedReceiptSchema },
@{ field = "artifactKind"; value = "json-projection" },
@{ field = "captureKind"; value = "unity-uitoolkit-projection-json" }
)) {

View file

@ -27,7 +27,43 @@ try {
-Port 8894 `
-SkipBuild
& (Join-Path $PSScriptRoot "run-eveunity-uitoolkit-capture-smoke.ps1")
& (Join-Path $PSScriptRoot "run-eveunity-uitoolkit-capture-smoke.ps1") `
-AdvertisementPath "web\fixtures\eve-world-smoke.provider-advertisement.json" `
-SurfacePath "web\fixtures\eve-world-smoke-surface.json" `
-OutputPath "artifacts\eveunity-uitoolkit-capture\latest\eve-world-smoke-unity-uitoolkit-projection.json" `
-RequestOutputPath "artifacts\eveunity-uitoolkit-capture\latest\eve-world-smoke-capture-request.json" `
-ExpectedProviderId "eve.world-smoke" `
-ExpectedSurfaceId "eve.world-smoke.surface" `
-ExpectedCommandBoundary "eve.world-smoke.commands" `
-ExpectedReceiptSchema "eve.world_smoke.command_receipt.v1"
& (Join-Path $PSScriptRoot "run-eveunity-scene-capture-smoke.ps1") `
-AdvertisementPath "web\fixtures\eve-world-smoke.provider-advertisement.json" `
-SurfacePath "web\fixtures\eve-world-smoke-surface.json" `
-OutputPath "artifacts\eveunity-scene-capture\latest\eve-world-smoke-unity-scene-projection.json" `
-RequestOutputPath "artifacts\eveunity-scene-capture\latest\eve-world-smoke-capture-request.json" `
-ExpectedProviderId "eve.world-smoke" `
-ExpectedSurfaceId "eve.world-smoke.surface" `
-ExpectedCommandBoundary "eve.world-smoke.commands" `
-ExpectedReceiptSchema "eve.world_smoke.command_receipt.v1"
& (Join-Path $PSScriptRoot "run-eveelectron-capture-smoke.ps1") `
-AdvertisementPath "web\fixtures\eve-world-smoke.provider-advertisement.json" `
-SurfacePath "web\fixtures\eve-world-smoke-surface.json" `
-OutputPath "artifacts\eveelectron-capture\latest\eve-world-smoke-electron-shell-projection.json" `
-RequestOutputPath "artifacts\eveelectron-capture\latest\eve-world-smoke-capture-request.json" `
-ExpectedProviderId "eve.world-smoke" `
-ExpectedSurfaceId "eve.world-smoke.surface" `
-ExpectedCommandBoundary "eve.world-smoke.commands" `
-ExpectedReceiptSchema "eve.world_smoke.command_receipt.v1"
& (Join-Path $PSScriptRoot "run-evetui-capture-smoke.ps1")
& (Join-Path $PSScriptRoot "run-evetui-capture-smoke.ps1") `
-AdvertisementPath "web\fixtures\eve-world-smoke.provider-advertisement.json" `
-SurfacePath "web\fixtures\eve-world-smoke-surface.json" `
-OutputPath "artifacts\evetui-capture\latest\eve-world-smoke-tui-grid.json" `
-RequestOutputPath "artifacts\evetui-capture\latest\eve-world-smoke-capture-request.json" `
-ExpectedProviderId "eve.world-smoke" `
-ExpectedSurfaceId "eve.world-smoke.surface" `
-ExpectedCommandBoundary "eve.world-smoke.commands" `
-ExpectedReceiptSchema "eve.world_smoke.command_receipt.v1"
node .\tools\parity\run-parity.mjs
& (Join-Path $PSScriptRoot "run-eveconformance-handoff-smoke.ps1")
& (Join-Path $PSScriptRoot "run-plugin-handoff-smoke.ps1")

View file

@ -145,12 +145,16 @@ node $consumerScript $consumerExport `
--expect-runtime-capture-status android-flutter:adb-png `
--expect-runtime-capture-status unity-uitoolkit:json-projection `
--expect-runtime-capture-artifact unity-uitoolkit:json-projection:gamecult.eve.unity_uitoolkit_projection.v1:aetheria:aetheria.daemon.game `
--expect-runtime-capture-artifact unity-uitoolkit:json-projection:gamecult.eve.unity_uitoolkit_projection.v1:eve.world-smoke:eve.world-smoke.surface `
--expect-runtime-capture-status unity-scene:json-projection `
--expect-runtime-capture-artifact unity-scene:json-projection:gamecult.eve.unity_scene_projection.v1:aetheria:aetheria.daemon.game `
--expect-runtime-capture-artifact unity-scene:json-projection:gamecult.eve.unity_scene_projection.v1:eve.world-smoke:eve.world-smoke.surface `
--expect-runtime-capture-status electron-shell:json-projection `
--expect-runtime-capture-artifact electron-shell:json-projection:gamecult.eve.electron_shell_projection.v1:aetheria:aetheria.daemon.game `
--expect-runtime-capture-artifact electron-shell:json-projection:gamecult.eve.electron_shell_projection.v1:eve.world-smoke:eve.world-smoke.surface `
--expect-runtime-capture-status tui:json-grid `
--expect-runtime-capture-artifact tui:json-grid:gamecult.eve.tui_grid.v1:aetheria:aetheria.daemon.game `
--expect-runtime-capture-artifact tui:json-grid:gamecult.eve.tui_grid.v1:eve.world-smoke:eve.world-smoke.surface `
--expect-runtime-capture-status direct2d:missing `
--expect-runtime-capture-probe unity-uitoolkit:semantic-artifact-present-capture-pending:png:EveUnity `
--expect-runtime-capture-probe unity-scene:semantic-artifact-present-capture-pending:png:EveUnity `
@ -209,6 +213,8 @@ node $consumerScript $consumerExport `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.conformanceAttachment:runtime.captureArtifacts[]" `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.requiredProvider:aetheria" `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.requiredSurface:aetheria.daemon.game" `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.additionalProviderSurfaces.0.providerId:eve.world-smoke" `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.additionalProviderSurfaces.0.surfaceId:eve.world-smoke.surface" `
--expect-runtime-lifecycle-status unity-scene:release:pending-unity-scene-package `
--expect-runtime-lifecycle-status unity-scene:test:provider-shell-contract-skeleton `
--expect-runtime-lifecycle-status unity-scene:capture:pending-unity-scene-capture `
@ -233,6 +239,8 @@ node $consumerScript $consumerExport `
--expect-runtime-lifecycle-field "unity-scene:capture:captureContract.requestBuilder:tools/eveunity/eveunity-capture-contract.mjs" `
--expect-runtime-lifecycle-field "unity-scene:capture:captureContract.advertisementPath:web/fixtures/aetheria.provider-advertisement.json" `
--expect-runtime-lifecycle-field "unity-scene:capture:captureContract.requiredSurface:aetheria.daemon.game" `
--expect-runtime-lifecycle-field "unity-scene:capture:captureContract.additionalProviderSurfaces.0.providerId:eve.world-smoke" `
--expect-runtime-lifecycle-field "unity-scene:capture:captureContract.additionalProviderSurfaces.0.surfaceId:eve.world-smoke.surface" `
--expect-runtime-lifecycle-status electron-shell:release:pending-electron-package `
--expect-runtime-lifecycle-status electron-shell:test:provider-shell-contract-skeleton `
--expect-runtime-lifecycle-status electron-shell:capture:pending-electron-window-capture `
@ -252,6 +260,8 @@ node $consumerScript $consumerExport `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requestBuilder:tools/eveelectron/eveelectron-capture-contract.mjs" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.advertisementPath:web/fixtures/aetheria.provider-advertisement.json" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requiredSurface:aetheria.daemon.game" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.additionalProviderSurfaces.0.providerId:eve.world-smoke" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.additionalProviderSurfaces.0.surfaceId:eve.world-smoke.surface" `
--expect-runtime-lifecycle-status tui:release:pending-tui-package `
--expect-runtime-lifecycle-status tui:test:provider-shell-contract-skeleton `
--expect-runtime-lifecycle-status tui:capture:cell-grid-json-capture `
@ -272,7 +282,9 @@ node $consumerScript $consumerExport `
--expect-runtime-lifecycle-field "tui:capture:captureContract.requestSchema:gamecult.eve.runtime_capture_request.v1" `
--expect-runtime-lifecycle-field "tui:capture:captureContract.requestBuilder:tools/evetui/evetui-capture-contract.mjs" `
--expect-runtime-lifecycle-field "tui:capture:captureContract.advertisementPath:web/fixtures/aetheria.provider-advertisement.json" `
--expect-runtime-lifecycle-field "tui:capture:captureContract.requiredSurface:aetheria.daemon.game"
--expect-runtime-lifecycle-field "tui:capture:captureContract.requiredSurface:aetheria.daemon.game" `
--expect-runtime-lifecycle-field "tui:capture:captureContract.additionalProviderSurfaces.0.providerId:eve.world-smoke" `
--expect-runtime-lifecycle-field "tui:capture:captureContract.additionalProviderSurfaces.0.surfaceId:eve.world-smoke.surface"
if ($LASTEXITCODE -ne 0) {
throw "Runtime owner conformance consumer smoke failed with exit code $LASTEXITCODE"

View file

@ -6,6 +6,8 @@ import { buildElectronCaptureArtifact } from "./eveelectron-capture-artifact.mjs
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-electron/eve-runtime-capability.json", import.meta.url), "utf8"));
const surfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria-world-surface.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke-surface.json", import.meta.url), "utf8"));
test("builds Electron shell projection capture artifact from provider advertisement and surface", () => {
const { request, projection } = buildElectronCaptureArtifact({
@ -28,3 +30,22 @@ test("builds Electron shell projection capture artifact from provider advertisem
assert.equal(projection.captureKind, "electron-shell-projection-json");
assert.equal(projection.root.id, "aetheria.daemon.game.root");
});
test("builds Electron shell projection capture artifact from a generic world provider", () => {
const { projection } = buildElectronCaptureArtifact({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
surfaceDocument: worldSmokeSurfaceDocument,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-electron/eve-runtime-capability.json",
stamp: "smoke",
});
assert.equal(projection.schema, "gamecult.eve.electron_shell_projection.v1");
assert.equal(projection.runtimeId, "electron-shell");
assert.equal(projection.providerId, "eve.world-smoke");
assert.equal(projection.surfaceId, "eve.world-smoke.surface");
assert.equal(projection.commandBoundary, "eve.world-smoke.commands");
assert.equal(projection.receiptSchema, "eve.world_smoke.command_receipt.v1");
assert.equal(projection.root.id, "eve.world-smoke.root");
});

View file

@ -21,16 +21,17 @@ export function buildElectronCaptureRequest({
throw new Error("capability manifest is missing lifecycle.capture.captureContract");
}
if (advertisement.providerId !== captureContract.requiredProvider) {
const captureSurface = selectCaptureSurface(captureContract, advertisement.providerId);
if (!captureSurface) {
throw new Error(
`capture provider mismatch: expected ${captureContract.requiredProvider} got ${advertisement.providerId || "missing"}`,
`capture provider mismatch: expected ${captureProviderList(captureContract)} got ${advertisement.providerId || "missing"}`,
);
}
const targetId = captureContract.targetId || captureContract.runtimeId;
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureContract.requiredSurface);
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureSurface.surfaceId);
if (!surface) {
throw new Error(`capture surface not advertised: ${captureContract.requiredSurface}`);
throw new Error(`capture surface not advertised: ${captureSurface.surfaceId}`);
}
const loweringTargets = surface.worldInteraction?.loweringTargets || [];
@ -78,6 +79,30 @@ function replaceStamp(pattern, stamp) {
return pattern.replace("{stamp}", stamp);
}
function selectCaptureSurface(captureContract, providerId) {
return captureSurfaceClaims(captureContract).find(claim => claim.providerId === providerId) || null;
}
function captureProviderList(captureContract) {
return captureSurfaceClaims(captureContract).map(claim => claim.providerId).filter(Boolean).join(", ") || "missing";
}
function captureSurfaceClaims(captureContract) {
return [
{
providerId: captureContract.requiredProvider || "",
surfaceId: captureContract.requiredSurface || "",
},
...(Array.isArray(captureContract.additionalProviderSurfaces) ? captureContract.additionalProviderSurfaces : []),
]
.filter(claim => claim && typeof claim === "object")
.map(claim => ({
providerId: String(claim.providerId || ""),
surfaceId: String(claim.surfaceId || ""),
}))
.filter(claim => claim.providerId && claim.surfaceId);
}
function parseArgs(argv) {
const args = {};
for (let index = 0; index < argv.length; index += 1) {

View file

@ -4,6 +4,7 @@ import test from "node:test";
import { buildElectronCaptureRequest } from "./eveelectron-capture-contract.mjs";
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-electron/eve-runtime-capability.json", import.meta.url), "utf8"));
test("builds Electron shell capture request from provider advertisement", () => {
@ -28,6 +29,22 @@ test("builds Electron shell capture request from provider advertisement", () =>
assert.match(request.authority, /provider state/);
});
test("builds Electron shell capture request from a declared generic world provider", () => {
const request = buildElectronCaptureRequest({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-electron/eve-runtime-capability.json",
stamp: "smoke",
});
assert.equal(request.runtimeId, "electron-shell");
assert.equal(request.providerId, "eve.world-smoke");
assert.equal(request.surfaceId, "eve.world-smoke.surface");
assert.equal(request.commandBoundary, "eve.world-smoke.commands");
assert.equal(request.receiptSchema, "eve.world_smoke.command_receipt.v1");
});
test("rejects capture request when the surface does not advertise Electron shell", () => {
const withoutTarget = structuredClone(advertisement);
const surface = withoutTarget.surfaces.find(candidate => candidate.surfaceId === "aetheria.daemon.game");

View file

@ -6,6 +6,8 @@ import { buildTuiCaptureArtifact } from "./evetui-capture-artifact.mjs";
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-tui/eve-runtime-capability.json", import.meta.url), "utf8"));
const surfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria-world-surface.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke-surface.json", import.meta.url), "utf8"));
test("builds TUI JSON grid capture artifact from provider advertisement and surface", () => {
const { request, grid } = buildTuiCaptureArtifact({
@ -31,3 +33,25 @@ test("builds TUI JSON grid capture artifact from provider advertisement and surf
assert.equal(grid.width, 72);
assert.ok(grid.lines.some(line => line.includes("aetheria.daemon.game")));
});
test("builds TUI JSON grid capture artifact from a generic world provider", () => {
const { grid } = buildTuiCaptureArtifact({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
surfaceDocument: worldSmokeSurfaceDocument,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-tui/eve-runtime-capability.json",
stamp: "smoke",
width: 72,
});
assert.equal(grid.schema, "gamecult.eve.tui_grid.v1");
assert.equal(grid.runtimeId, "tui");
assert.equal(grid.providerId, "eve.world-smoke");
assert.equal(grid.surfaceId, "eve.world-smoke.surface");
assert.equal(grid.commandBoundary, "eve.world-smoke.commands");
assert.equal(grid.receiptSchema, "eve.world_smoke.command_receipt.v1");
assert.equal(grid.artifactKind, "json-grid");
assert.equal(grid.captureKind, "terminal-cell-grid");
assert.ok(grid.lines.some(line => line.includes("eve.world-smoke.surface")));
});

View file

@ -21,16 +21,17 @@ export function buildTuiCaptureRequest({
throw new Error("capability manifest is missing lifecycle.capture.captureContract");
}
if (advertisement.providerId !== captureContract.requiredProvider) {
const captureSurface = selectCaptureSurface(captureContract, advertisement.providerId);
if (!captureSurface) {
throw new Error(
`capture provider mismatch: expected ${captureContract.requiredProvider} got ${advertisement.providerId || "missing"}`,
`capture provider mismatch: expected ${captureProviderList(captureContract)} got ${advertisement.providerId || "missing"}`,
);
}
const targetId = captureContract.targetId || captureContract.runtimeId;
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureContract.requiredSurface);
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureSurface.surfaceId);
if (!surface) {
throw new Error(`capture surface not advertised: ${captureContract.requiredSurface}`);
throw new Error(`capture surface not advertised: ${captureSurface.surfaceId}`);
}
const loweringTargets = surface.worldInteraction?.loweringTargets || [];
@ -78,6 +79,30 @@ function replaceStamp(pattern, stamp) {
return pattern.replace("{stamp}", stamp);
}
function selectCaptureSurface(captureContract, providerId) {
return captureSurfaceClaims(captureContract).find(claim => claim.providerId === providerId) || null;
}
function captureProviderList(captureContract) {
return captureSurfaceClaims(captureContract).map(claim => claim.providerId).filter(Boolean).join(", ") || "missing";
}
function captureSurfaceClaims(captureContract) {
return [
{
providerId: captureContract.requiredProvider || "",
surfaceId: captureContract.requiredSurface || "",
},
...(Array.isArray(captureContract.additionalProviderSurfaces) ? captureContract.additionalProviderSurfaces : []),
]
.filter(claim => claim && typeof claim === "object")
.map(claim => ({
providerId: String(claim.providerId || ""),
surfaceId: String(claim.surfaceId || ""),
}))
.filter(claim => claim.providerId && claim.surfaceId);
}
function parseArgs(argv) {
const args = {};
for (let index = 0; index < argv.length; index += 1) {

View file

@ -4,6 +4,7 @@ import test from "node:test";
import { buildTuiCaptureRequest } from "./evetui-capture-contract.mjs";
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-tui/eve-runtime-capability.json", import.meta.url), "utf8"));
test("builds TUI capture request from provider advertisement", () => {
@ -30,6 +31,22 @@ test("builds TUI capture request from provider advertisement", () => {
assert.match(request.authority, /provider state/);
});
test("builds TUI capture request from a declared generic world provider", () => {
const request = buildTuiCaptureRequest({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-tui/eve-runtime-capability.json",
stamp: "smoke",
});
assert.equal(request.runtimeId, "tui");
assert.equal(request.providerId, "eve.world-smoke");
assert.equal(request.surfaceId, "eve.world-smoke.surface");
assert.equal(request.commandBoundary, "eve.world-smoke.commands");
assert.equal(request.receiptSchema, "eve.world_smoke.command_receipt.v1");
});
test("rejects capture request when the surface does not advertise TUI", () => {
const withoutTarget = structuredClone(advertisement);
const surface = withoutTarget.surfaces.find(candidate => candidate.surfaceId === "aetheria.daemon.game");

View file

@ -21,16 +21,17 @@ export function buildUnityCaptureRequest({
throw new Error("capability manifest is missing lifecycle.capture.captureContract");
}
if (advertisement.providerId !== captureContract.requiredProvider) {
const captureSurface = selectCaptureSurface(captureContract, advertisement.providerId);
if (!captureSurface) {
throw new Error(
`capture provider mismatch: expected ${captureContract.requiredProvider} got ${advertisement.providerId || "missing"}`,
`capture provider mismatch: expected ${captureProviderList(captureContract)} got ${advertisement.providerId || "missing"}`,
);
}
const targetId = captureContract.targetId || captureContract.runtimeId;
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureContract.requiredSurface);
const surface = (advertisement.surfaces || []).find(candidate => candidate.surfaceId === captureSurface.surfaceId);
if (!surface) {
throw new Error(`capture surface not advertised: ${captureContract.requiredSurface}`);
throw new Error(`capture surface not advertised: ${captureSurface.surfaceId}`);
}
const loweringTargets = surface.worldInteraction?.loweringTargets || [];
@ -78,6 +79,30 @@ function replaceStamp(pattern, stamp) {
return pattern.replace("{stamp}", stamp);
}
function selectCaptureSurface(captureContract, providerId) {
return captureSurfaceClaims(captureContract).find(claim => claim.providerId === providerId) || null;
}
function captureProviderList(captureContract) {
return captureSurfaceClaims(captureContract).map(claim => claim.providerId).filter(Boolean).join(", ") || "missing";
}
function captureSurfaceClaims(captureContract) {
return [
{
providerId: captureContract.requiredProvider || "",
surfaceId: captureContract.requiredSurface || "",
},
...(Array.isArray(captureContract.additionalProviderSurfaces) ? captureContract.additionalProviderSurfaces : []),
]
.filter(claim => claim && typeof claim === "object")
.map(claim => ({
providerId: String(claim.providerId || ""),
surfaceId: String(claim.surfaceId || ""),
}))
.filter(claim => claim.providerId && claim.surfaceId);
}
function parseArgs(argv) {
const args = {};
for (let index = 0; index < argv.length; index += 1) {

View file

@ -4,6 +4,7 @@ import test from "node:test";
import { buildUnityCaptureRequest } from "./eveunity-capture-contract.mjs";
const advertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json", import.meta.url), "utf8"));
const sceneCapabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-unity-scene/eve-runtime-capability.json", import.meta.url), "utf8"));
@ -29,6 +30,22 @@ test("builds Unity UI Toolkit capture request from provider advertisement", () =
assert.match(request.authority, /provider state/);
});
test("builds Unity UI Toolkit capture request from a declared generic world provider", () => {
const request = buildUnityCaptureRequest({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json",
stamp: "smoke",
});
assert.equal(request.runtimeId, "unity-uitoolkit");
assert.equal(request.providerId, "eve.world-smoke");
assert.equal(request.surfaceId, "eve.world-smoke.surface");
assert.equal(request.commandBoundary, "eve.world-smoke.commands");
assert.equal(request.receiptSchema, "eve.world_smoke.command_receipt.v1");
});
test("rejects a capture request when the surface does not advertise the runtime target", () => {
const withoutTarget = structuredClone(advertisement);
const surface = withoutTarget.surfaces.find(candidate => candidate.surfaceId === "aetheria.daemon.game");
@ -61,3 +78,19 @@ test("builds Unity scene capture request from provider advertisement", () => {
assert.equal(request.artifactPath, "artifacts/eveunity-scene-capture/smoke/unity-scene.png");
assert.match(request.authority, /provider state/);
});
test("builds Unity scene capture request from a declared generic world provider", () => {
const request = buildUnityCaptureRequest({
advertisement: worldSmokeAdvertisement,
capabilityManifest: sceneCapabilityManifest,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json",
stamp: "smoke",
});
assert.equal(request.runtimeId, "unity-scene");
assert.equal(request.providerId, "eve.world-smoke");
assert.equal(request.surfaceId, "eve.world-smoke.surface");
assert.equal(request.commandBoundary, "eve.world-smoke.commands");
assert.equal(request.receiptSchema, "eve.world_smoke.command_receipt.v1");
});

View file

@ -8,6 +8,8 @@ const unitySceneProjectionSchema = JSON.parse(readFileSync(new URL("../../schema
const aetheriaAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../runtimes/incubating/eve-unity-scene/eve-runtime-capability.json", import.meta.url), "utf8"));
const aetheriaSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria-world-surface.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke-surface.json", import.meta.url), "utf8"));
const saiAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/sai-vn.provider-advertisement.json", import.meta.url), "utf8"));
const saiSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/sai-vn-surface.json", import.meta.url), "utf8"));
@ -35,6 +37,25 @@ test("builds Unity scene projection capture artifact from provider advertisement
assert.equal(projection.root.children[1].children[0].sceneObjectKind, "world-projection-node");
});
test("builds Unity scene capture artifact for a generic world provider", () => {
const { projection } = buildUnitySceneCaptureArtifact({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
surfaceDocument: worldSmokeSurfaceDocument,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json",
stamp: "smoke",
});
assert.deepEqual(validateSchemaSubset(unitySceneProjectionSchema, projection), []);
assert.equal(projection.providerId, "eve.world-smoke");
assert.equal(projection.surfaceId, "eve.world-smoke.surface");
assert.equal(projection.commandBoundary, "eve.world-smoke.commands");
assert.equal(projection.receiptSchema, "eve.world_smoke.command_receipt.v1");
assert.equal(projection.root.id, "eve.world-smoke.root");
assert.equal(projection.root.children[1].sceneObjectKind, "world-projection-node");
});
test("marks Sai required and Norn TeX optional sidecar plugin projections", () => {
const advertisement = structuredClone(saiAdvertisement);
advertisement.surfaces[0].worldInteraction = {

View file

@ -8,6 +8,8 @@ const unityUiToolkitProjectionSchema = JSON.parse(readFileSync(new URL("../../sc
const aetheriaAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria.provider-advertisement.json", import.meta.url), "utf8"));
const capabilityManifest = JSON.parse(readFileSync(new URL("../../packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json", import.meta.url), "utf8"));
const aetheriaSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/aetheria-world-surface.json", import.meta.url), "utf8"));
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
const worldSmokeSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/eve-world-smoke-surface.json", import.meta.url), "utf8"));
const saiAdvertisement = JSON.parse(readFileSync(new URL("../../web/fixtures/sai-vn.provider-advertisement.json", import.meta.url), "utf8"));
const saiSurfaceDocument = JSON.parse(readFileSync(new URL("../../web/fixtures/sai-vn-surface.json", import.meta.url), "utf8"));
@ -36,6 +38,25 @@ test("builds Unity UI Toolkit projection capture artifact from provider advertis
assert.deepEqual(projection.root.classNames.slice(0, 2), ["eve-component", "eve-kind-surface"]);
});
test("builds Unity UI Toolkit capture artifact for a generic world provider", () => {
const { projection } = buildUnityUiToolkitCaptureArtifact({
advertisement: worldSmokeAdvertisement,
capabilityManifest,
surfaceDocument: worldSmokeSurfaceDocument,
advertisementPath: "web/fixtures/eve-world-smoke.provider-advertisement.json",
capabilityManifestPath: "packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json",
stamp: "smoke",
});
assert.deepEqual(validateSchemaSubset(unityUiToolkitProjectionSchema, projection), []);
assert.equal(projection.providerId, "eve.world-smoke");
assert.equal(projection.surfaceId, "eve.world-smoke.surface");
assert.equal(projection.commandBoundary, "eve.world-smoke.commands");
assert.equal(projection.receiptSchema, "eve.world_smoke.command_receipt.v1");
assert.equal(projection.root.id, "eve.world-smoke.root");
assert.equal(projection.root.children[1].visualElementKind, "VisualElement");
});
test("marks Sai required and Norn TeX optional sidecar plugin UI projections", () => {
const advertisement = structuredClone(saiAdvertisement);
advertisement.surfaces[0].worldInteraction = {

View file

@ -785,7 +785,7 @@
"manifestPath": "runtimes/incubating/eve-electron/eve-runtime-capability.json"
},
"splitHandoffPath": "runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"requiredFixtures": ["embedded-surface", "aetheria-world"],
"requiredFixtures": ["embedded-surface", "aetheria-world", "eve-world-smoke"],
"pluginFixtures": ["sai-vn"],
"supportedFeatures": ["providerAdvertisements", "commandTransport", "surfaceTreeProjection", "embeddedDocuments", "pluginProjection"],
"supportedPlugins": [
@ -814,7 +814,8 @@
"runtimes/incubating/eve-electron/src/eve-electron-shell.mjs",
"runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs",
"web/fixtures/sai-vn-surface.json",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -851,7 +852,7 @@
},
{
"path": "tools/eveelectron/eveelectron-capture-contract.test.mjs",
"contains": ["builds Electron shell capture request from provider advertisement", "rejects capture request when the surface does not advertise Electron shell", "electron-shell", "aetheria.daemon.commands"]
"contains": ["builds Electron shell capture request from provider advertisement", "builds Electron shell capture request from a declared generic world provider", "rejects capture request when the surface does not advertise Electron shell", "electron-shell", "aetheria.daemon.commands", "eve.world-smoke.commands"]
},
{
"path": "tools/eveelectron/eveelectron-capture-artifact.mjs",
@ -859,7 +860,7 @@
},
{
"path": "tools/eveelectron/eveelectron-capture-artifact.test.mjs",
"contains": ["builds Electron shell projection capture artifact", "gamecult.eve.electron_shell_projection.v1", "electron-shell-projection-json"]
"contains": ["builds Electron shell projection capture artifact", "builds Electron shell projection capture artifact from a generic world provider", "gamecult.eve.electron_shell_projection.v1", "electron-shell-projection-json", "eve.world-smoke.commands"]
},
{
"path": "tools/eveelectron/eveelectron-release-contract.mjs",
@ -883,6 +884,16 @@
"surfaceId": "aetheria.daemon.game",
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
"requestPath": "artifacts/eveelectron-capture/latest/capture-request.json"
},
{
"kind": "json-projection",
"schema": "gamecult.eve.electron_shell_projection.v1",
"path": "artifacts/eveelectron-capture/latest/eve-world-smoke-electron-shell-projection.json",
"runtimeId": "electron-shell",
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"sourceSurfacePath": "web/fixtures/eve-world-smoke-surface.json",
"requestPath": "artifacts/eveelectron-capture/latest/eve-world-smoke-capture-request.json"
}
]
}
@ -900,7 +911,7 @@
"manifestPath": "runtimes/incubating/eve-tui/eve-runtime-capability.json"
},
"splitHandoffPath": "runtimes/incubating/eve-tui/evetui-split-handoff.json",
"requiredFixtures": ["embedded-surface", "aetheria-world"],
"requiredFixtures": ["embedded-surface", "aetheria-world", "eve-world-smoke"],
"pluginFixtures": ["sai-vn"],
"supportedFeatures": ["providerAdvertisements", "commandTransport", "terminalGridSummary", "terminalGridLowering", "embeddedDocuments", "pluginProjection"],
"supportedPlugins": [
@ -930,7 +941,8 @@
"runtimes/incubating/eve-tui/src/eve-tui-shell.mjs",
"runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs",
"web/fixtures/sai-vn-surface.json",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -968,7 +980,7 @@
},
{
"path": "tools/evetui/evetui-capture-contract.test.mjs",
"contains": ["builds TUI capture request from provider advertisement", "rejects capture request when the surface does not advertise TUI", "artifacts/evetui-capture/smoke/tui-grid.json"]
"contains": ["builds TUI capture request from provider advertisement", "builds TUI capture request from a declared generic world provider", "rejects capture request when the surface does not advertise TUI", "artifacts/evetui-capture/smoke/tui-grid.json", "eve.world-smoke.commands"]
},
{
"path": "tools/evetui/evetui-capture-artifact.mjs",
@ -976,7 +988,7 @@
},
{
"path": "tools/evetui/evetui-capture-artifact.test.mjs",
"contains": ["builds TUI JSON grid capture artifact", "gamecult.eve.tui_grid.v1", "artifacts/evetui-capture/smoke/tui-grid.json"]
"contains": ["builds TUI JSON grid capture artifact", "builds TUI JSON grid capture artifact from a generic world provider", "gamecult.eve.tui_grid.v1", "artifacts/evetui-capture/smoke/tui-grid.json", "eve.world-smoke.commands"]
},
{
"path": "tools/evetui/evetui-release-contract.mjs",
@ -999,6 +1011,15 @@
"surfaceId": "aetheria.daemon.game",
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
"requestPath": "artifacts/evetui-capture/latest/capture-request.json"
},
{
"kind": "json-grid",
"schema": "gamecult.eve.tui_grid.v1",
"path": "artifacts/evetui-capture/latest/eve-world-smoke-tui-grid.json",
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"sourceSurfacePath": "web/fixtures/eve-world-smoke-surface.json",
"requestPath": "artifacts/evetui-capture/latest/eve-world-smoke-capture-request.json"
}
]
}
@ -1016,7 +1037,7 @@
"manifestPath": "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json"
},
"splitHandoffPath": "runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json",
"requiredFixtures": ["aetheria-world"],
"requiredFixtures": ["aetheria-world", "eve-world-smoke"],
"pluginFixtures": ["sai-vn"],
"supportedFeatures": ["providerAdvertisements", "commandTransport", "sceneGraphProjection", "embeddedDocuments"],
"supportedPlugins": [
@ -1050,7 +1071,8 @@
"runtimes/incubating/eve-unity-scene/Runtime/NornGraphUnitySceneProjectionAdapter.cs",
"runtimes/incubating/eve-unity-scene/Runtime/TeXMathUnitySceneProjectionAdapter.cs",
"runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -1100,7 +1122,7 @@
},
{
"path": "tools/eveunity/eveunity-capture-contract.test.mjs",
"contains": ["builds Unity scene capture request from provider advertisement", "unity-scene", "artifacts/eveunity-scene-capture/smoke/unity-scene.png"]
"contains": ["builds Unity scene capture request from provider advertisement", "builds Unity UI Toolkit capture request from a declared generic world provider", "builds Unity scene capture request from a declared generic world provider", "unity-scene", "artifacts/eveunity-scene-capture/smoke/unity-scene.png", "eve.world-smoke.commands"]
},
{
"path": "tools/eveunity/eveunity-scene-capture-artifact.mjs",
@ -1108,7 +1130,7 @@
},
{
"path": "tools/eveunity/eveunity-scene-capture-artifact.test.mjs",
"contains": ["builds Unity scene projection capture artifact", "marks Sai required and Norn TeX optional sidecar plugin projections", "gamecult.eve.unity_scene_projection.v1", "unity-scene-projection-json", "optional-nested"]
"contains": ["builds Unity scene projection capture artifact", "builds Unity scene capture artifact for a generic world provider", "marks Sai required and Norn TeX optional sidecar plugin projections", "gamecult.eve.unity_scene_projection.v1", "unity-scene-projection-json", "optional-nested", "eve.world-smoke.commands"]
},
{
"path": "tools/eveunity/eveunity-release-contract.test.mjs",
@ -1128,6 +1150,16 @@
"surfaceId": "aetheria.daemon.game",
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
"requestPath": "artifacts/eveunity-scene-capture/latest/capture-request.json"
},
{
"kind": "json-projection",
"schema": "gamecult.eve.unity_scene_projection.v1",
"path": "artifacts/eveunity-scene-capture/latest/eve-world-smoke-unity-scene-projection.json",
"runtimeId": "unity-scene",
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"sourceSurfacePath": "web/fixtures/eve-world-smoke-surface.json",
"requestPath": "artifacts/eveunity-scene-capture/latest/eve-world-smoke-capture-request.json"
}
]
}
@ -1521,7 +1553,7 @@
"schemaPath": "schemas/gamecult.eve.runtime_capability.v1.schema.json",
"manifestPath": "packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json"
},
"requiredFixtures": ["embedded-surface"],
"requiredFixtures": ["embedded-surface", "eve-world-smoke"],
"pluginFixtures": ["sai-vn"],
"supportedFeatures": ["embeddedDocuments"],
"supportedPlugins": [
@ -1549,7 +1581,8 @@
"evidencePaths": [
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs",
"packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs",
"web/fixtures/aetheria.provider-advertisement.json"
"web/fixtures/aetheria.provider-advertisement.json",
"web/fixtures/eve-world-smoke.provider-advertisement.json"
]
}
],
@ -1599,7 +1632,7 @@
},
{
"path": "tools/eveunity/eveunity-uitoolkit-capture-artifact.test.mjs",
"contains": ["builds Unity UI Toolkit projection capture artifact", "marks Sai required and Norn TeX optional sidecar plugin UI projections", "gamecult.eve.unity_uitoolkit_projection.v1", "unity-uitoolkit-projection-json", "optional-nested"]
"contains": ["builds Unity UI Toolkit projection capture artifact", "builds Unity UI Toolkit capture artifact for a generic world provider", "marks Sai required and Norn TeX optional sidecar plugin UI projections", "gamecult.eve.unity_uitoolkit_projection.v1", "unity-uitoolkit-projection-json", "optional-nested", "eve.world-smoke.commands"]
}
],
"commandTransportSmoke": {
@ -1751,6 +1784,13 @@
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"additionalProviderSurfaces": [
{
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"purpose": "Generic non-product interactive-world capture control."
}
],
"authority": "Capture observes runtime projection only; provider state, command acceptance, and receipts stay provider-owned.",
"publishProof": "Unity editor or batchmode capture artifact is attached to the runtime conformance report from EveUnity."
},
@ -1781,6 +1821,16 @@
"surfaceId": "aetheria.daemon.game",
"sourceSurfacePath": "web/fixtures/aetheria-world-surface.json",
"requestPath": "artifacts/eveunity-uitoolkit-capture/latest/capture-request.json"
},
{
"kind": "json-projection",
"schema": "gamecult.eve.unity_uitoolkit_projection.v1",
"path": "artifacts/eveunity-uitoolkit-capture/latest/eve-world-smoke-unity-uitoolkit-projection.json",
"runtimeId": "unity-uitoolkit",
"providerId": "eve.world-smoke",
"surfaceId": "eve.world-smoke.surface",
"sourceSurfacePath": "web/fixtures/eve-world-smoke-surface.json",
"requestPath": "artifacts/eveunity-uitoolkit-capture/latest/eve-world-smoke-capture-request.json"
}
]
}

View file

@ -1540,9 +1540,19 @@ function compareCaptureContract(expected, actual, label) {
if (actual.requestSchema && !manifest.schemas?.[actual.requestSchema]) {
errors.push(`${label}.requestSchema:${actual.requestSchema}:missing-schema-catalog-entry`);
}
const expectedAdditionalSurfaces = captureSurfaceClaimKeys(expected.additionalProviderSurfaces || []);
const actualAdditionalSurfaces = captureSurfaceClaimKeys(actual.additionalProviderSurfaces || []);
errors.push(...missingMembers(expectedAdditionalSurfaces, actualAdditionalSurfaces, `${label}.additionalProviderSurfaces`));
return errors;
}
function captureSurfaceClaimKeys(claims) {
return (Array.isArray(claims) ? claims : [])
.filter(claim => claim && typeof claim === "object")
.map(claim => `${claim.providerId || ""}:${claim.surfaceId || ""}`)
.filter(claim => claim !== ":");
}
function compareTestContract(expected, actual, label) {
const errors = [];
if (!expected) return errors;
@ -2660,6 +2670,7 @@ function buildRuntimeCaptureProbeRecord(runtime) {
conformanceAttachment: contract.conformanceAttachment || "",
requiredProvider: contract.requiredProvider || "",
requiredSurface: contract.requiredSurface || "",
additionalProviderSurfaces: contract.additionalProviderSurfaces || [],
authority: contract.authority || "",
currentArtifactKind,
currentArtifactSchema: artifact.schema || "",