From 2355032c567aaf4bd0006898ad800b90350a70a2 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 10 Jul 2026 08:02:04 +0100 Subject: [PATCH] Attach native EveElectron capture witnesses --- docs/eve-migration-roadmap.md | 14 ++++++-- docs/parity-testing-harness.md | 6 ++-- ...amecult.eve.runtime_witness.v1.schema.json | 4 +-- ...un-aetheria-conformance-consumer-smoke.ps1 | 4 +-- scripts/run-conformance-consumer-smoke.ps1 | 4 ++- scripts/run-eveelectron-owner-smoke.ps1 | 2 ++ scripts/run-parity-harness.ps1 | 6 ++++ ...ntime-owner-conformance-consumer-smoke.ps1 | 15 +++++---- ...plit-target-conformance-consumer-smoke.ps1 | 3 +- tools/conformance/attach-runtime-witness.mjs | 2 +- tools/parity/parity-manifest.json | 33 +++++++++++++++---- tools/parity/run-parity.mjs | 3 +- 12 files changed, 68 insertions(+), 28 deletions(-) diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 7d35b65..4add64c 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -285,11 +285,21 @@ Exit criteria: ## Active Work Queue -1. Produce owner-repo Electron window captures for the generic world fixture - and Aetheria, then attach them to conformance from EveElectron. +1. Audit the migration against the target ownership rule and remove any + remaining runtime, plugin-semantic, or provider-product authority from Eve. Recently cut: +- EveElectron now produces native offscreen-painted 1280x800 PNG captures for + both `eve.world-smoke.surface` and `aetheria.daemon.game`. The owner runner + emits generic runtime witnesses with dimensions, byte counts, SHA-256 hashes, + provider/surface assertions, and runtime-owned authority. Eve's parity + harness regenerates the captures, attaches both witnesses to conformance, + and downstream consumers require them. The generic runtime-witness contract + no longer requires Unity-specific movement, targeting, action, or receipt + fields; those remain valid profile assertions when a gameplay witness has + them. EveElectron is now reported as graduated rather than "ready to split." + - `GameCult/EveElectron` now owns the generic Electron runtime package. Its shell lowers provider-advertised surfaces and command intents; its window host owns secure `BrowserWindow` construction and controls; its preload diff --git a/docs/parity-testing-harness.md b/docs/parity-testing-harness.md index 97bffe5..3406bab 100644 --- a/docs/parity-testing-harness.md +++ b/docs/parity-testing-harness.md @@ -476,9 +476,9 @@ artifact. Electron runtime evidence is consumed from the `EveElectron` owner repo. Eve core no longer manufactures a JSON shell projection and presents it as -runtime capture evidence. Until EveElectron attaches real window PNGs for a -generic provider and Aetheria, the capture contract reports -`contract-artifact-missing` and remains visibly pending. +runtime capture evidence. EveElectron produces native offscreen-painted PNGs +for the generic world fixture and Aetheria, emits hashed runtime witnesses, and +the parity harness attaches both witnesses to the conformance export. Unity scene runtime evidence is now consumed from the `EveUnity` owner repo through the parity runtime's `sourceRoot`. Eve does not generate a substitute diff --git a/schemas/gamecult.eve.runtime_witness.v1.schema.json b/schemas/gamecult.eve.runtime_witness.v1.schema.json index 275927c..27de6d4 100644 --- a/schemas/gamecult.eve.runtime_witness.v1.schema.json +++ b/schemas/gamecult.eve.runtime_witness.v1.schema.json @@ -6,7 +6,7 @@ "required": [ "schema", "witnessId", "runtimeId", "runtimeOwnerRepo", "providerId", "surfaceId", "projectionKind", "status", "generatedAtUtc", "execution", - "assertions", "receipts", "screenshotMetrics", "artifacts", "authority" + "assertions", "screenshotMetrics", "artifacts", "authority" ], "properties": { "schema": { "const": "gamecult.eve.runtime_witness.v1" }, @@ -30,7 +30,6 @@ }, "assertions": { "type": "object", - "required": ["providerAdvertisement", "providerAssets", "movement", "targeting", "action", "initialVersion", "finalVersion"], "properties": { "providerAdvertisement": { "type": "boolean" }, "providerAssets": { "type": "boolean" }, @@ -45,7 +44,6 @@ }, "receipts": { "type": "array", - "minItems": 1, "items": { "type": "object", "required": ["commandKind", "commandId", "state", "sourceVersion"], diff --git a/scripts/run-aetheria-conformance-consumer-smoke.ps1 b/scripts/run-aetheria-conformance-consumer-smoke.ps1 index bc4eb36..157ac6d 100644 --- a/scripts/run-aetheria-conformance-consumer-smoke.ps1 +++ b/scripts/run-aetheria-conformance-consumer-smoke.ps1 @@ -82,13 +82,13 @@ try { --expect-command-boundary-coverage aetheria:aetheria.daemon.editor:tui:covered:EveTui:tui ` --expect-split-target-proof "EveUnity:Aetheria daemon 3D ARPG world lowers through a generic EveUnity playable-world client" ` --expect-runtime-capture-artifact unity-uitoolkit:json-projection:gamecult.eve.unity_uitoolkit_projection.v1:aetheria:aetheria.daemon.game ` - --expect-runtime-capture-probe electron-shell:contract-artifact-missing:png:EveElectron ` + --expect-runtime-capture-probe electron-shell:contract-artifact-present:png:EveElectron ` + --expect-runtime-witness electron-shell:aetheria:aetheria.daemon.game:cold:pass ` --expect-runtime-capture-artifact tui:json-grid:gamecult.eve.tui_grid.v1:aetheria:aetheria.daemon.game ` --expect-split-handoff-move EveTui:tui:tui-runtime-body:current:exists:eve-tui-shell.mjs ` --expect-split-handoff-move EveTui:tui:tui-world-surface-lowering:current:exists:eve-tui-shell.mjs ` --expect-split-handoff-move EveTui:tui:tui-command-transport:current:exists:eve-tui-shell.mjs ` --expect-split-target-proof "EveElectron:Aetheria consumes EveElectron for generic window and preload authority" ` - --expect-split-target-blocker "EveElectron:Electron packaged window PNG capture artifacts are attached to conformance output" ` --expect-split-target-blocker "EveTui:TUI package release is cut from EveTui rather than Eve incubation" ` --expect-split-target-blocker "EveTui:TUI capture path is owned by EveTui rather than Eve incubation" ` --expect-split-handoff-move EveUnity:unity-uitoolkit:aetheria-unity-consumer-boundary:observed-provider:exists:Packages/manifest.json ` diff --git a/scripts/run-conformance-consumer-smoke.ps1 b/scripts/run-conformance-consumer-smoke.ps1 index 1c18be3..9d0ab3a 100644 --- a/scripts/run-conformance-consumer-smoke.ps1 +++ b/scripts/run-conformance-consumer-smoke.ps1 @@ -102,7 +102,9 @@ try { --expect-screenshot-metric electron-shell:aetheria-world:bounding-boxes:pending-capture ` --expect-runtime-capture-probe unity-uitoolkit:semantic-artifact-present-capture-pending:png:EveUnity ` --expect-runtime-capture-probe unity-scene:control-artifact-present-product-capture-pending:png:EveUnity ` - --expect-runtime-capture-probe electron-shell:contract-artifact-missing:png:EveElectron ` + --expect-runtime-capture-probe electron-shell:contract-artifact-present:png:EveElectron ` + --expect-runtime-witness electron-shell:eve.world-smoke:eve.world-smoke.surface:cold:pass ` + --expect-runtime-witness electron-shell:aetheria:aetheria.daemon.game:cold:pass ` --expect-runtime-capture-probe tui:contract-artifact-present:json-grid:EveTui ` --expect-capability-gap "split-target:EveUnity:EveUnity:proof:Tagged UPM release" ` --expect-conformance-handoff diff --git a/scripts/run-eveelectron-owner-smoke.ps1 b/scripts/run-eveelectron-owner-smoke.ps1 index 274d620..54e3252 100644 --- a/scripts/run-eveelectron-owner-smoke.ps1 +++ b/scripts/run-eveelectron-owner-smoke.ps1 @@ -43,6 +43,8 @@ try { if ($LASTEXITCODE -ne 0) { throw "EveElectron owner tests failed with exit code $LASTEXITCODE" } npm pack --dry-run | Out-Null if ($LASTEXITCODE -ne 0) { throw "EveElectron owner package smoke failed with exit code $LASTEXITCODE" } + powershell -ExecutionPolicy Bypass -File scripts/capture-conformance.ps1 -EveRoot $projectRoot + if ($LASTEXITCODE -ne 0) { throw "EveElectron owner capture smoke failed with exit code $LASTEXITCODE" } } finally { Pop-Location } diff --git a/scripts/run-parity-harness.ps1 b/scripts/run-parity-harness.ps1 index 7103185..0eff372 100644 --- a/scripts/run-parity-harness.ps1 +++ b/scripts/run-parity-harness.ps1 @@ -47,6 +47,12 @@ try { -ExpectedCommandBoundary "eve.world-smoke.commands" ` -ExpectedReceiptSchema "eve.world_smoke.command_receipt.v1" node .\tools\parity\run-parity.mjs + node .\tools\conformance\attach-runtime-witness.mjs ` + "E:\Projects\EveElectron\artifacts\capture\generic-world\runtime-witness.json" ` + ".\artifacts\conformance\latest" + node .\tools\conformance\attach-runtime-witness.mjs ` + "E:\Projects\EveElectron\artifacts\capture\aetheria-world\runtime-witness.json" ` + ".\artifacts\conformance\latest" & (Join-Path $PSScriptRoot "run-eveconformance-handoff-smoke.ps1") & (Join-Path $PSScriptRoot "run-plugin-handoff-smoke.ps1") & (Join-Path $PSScriptRoot "run-aetheria-provider-handoff-smoke.ps1") diff --git a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 index 39b96e1..c25b491 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -165,14 +165,18 @@ node $consumerScript $consumerExport ` --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:partial-world-smoke-playmode-capture ` - --expect-runtime-capture-status electron-shell:pending-owner-window-capture ` + --expect-runtime-capture-status electron-shell:owner-window-png ` + --expect-runtime-capture-artifact electron-shell:png:image/png:eve.world-smoke:eve.world-smoke.surface ` + --expect-runtime-capture-artifact electron-shell:png:image/png:aetheria:aetheria.daemon.game ` --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:control-artifact-present-product-capture-pending:png:EveUnity ` - --expect-runtime-capture-probe electron-shell:contract-artifact-missing:png:EveElectron ` + --expect-runtime-capture-probe electron-shell:contract-artifact-present:png:EveElectron ` + --expect-runtime-witness electron-shell:eve.world-smoke:eve.world-smoke.surface:cold:pass ` + --expect-runtime-witness electron-shell:aetheria:aetheria.daemon.game:cold:pass ` --expect-runtime-capture-probe tui:contract-artifact-present:json-grid:EveTui ` --expect-screenshot-metric web:embedded-surface:structure:pass ` --expect-screenshot-metric web:embedded-surface:color-tokens:pass ` @@ -263,8 +267,7 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "unity-scene:capture:captureContract.additionalProviderSurfaces.0.surfaceId:eve.world-smoke.surface" ` --expect-runtime-lifecycle-status electron-shell:release:owner-npm-package ` --expect-runtime-lifecycle-status electron-shell:test:owner-package-tests-and-aetheria-live-smoke ` - --expect-runtime-lifecycle-status electron-shell:capture:pending-owner-window-capture ` - --expect-runtime-lifecycle-pending "electron-shell:capture:Capture one non-product and one Aetheria window" ` + --expect-runtime-lifecycle-status electron-shell:capture:owner-window-captures ` --expect-runtime-lifecycle-field "electron-shell:release:releaseContract.artifactKind:npm-package" ` --expect-runtime-lifecycle-field "electron-shell:release:releaseContract.versionSource:package.json" ` --expect-runtime-lifecycle-field "electron-shell:release:releaseContract.requestSchema:gamecult.eve.runtime_release_request.v1" ` @@ -275,9 +278,9 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.captureKind:electron-window-png" ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.targetId:electron-shell" ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requestSchema:gamecult.eve.runtime_capture_request.v1" ` - --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requestBuilder:pending" ` + --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requestBuilder:scripts/capture-conformance.ps1" ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.advertisementPath:provider-supplied" ` - --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requiredSurface:aetheria.game" ` + --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 ` diff --git a/scripts/run-split-target-conformance-consumer-smoke.ps1 b/scripts/run-split-target-conformance-consumer-smoke.ps1 index 824bc16..64a2df2 100644 --- a/scripts/run-split-target-conformance-consumer-smoke.ps1 +++ b/scripts/run-split-target-conformance-consumer-smoke.ps1 @@ -51,10 +51,9 @@ try { --expect-split-handoff-move EveUnity:unity-uitoolkit:aetheria-unity-consumer-boundary:observed-provider:exists:Aetheria.State.Unity/AetheriaRuntimeCatalogClient.cs ` --expect-split-target-blocker "EveUnity:Tagged UPM release" ` --expect-split-target EveElectron ` - --expect-split-target-status EveElectron:incubating ` + --expect-split-target-status EveElectron:graduated ` --expect-split-target-proof "EveElectron:EveElectron owner repository publishes the generic runtime package" ` --expect-split-target-proof "EveElectron:EveElectron owns secure window and preload lifecycle" ` - --expect-split-target-blocker "EveElectron:Electron packaged window PNG capture artifacts are attached to conformance output" ` --expect-split-target EveTui ` --expect-split-target-status EveTui:incubating ` --expect-split-target-proof "EveTui:EveTui split handoff is machine-readable" ` diff --git a/tools/conformance/attach-runtime-witness.mjs b/tools/conformance/attach-runtime-witness.mjs index 3670df5..c42adad 100644 --- a/tools/conformance/attach-runtime-witness.mjs +++ b/tools/conformance/attach-runtime-witness.mjs @@ -64,7 +64,7 @@ function validateWitness(value) { if (value.schema !== "gamecult.eve.runtime_witness.v1") throw new Error(`Unexpected runtime witness schema: ${value.schema || ""}`); if (!value.execution?.cacheState || !Number.isFinite(value.execution?.durationMs)) throw new Error("Runtime witness execution is incomplete."); if (!value.assertions || typeof value.assertions !== "object") throw new Error("Runtime witness assertions are missing."); - if (!Array.isArray(value.receipts) || !value.receipts.length) throw new Error("Runtime witness receipts are missing."); + if (value.receipts !== undefined && !Array.isArray(value.receipts)) throw new Error("Runtime witness receipts must be an array when present."); if (!Array.isArray(value.artifacts) || !value.artifacts.length) throw new Error("Runtime witness artifacts are missing."); for (const artifact of value.artifacts) { if (!artifact.path || !/^[a-f0-9]{64}$/i.test(artifact.sha256 || "") || !(artifact.sizeBytes > 0)) { diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index cea0b92..7dc60d3 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -658,7 +658,7 @@ "id": "EveElectron", "ownerRepo": "EveElectron", "repoRole": "runtime-target", - "status": "graduated-runtime-capture-pending", + "status": "graduated", "runtimes": ["electron-shell"], "requiredRuntimeStatuses": ["active"], "requiredFeatures": ["providerAdvertisements", "surfaceTreeProjection", "embeddedDocuments"], @@ -694,9 +694,7 @@ ] } ], - "pendingProofs": [ - "Electron packaged window PNG capture artifacts are attached to conformance output." - ] + "pendingProofs": [] }, { "id": "EveTui", @@ -824,9 +822,30 @@ } ], "capture": { - "status": "pending-owner-window-capture", - "note": "EveElectron owns capture production; Eve core no longer manufactures runtime projection artifacts on its behalf.", - "artifacts": [] + "status": "owner-window-png", + "note": "EveElectron owns native window PNG production for the generic and Aetheria provider surfaces.", + "artifacts": [ + { + "kind": "png", + "schema": "image/png", + "path": "artifacts/capture/generic-world/window.png", + "runtimeId": "electron-shell", + "providerId": "eve.world-smoke", + "surfaceId": "eve.world-smoke.surface", + "sourceSurfacePath": "../Eve/web/fixtures/eve-world-smoke-surface.json", + "requestPath": "artifacts/capture/generic-world/runtime-witness.json" + }, + { + "kind": "png", + "schema": "image/png", + "path": "artifacts/capture/aetheria-world/window.png", + "runtimeId": "electron-shell", + "providerId": "aetheria", + "surfaceId": "aetheria.daemon.game", + "sourceSurfacePath": "../Eve/web/fixtures/aetheria-world-surface.json", + "requestPath": "artifacts/capture/aetheria-world/runtime-witness.json" + } + ] } }, { diff --git a/tools/parity/run-parity.mjs b/tools/parity/run-parity.mjs index e691535..c8966bf 100644 --- a/tools/parity/run-parity.mjs +++ b/tools/parity/run-parity.mjs @@ -1856,7 +1856,7 @@ function evaluateSplitTargets(splitTargets, runtimeResults) { id: target.id, ownerRepo: target.ownerRepo || "", repoRole: target.repoRole || "", - status: blockers.length ? "incubating" : "ready-to-split", + status: blockers.length ? "incubating" : target.status === "graduated" ? "graduated" : "ready-to-split", declaredStatus: target.status || "", runtimes: runtimeIds, runtimeStatuses, @@ -2014,6 +2014,7 @@ function summarize(fixtures, runtimes, plugins, providers, splitTargets) { pendingRuntimes: runtimes.filter(runtime => runtime.status !== "active").length, totalSplitTargets: splitTargets.length, readySplitTargets: splitTargets.filter(target => target.status === "ready-to-split").length, + graduatedSplitTargets: splitTargets.filter(target => target.status === "graduated").length, }; }