Type EveElectron pending lifecycle

This commit is contained in:
Meta Vens 2026-07-09 10:01:42 +01:00
commit ced282f8b6
9 changed files with 364 additions and 3 deletions

View file

@ -387,6 +387,13 @@ Recently cut:
observed Aetheria Electron/client paths that must be replaced, the required
Eve contract inputs, and the pending external proofs without treating
Aetheria's product client as the generic Electron runtime.
- EveElectron now has a pending runtime capability manifest at
`runtimes/incubating/eve-electron/eve-runtime-capability.json` and a
lifecycle smoke at `scripts/run-eveelectron-lifecycle-smoke.ps1`. The
manifest declares no supported runtime features or plugin projection yet; it
only types the pending command boundary, package release, provider-shell
smoke, and Electron window capture contracts so EveElectron can consume the
conformance export without pretending the generic shell already exists.
- EveTui now has a pending split target and handoff at
`runtimes/incubating/eve-tui/evetui-split-handoff.json`. It does not claim
the advertised `tui` world-surface lowering target yet. The handoff draws the

View file

@ -0,0 +1,108 @@
{
"schema": "gamecult.eve.runtime_capability.v1",
"runtimeId": "electron-shell",
"title": "Electron shell",
"owner": "EveElectron",
"incubation": {
"ownerRepo": "EveElectron",
"currentHostRepo": "Eve",
"splitTarget": "EveElectron",
"graduationTrigger": "Split when Electron has a provider-agnostic shell body, provider advertisement consumption, command transport, packaged app lifecycle, and capture evidence independent of Aetheria product code.",
"splitHandoff": {
"manifestPath": "runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"smokeCommand": "powershell -ExecutionPolicy Bypass -File .\\scripts\\run-eveelectron-split-handoff-smoke.ps1"
}
},
"supportedFeatures": [],
"supportedPlugins": [],
"unsupportedPlugins": [
{
"pluginId": "sai.vn",
"reason": "Electron has no generic runtime body yet; Sai projection belongs behind provider/plugin advertisements once EveElectron exists."
},
{
"pluginId": "norn.graph",
"reason": "Electron has no generic runtime body yet; Norn graph projection belongs behind provider/plugin advertisements once EveElectron exists."
},
{
"pluginId": "tex.math",
"reason": "Electron has no generic runtime body yet; TeX projection belongs behind provider/plugin advertisements once EveElectron exists."
}
],
"commandTransport": {
"schema": "gamecult.eve.command.v1",
"status": "pending-runtime-body",
"emitter": "EveElectronShell.EmitCommand",
"clientId": "electron-shell",
"authority": "Electron emits command intents through provider-advertised command boundaries; providers accept, deny, and publish receipts."
},
"lifecycle": {
"release": {
"ownerRepo": "EveElectron",
"status": "pending-electron-package",
"releaseContract": {
"ownerRepo": "EveElectron",
"packageName": "eve-electron",
"packageRoot": "runtimes/incubating/eve-electron",
"versionSource": "runtimes/incubating/eve-electron/eve-runtime-capability.json",
"tagPattern": "eveelectron-v{version}",
"artifactKind": "electron-app",
"publishProof": "Packaged Electron release is created from the EveElectron repo and references the provider-agnostic shell package root."
},
"evidencePaths": [
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"scripts/run-eveelectron-split-handoff-smoke.ps1"
],
"pendingProofs": [
"Electron packaged app release is cut from EveElectron rather than Eve incubation."
]
},
"test": {
"ownerRepo": "EveElectron",
"status": "pending-provider-advertisement-shell-smoke",
"testContract": {
"ownerRepo": "EveElectron",
"runnerKind": "electron-provider-shell-smoke",
"runnerScript": "scripts/run-eveelectron-provider-shell-smoke.ps1",
"consumerProject": "E:\\Projects\\Aetheria",
"packageName": "eve-electron",
"testAssembly": "EveElectron.ProviderShell",
"testPlatform": "Electron",
"resultsArtifact": "artifacts/eveelectron-provider-shell/{stamp}/provider-shell-results.json",
"logArtifact": "artifacts/eveelectron-provider-shell/{stamp}/provider-shell.log",
"manifestMutation": "None; the shell consumes provider advertisements and must not mutate provider product manifests."
},
"evidencePaths": [
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"scripts/run-eveelectron-split-handoff-smoke.ps1"
],
"pendingProofs": [
"Electron provider-advertisement shell smoke runs from EveElectron without importing Aetheria source layout."
]
},
"capture": {
"ownerRepo": "EveElectron",
"status": "pending-electron-window-capture",
"captureContract": {
"ownerRepo": "EveElectron",
"runtimeId": "electron-shell",
"captureKind": "electron-window-png",
"artifactKind": "png",
"artifactPattern": "artifacts/eveelectron-capture/{stamp}/electron-shell.png",
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"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."
},
"evidencePaths": [],
"pendingProofs": [
"Electron window capture artifact is attached to the runtime conformance report."
]
}
},
"capture": {
"status": "missing",
"note": "Electron capture is a split blocker until EveElectron owns a provider-agnostic shell."
}
}

View file

@ -286,7 +286,6 @@
"runnerKind",
"runnerScript",
"consumerProject",
"unityExeDefault",
"packageName",
"testAssembly",
"testPlatform",

View file

@ -0,0 +1,123 @@
param(
[string] $CapabilityManifestPath = "runtimes\incubating\eve-electron\eve-runtime-capability.json"
)
$ErrorActionPreference = "Stop"
$projectRoot = Split-Path -Parent $PSScriptRoot
$absoluteManifestPath = if ([System.IO.Path]::IsPathRooted($CapabilityManifestPath)) {
$CapabilityManifestPath
} else {
Join-Path $projectRoot $CapabilityManifestPath
}
if (-not (Test-Path -LiteralPath $absoluteManifestPath)) {
throw "EveElectron runtime capability manifest not found: $absoluteManifestPath"
}
$manifest = Get-Content -LiteralPath $absoluteManifestPath -Raw | ConvertFrom-Json
if ($manifest.schema -ne "gamecult.eve.runtime_capability.v1") {
throw "Unexpected EveElectron manifest schema: $($manifest.schema)"
}
if ($manifest.runtimeId -ne "electron-shell") {
throw "Unexpected EveElectron runtime id: $($manifest.runtimeId)"
}
if ($manifest.owner -ne "EveElectron") {
throw "Unexpected EveElectron owner: $($manifest.owner)"
}
if ($manifest.incubation.ownerRepo -ne "EveElectron") {
throw "Unexpected EveElectron incubation owner: $($manifest.incubation.ownerRepo)"
}
if ($manifest.incubation.currentHostRepo -ne "Eve") {
throw "Unexpected EveElectron current host repo: $($manifest.incubation.currentHostRepo)"
}
if ($manifest.incubation.splitTarget -ne "EveElectron") {
throw "Unexpected EveElectron split target: $($manifest.incubation.splitTarget)"
}
if (-not $manifest.incubation.splitHandoff.manifestPath) {
throw "EveElectron manifest missing split handoff path"
}
if (@($manifest.supportedFeatures).Count -ne 0) {
throw "EveElectron must not claim supported runtime features before the generic shell body exists"
}
if (@($manifest.supportedPlugins).Count -ne 0) {
throw "EveElectron must not claim plugin projection before the generic shell body exists"
}
foreach ($pluginId in @("sai.vn", "norn.graph", "tex.math")) {
$unsupported = @($manifest.unsupportedPlugins) | Where-Object { $_.pluginId -eq $pluginId } | Select-Object -First 1
if (-not $unsupported) {
throw "EveElectron manifest missing unsupported plugin declaration: $pluginId"
}
}
if ($manifest.commandTransport.schema -ne "gamecult.eve.command.v1") {
throw "Unexpected EveElectron command schema: $($manifest.commandTransport.schema)"
}
if ($manifest.commandTransport.status -ne "pending-runtime-body") {
throw "Unexpected EveElectron command transport status: $($manifest.commandTransport.status)"
}
foreach ($stage in @("release", "test", "capture")) {
$stageDocument = $manifest.lifecycle.$stage
if ($null -eq $stageDocument) {
throw "EveElectron lifecycle missing stage: $stage"
}
if ($stageDocument.ownerRepo -ne "EveElectron") {
throw "EveElectron lifecycle stage $stage has unexpected owner: $($stageDocument.ownerRepo)"
}
if (-not $stageDocument.status) {
throw "EveElectron lifecycle stage $stage missing status"
}
foreach ($evidencePath in @($stageDocument.evidencePaths)) {
$absoluteEvidencePath = Join-Path $projectRoot $evidencePath
if (-not (Test-Path -LiteralPath $absoluteEvidencePath)) {
throw "EveElectron lifecycle stage $stage missing evidence path: $evidencePath"
}
}
}
$releaseContract = $manifest.lifecycle.release.releaseContract
foreach ($field in @("ownerRepo", "packageName", "packageRoot", "versionSource", "tagPattern", "artifactKind", "publishProof")) {
if (-not $releaseContract.$field) {
throw "EveElectron release contract missing $field"
}
}
foreach ($pathProperty in @("packageRoot", "versionSource")) {
$relativePath = $releaseContract.$pathProperty
$absolutePath = Join-Path $projectRoot $relativePath
if (-not (Test-Path -LiteralPath $absolutePath)) {
throw "EveElectron release contract $pathProperty does not exist: $relativePath"
}
}
$testContract = $manifest.lifecycle.test.testContract
foreach ($field in @("ownerRepo", "runnerKind", "runnerScript", "consumerProject", "packageName", "testAssembly", "testPlatform", "resultsArtifact", "logArtifact", "manifestMutation")) {
if (-not $testContract.$field) {
throw "EveElectron test contract missing $field"
}
}
foreach ($pathProperty in @("runnerScript", "consumerProject")) {
$candidate = $testContract.$pathProperty
$absolutePath = if ([System.IO.Path]::IsPathRooted($candidate)) {
$candidate
} else {
Join-Path $projectRoot $candidate
}
if (-not (Test-Path -LiteralPath $absolutePath)) {
throw "EveElectron test contract $pathProperty does not exist: $candidate"
}
}
$captureContract = $manifest.lifecycle.capture.captureContract
foreach ($field in @("ownerRepo", "runtimeId", "captureKind", "artifactKind", "artifactPattern", "conformanceAttachment", "requiredProvider", "requiredSurface", "authority", "publishProof")) {
if (-not $captureContract.$field) {
throw "EveElectron capture contract missing $field"
}
}
& (Join-Path $projectRoot "scripts\run-eveelectron-split-handoff-smoke.ps1")
Write-Host "EveElectron lifecycle smoke passed: $absoluteManifestPath"

View file

@ -0,0 +1,27 @@
param(
[string] $CapabilityManifestPath = "runtimes\incubating\eve-electron\eve-runtime-capability.json"
)
$ErrorActionPreference = "Stop"
$projectRoot = Split-Path -Parent $PSScriptRoot
$absoluteManifestPath = if ([System.IO.Path]::IsPathRooted($CapabilityManifestPath)) {
$CapabilityManifestPath
} else {
Join-Path $projectRoot $CapabilityManifestPath
}
if (-not (Test-Path -LiteralPath $absoluteManifestPath)) {
throw "EveElectron runtime capability manifest not found: $absoluteManifestPath"
}
$manifest = Get-Content -LiteralPath $absoluteManifestPath -Raw | ConvertFrom-Json
if ($manifest.runtimeId -ne "electron-shell") {
throw "Unexpected EveElectron runtime id: $($manifest.runtimeId)"
}
if ($manifest.lifecycle.test.status -ne "pending-provider-advertisement-shell-smoke") {
throw "EveElectron provider shell smoke should remain pending until a generic shell body exists: $($manifest.lifecycle.test.status)"
}
throw "EveElectron provider shell smoke is a pending contract, not a runnable proof, until EveElectron owns the provider-agnostic Electron shell body."

View file

@ -20,6 +20,7 @@ try {
& (Join-Path $PSScriptRoot "run-eveunity-split-handoff-smoke.ps1")
& (Join-Path $PSScriptRoot "run-eveunity-scene-split-handoff-smoke.ps1")
& (Join-Path $PSScriptRoot "run-eveelectron-split-handoff-smoke.ps1")
& (Join-Path $PSScriptRoot "run-eveelectron-lifecycle-smoke.ps1")
& (Join-Path $PSScriptRoot "run-conformance-consumer-smoke.ps1")
& (Join-Path $PSScriptRoot "run-plugin-owner-conformance-consumer-smoke.ps1")
& (Join-Path $PSScriptRoot "run-runtime-owner-conformance-consumer-smoke.ps1")

View file

@ -37,12 +37,14 @@ node $consumerScript $consumerExport `
--expect-runtime linux-flutter `
--expect-runtime android-flutter `
--expect-runtime unity-uitoolkit `
--expect-runtime electron-shell `
--expect-runtime direct2d `
--expect-runtime-status web:active `
--expect-runtime-status windows-flutter:active `
--expect-runtime-status linux-flutter:active `
--expect-runtime-status android-flutter:active `
--expect-runtime-status unity-uitoolkit:active `
--expect-runtime-status electron-shell:pending `
--expect-runtime-status direct2d:external-adapter-spike `
--expect-runtime-feature web:providerAdvertisements `
--expect-runtime-feature windows-flutter:embeddedDocuments `
@ -80,6 +82,7 @@ node $consumerScript $consumerExport `
--expect-runtime-capture-status linux-flutter:ssh-golden `
--expect-runtime-capture-status android-flutter:adb-png `
--expect-runtime-capture-status unity-uitoolkit:semantic `
--expect-runtime-capture-status electron-shell:missing `
--expect-runtime-capture-status direct2d:missing `
--expect-runtime-lifecycle-status unity-uitoolkit:release:incubating-upm-package `
--expect-runtime-lifecycle-status unity-uitoolkit:test:batchmode-editmode-tests-and-consumer-build-smoke `
@ -100,7 +103,18 @@ node $consumerScript $consumerExport `
--expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.artifactKind:png" `
--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.requiredSurface:aetheria.daemon.game" `
--expect-runtime-lifecycle-status electron-shell:release:pending-electron-package `
--expect-runtime-lifecycle-status electron-shell:test:pending-provider-advertisement-shell-smoke `
--expect-runtime-lifecycle-status electron-shell:capture:pending-electron-window-capture `
--expect-runtime-lifecycle-pending "electron-shell:release:Electron packaged app release" `
--expect-runtime-lifecycle-pending "electron-shell:test:Electron provider-advertisement shell smoke" `
--expect-runtime-lifecycle-pending "electron-shell:capture:Electron window capture artifact" `
--expect-runtime-lifecycle-field "electron-shell:release:releaseContract.artifactKind:electron-app" `
--expect-runtime-lifecycle-field "electron-shell:test:testContract.runnerKind:electron-provider-shell-smoke" `
--expect-runtime-lifecycle-field "electron-shell:test:testContract.runnerScript:scripts/run-eveelectron-provider-shell-smoke.ps1" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.captureKind:electron-window-png" `
--expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requiredSurface:aetheria.daemon.game"
if ($LASTEXITCODE -ne 0) {
throw "Runtime owner conformance consumer smoke failed with exit code $LASTEXITCODE"

View file

@ -55,6 +55,7 @@ try {
--expect-split-target EveElectron `
--expect-split-target-status EveElectron:incubating `
--expect-split-target-proof "EveElectron:EveElectron split handoff is machine-readable" `
--expect-split-target-proof "EveElectron:EveElectron lifecycle contract is machine-readable" `
--expect-split-target-blocker "EveElectron:runtime:electron-shell:status:pending" `
--expect-split-target-blocker-record EveElectron:runtime-status:electron-shell `
--expect-split-target-blocker-record EveElectron:runtime-feature:electron-shell:providerAdvertisements `

View file

@ -610,6 +610,15 @@
"docs/eve-migration-roadmap.md",
"docs/parity-testing-harness.md"
]
},
{
"description": "EveElectron lifecycle contract is machine-readable and smoke-checked.",
"status": "passed",
"evidencePaths": [
"runtimes/incubating/eve-electron/eve-runtime-capability.json",
"scripts/run-eveelectron-lifecycle-smoke.ps1",
"scripts/run-eveelectron-provider-shell-smoke.ps1"
]
}
],
"pendingProofs": [
@ -657,6 +666,10 @@
"repoRole": "runtime-target",
"splitTarget": "EveElectron",
"graduationTrigger": "Split when Electron has a provider-agnostic shell body, provider advertisement consumption, command transport, packaged app lifecycle, and capture evidence independent of Aetheria product code.",
"capabilityManifest": {
"schemaPath": "schemas/gamecult.eve.runtime_capability.v1.schema.json",
"manifestPath": "runtimes/incubating/eve-electron/eve-runtime-capability.json"
},
"splitHandoffPath": "runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"requiredFixtures": ["embedded-surface", "aetheria-world"],
"pluginFixtures": [],
@ -677,8 +690,76 @@
}
],
"expectedPaths": [
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json"
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"runtimes/incubating/eve-electron/eve-runtime-capability.json",
"scripts/run-eveelectron-lifecycle-smoke.ps1",
"scripts/run-eveelectron-provider-shell-smoke.ps1"
],
"lifecycle": {
"release": {
"ownerRepo": "EveElectron",
"status": "pending-electron-package",
"releaseContract": {
"ownerRepo": "EveElectron",
"packageName": "eve-electron",
"packageRoot": "runtimes/incubating/eve-electron",
"versionSource": "runtimes/incubating/eve-electron/eve-runtime-capability.json",
"tagPattern": "eveelectron-v{version}",
"artifactKind": "electron-app",
"publishProof": "Packaged Electron release is created from the EveElectron repo and references the provider-agnostic shell package root."
},
"evidencePaths": [
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"scripts/run-eveelectron-split-handoff-smoke.ps1"
],
"pendingProofs": [
"Electron packaged app release is cut from EveElectron rather than Eve incubation."
]
},
"test": {
"ownerRepo": "EveElectron",
"status": "pending-provider-advertisement-shell-smoke",
"testContract": {
"ownerRepo": "EveElectron",
"runnerKind": "electron-provider-shell-smoke",
"runnerScript": "scripts/run-eveelectron-provider-shell-smoke.ps1",
"consumerProject": "E:\\Projects\\Aetheria",
"packageName": "eve-electron",
"testAssembly": "EveElectron.ProviderShell",
"testPlatform": "Electron",
"resultsArtifact": "artifacts/eveelectron-provider-shell/{stamp}/provider-shell-results.json",
"logArtifact": "artifacts/eveelectron-provider-shell/{stamp}/provider-shell.log",
"manifestMutation": "None; the shell consumes provider advertisements and must not mutate provider product manifests."
},
"evidencePaths": [
"runtimes/incubating/eve-electron/eveelectron-split-handoff.json",
"scripts/run-eveelectron-split-handoff-smoke.ps1"
],
"pendingProofs": [
"Electron provider-advertisement shell smoke runs from EveElectron without importing Aetheria source layout."
]
},
"capture": {
"ownerRepo": "EveElectron",
"status": "pending-electron-window-capture",
"captureContract": {
"ownerRepo": "EveElectron",
"runtimeId": "electron-shell",
"captureKind": "electron-window-png",
"artifactKind": "png",
"artifactPattern": "artifacts/eveelectron-capture/{stamp}/electron-shell.png",
"conformanceAttachment": "runtime.captureArtifacts[]",
"requiredProvider": "aetheria",
"requiredSurface": "aetheria.daemon.game",
"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."
},
"evidencePaths": [],
"pendingProofs": [
"Electron window capture artifact is attached to the runtime conformance report."
]
}
},
"capture": {
"status": "missing",
"note": "Electron capture is a split blocker until EveElectron owns a provider-agnostic shell."