From e64e659f1796ab05d68bd91bd673f4cba69e9a61 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 9 Jul 2026 10:42:45 +0100 Subject: [PATCH] Add TUI provider shell skeleton --- docs/eve-migration-roadmap.md | 6 + .../eve-tui/eve-runtime-capability.json | 30 +++-- .../eve-tui/evetui-split-handoff.json | 12 +- runtimes/incubating/eve-tui/package.json | 17 +++ .../incubating/eve-tui/src/eve-tui-shell.mjs | 120 ++++++++++++++++++ .../eve-tui/test/eve-tui-shell.test.mjs | 80 ++++++++++++ ...un-aetheria-conformance-consumer-smoke.ps1 | 3 + scripts/run-evetui-lifecycle-smoke.ps1 | 9 +- scripts/run-evetui-provider-shell-smoke.ps1 | 49 ++++++- scripts/run-evetui-split-handoff-smoke.ps1 | 14 +- ...ntime-owner-conformance-consumer-smoke.ps1 | 7 +- ...plit-target-conformance-consumer-smoke.ps1 | 6 +- tools/parity/parity-manifest.json | 35 ++++- 13 files changed, 357 insertions(+), 31 deletions(-) create mode 100644 runtimes/incubating/eve-tui/package.json create mode 100644 runtimes/incubating/eve-tui/src/eve-tui-shell.mjs create mode 100644 runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index b8ad7d2..e37df48 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -336,6 +336,12 @@ Recently cut: surfaces, emits `gamecult.eve.command.v1` intents with provider command boundary and receipt schema fields, and has a runnable Node smoke without claiming embedded document rendering, packaged Electron lifecycle, or capture. +- EveTui now has a provider-shell contract skeleton under + `runtimes/incubating/eve-tui`. The shell selects advertised provider + surfaces, emits `gamecult.eve.command.v1` intents with provider command + boundary and receipt schema fields, and produces an explicitly lossy + `gamecult.eve.tui_grid.v1` summary without claiming full `tui` world lowering + or transcript capture. - The conformance export carries `splitHandoffMoveCoverage[]`, joining runtime split handoff move sets to source path status. EveElectron now exposes the existing Aetheria `Aetheria.Rts.Web/Electron` and command transport paths as diff --git a/runtimes/incubating/eve-tui/eve-runtime-capability.json b/runtimes/incubating/eve-tui/eve-runtime-capability.json index dcc0d5b..289022b 100644 --- a/runtimes/incubating/eve-tui/eve-runtime-capability.json +++ b/runtimes/incubating/eve-tui/eve-runtime-capability.json @@ -13,25 +13,29 @@ "smokeCommand": "powershell -ExecutionPolicy Bypass -File .\\scripts\\run-evetui-split-handoff-smoke.ps1" } }, - "supportedFeatures": [], + "supportedFeatures": [ + "providerAdvertisements", + "commandTransport", + "terminalGridSummary" + ], "supportedPlugins": [], "unsupportedPlugins": [ { "pluginId": "sai.vn", - "reason": "TUI has no generic runtime body yet; Sai projection must be a declared lossy terminal projection once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no Sai terminal projection adapter exists in this runtime." }, { "pluginId": "norn.graph", - "reason": "TUI has no generic runtime body yet; Norn graph projection needs explicit text/grid fallback semantics once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no Norn graph terminal fallback exists in this runtime." }, { "pluginId": "tex.math", - "reason": "TUI has no generic runtime body yet; TeX projection needs explicit text/grid fallback semantics once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no TeX terminal fallback exists in this runtime." } ], "commandTransport": { "schema": "gamecult.eve.command.v1", - "status": "pending-runtime-body", + "status": "provider-shell-contract-skeleton", "emitter": "EveTui.EmitCommand", "clientId": "tui", "authority": "TUI emits command intents through provider-advertised command boundaries; providers accept, deny, and publish receipts." @@ -50,6 +54,8 @@ "publishProof": "Terminal runtime release is created from the EveTui repo and references the provider-agnostic TUI package root." }, "evidencePaths": [ + "runtimes/incubating/eve-tui/package.json", + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", "runtimes/incubating/eve-tui/evetui-split-handoff.json", "scripts/run-evetui-split-handoff-smoke.ps1" ], @@ -59,25 +65,29 @@ }, "test": { "ownerRepo": "EveTui", - "status": "pending-provider-advertisement-tui-smoke", + "status": "provider-shell-contract-skeleton", "testContract": { "ownerRepo": "EveTui", "runnerKind": "terminal-provider-shell-smoke", "runnerScript": "scripts/run-evetui-provider-shell-smoke.ps1", "consumerProject": "E:\\Projects\\Aetheria", "packageName": "eve-tui", - "testAssembly": "EveTui.ProviderShell", - "testPlatform": "Terminal", + "testAssembly": "eve-tui-shell.test.mjs", + "testPlatform": "Node terminal-grid contract skeleton", "resultsArtifact": "artifacts/evetui-provider-shell/{stamp}/provider-shell-results.json", "logArtifact": "artifacts/evetui-provider-shell/{stamp}/provider-shell.log", "manifestMutation": "None; the TUI consumes provider advertisements and must not mutate provider product manifests." }, "evidencePaths": [ + "runtimes/incubating/eve-tui/package.json", + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs", "runtimes/incubating/eve-tui/evetui-split-handoff.json", - "scripts/run-evetui-split-handoff-smoke.ps1" + "scripts/run-evetui-split-handoff-smoke.ps1", + "scripts/run-evetui-provider-shell-smoke.ps1" ], "pendingProofs": [ - "TUI provider-advertisement shell smoke runs from EveTui without importing provider source layout." + "TUI provider-advertisement smoke runs from EveTui with durable terminal transcript or cell-grid artifacts." ] }, "capture": { diff --git a/runtimes/incubating/eve-tui/evetui-split-handoff.json b/runtimes/incubating/eve-tui/evetui-split-handoff.json index 5e9f8e8..1c1ff14 100644 --- a/runtimes/incubating/eve-tui/evetui-split-handoff.json +++ b/runtimes/incubating/eve-tui/evetui-split-handoff.json @@ -12,7 +12,11 @@ { "id": "tui-runtime-body", "stage": "runtime-body", - "currentPaths": [], + "currentPaths": [ + "runtimes/incubating/eve-tui/package.json", + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs" + ], "destinationOwner": "EveTui", "replacementProof": "EveTui hosts a provider-agnostic TUI lowerer that consumes provider advertisements and Eve surface documents without importing provider internals." }, @@ -26,7 +30,10 @@ { "id": "tui-command-transport", "stage": "command", - "currentPaths": [], + "currentPaths": [ + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs" + ], "destinationOwner": "EveTui", "replacementProof": "TUI actions emit gamecult.eve.command.v1 intents through provider-advertised command boundaries and render provider receipts instead of mutating local state." }, @@ -55,6 +62,7 @@ ], "requiredExternalProofs": [ "EveTui publishes a runtime capability manifest with terminal/grid capabilities.", + "EveTui owns a provider-shell contract skeleton that selects advertised provider surfaces, emits gamecult.eve.command.v1 intents, and produces an explicitly lossy terminal-grid summary.", "EveTui claims the tui world-surface lowering target only after a real provider-agnostic lowerer exists.", "EveTui consumes at least one non-Aetheria provider advertisement.", "EveTui consumes Aetheria's agent-facing TUI surface through provider advertisements without importing Aetheria internals.", diff --git a/runtimes/incubating/eve-tui/package.json b/runtimes/incubating/eve-tui/package.json new file mode 100644 index 0000000..9d73ca8 --- /dev/null +++ b/runtimes/incubating/eve-tui/package.json @@ -0,0 +1,17 @@ +{ + "name": "eve-tui", + "version": "0.1.0", + "type": "module", + "description": "Provider-agnostic compact TUI shell skeleton for Eve surfaces.", + "main": "src/eve-tui-shell.mjs", + "scripts": { + "test": "C:\\Progra~1\\nodejs\\node.exe --test test/*.test.mjs" + }, + "keywords": [ + "Eve", + "TUI", + "CultUI", + "provider-advertisement" + ], + "license": "MPL-2.0" +} diff --git a/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs b/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs new file mode 100644 index 0000000..7ea318f --- /dev/null +++ b/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs @@ -0,0 +1,120 @@ +export class EveTuiShell { + constructor({ clientId = "tui", width = 80 } = {}) { + this.clientId = clientId; + this.width = Math.max(20, Number(width) || 80); + } + + selectSurface(providerAdvertisement, requestedSurfaceId = "") { + const provider = normalizeProviderAdvertisement(providerAdvertisement); + const surface = requestedSurfaceId + ? provider.surfaces.find(candidate => candidate.surfaceId === requestedSurfaceId) + : provider.surfaces[0]; + if (!surface) { + throw new Error(`Provider ${provider.providerId} does not advertise surface ${requestedSurfaceId || "(first)"}`); + } + return { + providerId: provider.providerId, + surfaceId: surface.surfaceId, + title: surface.title || provider.title || surface.surfaceId, + transport: surface.transport || "", + url: surface.url || surface.key || "", + worldInteraction: normalizeWorldInteraction(surface.worldInteraction), + }; + } + + createCommandIntent(providerAdvertisement, requestedSurfaceId, command, payload = {}) { + if (!command) throw new Error("Command is required."); + const selected = this.selectSurface(providerAdvertisement, requestedSurfaceId); + const action = objectValue(payload.action); + const commandBoundary = firstString( + selected.worldInteraction.commandBoundary, + payload.commandBoundary, + action.commandBoundary, + action.target, + ); + const receiptSchema = firstString( + selected.worldInteraction.receiptSchema, + payload.receiptSchema, + action.receiptSchema, + ); + const intent = { + type: "surface-command", + schema: "gamecult.eve.command.v1", + providerId: selected.providerId, + surfaceId: selected.surfaceId, + command, + payload: { + ...payload, + transport: payload.transport ?? null, + }, + issuedAt: new Date().toISOString(), + clientId: this.clientId, + }; + if (commandBoundary) intent.commandBoundary = commandBoundary; + if (receiptSchema) intent.receiptSchema = receiptSchema; + return intent; + } + + renderSummary(providerAdvertisement, requestedSurfaceId = "") { + const selected = this.selectSurface(providerAdvertisement, requestedSurfaceId); + const lines = [ + fitLine(`EveTui ${selected.providerId}`, this.width), + fitLine(`surface ${selected.surfaceId}`, this.width), + fitLine(`transport ${selected.transport || "unknown"}`, this.width), + fitLine(`command ${selected.worldInteraction.commandBoundary || "unadvertised"}`, this.width), + fitLine(`receipt ${selected.worldInteraction.receiptSchema || "unadvertised"}`, this.width), + ]; + return { + schema: "gamecult.eve.tui_grid.v1", + runtimeId: "tui", + providerId: selected.providerId, + surfaceId: selected.surfaceId, + width: this.width, + lines, + lossiness: "provider-shell-summary-only; not a full TUI world-surface lowering claim", + }; + } +} + +export function normalizeProviderAdvertisement(providerAdvertisement) { + if (!providerAdvertisement || typeof providerAdvertisement !== "object") { + throw new Error("Provider advertisement is required."); + } + const providerId = String(providerAdvertisement.providerId || ""); + if (!providerId) throw new Error("Provider advertisement missing providerId."); + const surfaces = Array.isArray(providerAdvertisement.surfaces) + ? providerAdvertisement.surfaces + .filter(surface => surface && typeof surface === "object" && surface.surfaceId) + .map(surface => ({ ...surface, surfaceId: String(surface.surfaceId) })) + : []; + if (!surfaces.length) throw new Error(`Provider ${providerId} advertises no surfaces.`); + return { ...providerAdvertisement, providerId, surfaces }; +} + +function normalizeWorldInteraction(value) { + const source = objectValue(value); + return { + projectionKind: firstString(source.projectionKind), + commandBoundary: firstString(source.commandBoundary), + receiptSchema: firstString(source.receiptSchema), + ownership: firstString(source.ownership), + }; +} + +function fitLine(value, width) { + const text = String(value || ""); + if (text.length <= width) return text; + return `${text.slice(0, Math.max(0, width - 3))}...`; +} + +function objectValue(value) { + return value && typeof value === "object" && !Array.isArray(value) ? value : {}; +} + +function firstString(...values) { + for (const value of values) { + if (typeof value === "string" && value.trim()) return value; + if (typeof value === "number" && Number.isFinite(value)) return String(value); + } + return ""; +} diff --git a/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs b/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs new file mode 100644 index 0000000..12fe3e3 --- /dev/null +++ b/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs @@ -0,0 +1,80 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { EveTuiShell } from "../src/eve-tui-shell.mjs"; + +test("selects advertised provider surfaces for compact projection", () => { + const shell = new EveTuiShell({ width: 48 }); + const selected = shell.selectSurface(advertisement(), "aetheria.daemon.editor"); + + assert.equal(selected.providerId, "aetheria"); + assert.equal(selected.surfaceId, "aetheria.daemon.editor"); + assert.equal(selected.worldInteraction.commandBoundary, "aetheria.daemon.commands"); + assert.equal(selected.worldInteraction.receiptSchema, "aetheria.eve_command_acceptance_status.v1"); +}); + +test("command intents carry provider-advertised boundaries", () => { + const shell = new EveTuiShell(); + const intent = shell.createCommandIntent( + advertisement(), + "aetheria.daemon.game", + "aetheria.daemon.commands", + { + action: { + commandBoundary: "component.fallback.boundary", + receiptSchema: "component.fallback.receipt.v1", + target: "component.fallback.target", + }, + commandId: "aetheria.daemon.focus", + }, + ); + + assert.equal(intent.schema, "gamecult.eve.command.v1"); + assert.equal(intent.providerId, "aetheria"); + assert.equal(intent.surfaceId, "aetheria.daemon.game"); + assert.equal(intent.commandBoundary, "aetheria.daemon.commands"); + assert.equal(intent.receiptSchema, "aetheria.eve_command_acceptance_status.v1"); + assert.equal(intent.clientId, "tui"); +}); + +test("summary grid is explicitly lossy provider-shell evidence", () => { + const shell = new EveTuiShell({ width: 36 }); + const grid = shell.renderSummary(advertisement(), "aetheria.daemon.game"); + + assert.equal(grid.schema, "gamecult.eve.tui_grid.v1"); + assert.equal(grid.runtimeId, "tui"); + assert.equal(grid.surfaceId, "aetheria.daemon.game"); + assert.match(grid.lossiness, /not a full TUI world-surface lowering claim/); + assert.ok(grid.lines.every(line => line.length <= 36)); +}); + +function advertisement() { + return { + schema: "gamecult.eve.provider_advertisement.v1", + providerId: "aetheria", + title: "Aetheria", + surfaces: [ + { + surfaceId: "aetheria.daemon.game", + transport: "local-json", + url: "web/fixtures/aetheria-world-surface.json", + worldInteraction: { + projectionKind: "provider-authored-world-surface", + commandBoundary: "aetheria.daemon.commands", + receiptSchema: "aetheria.eve_command_acceptance_status.v1", + ownership: "provider-owns-world-state-assets-command-acceptance-and-receipts", + }, + }, + { + surfaceId: "aetheria.daemon.editor", + transport: "local-json", + url: "web/fixtures/aetheria-world-surface.json", + worldInteraction: { + projectionKind: "provider-authored-world-editor-surface", + commandBoundary: "aetheria.daemon.commands", + receiptSchema: "aetheria.eve_command_acceptance_status.v1", + ownership: "provider-owns-editor-state-assets-command-acceptance-and-receipts", + }, + }, + ], + }; +} diff --git a/scripts/run-aetheria-conformance-consumer-smoke.ps1 b/scripts/run-aetheria-conformance-consumer-smoke.ps1 index f0e2c22..6716643 100644 --- a/scripts/run-aetheria-conformance-consumer-smoke.ps1 +++ b/scripts/run-aetheria-conformance-consumer-smoke.ps1 @@ -70,8 +70,11 @@ try { --expect-command-boundary-coverage aetheria:aetheria.daemon.editor:tui:missing-runtime-claim:EveTui:tui ` --expect-world-lowering-gap aetheria:aetheria.daemon.game:unity-scene:EveUnity:unity-scene ` --expect-world-lowering-gap aetheria:aetheria.daemon.editor:tui:EveTui:tui ` + --expect-split-handoff-move EveTui:tui:tui-runtime-body:current:exists:eve-tui-shell.mjs ` + --expect-split-handoff-move EveTui:tui:tui-command-transport:current:exists:eve-tui-shell.mjs ` --expect-split-target-blocker "EveUnity:Unity scene runtime body graduates to EveUnity outside Aetheria product code" ` --expect-split-target-blocker "EveElectron:Electron shell runtime body graduates to EveElectron outside Aetheria product code" ` + --expect-split-target-blocker "EveTui:TUI runtime body graduates to EveTui outside provider product code" ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-runtime-body:current:exists:EveUnitySceneSurfaceLowerer.cs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-command-transport:replacement-required:no-source-paths:none ` --expect-split-handoff-move EveElectron:electron-shell:electron-shell-runtime:current:exists:eve-electron-shell.mjs ` diff --git a/scripts/run-evetui-lifecycle-smoke.ps1 b/scripts/run-evetui-lifecycle-smoke.ps1 index e6510f6..e1b15f8 100644 --- a/scripts/run-evetui-lifecycle-smoke.ps1 +++ b/scripts/run-evetui-lifecycle-smoke.ps1 @@ -36,8 +36,10 @@ if ($manifest.incubation.splitTarget -ne "EveTui") { throw "Unexpected EveTui split target: $($manifest.incubation.splitTarget)" } -if (@($manifest.supportedFeatures).Count -ne 0) { - throw "EveTui must not claim supported runtime features before the generic TUI lowerer exists" +foreach ($feature in @("providerAdvertisements", "commandTransport", "terminalGridSummary")) { + if (-not (@($manifest.supportedFeatures) -contains $feature)) { + throw "EveTui manifest missing provider-shell feature: $feature" + } } if (@($manifest.supportedPlugins).Count -ne 0) { throw "EveTui must not claim plugin projection before the generic TUI lowerer exists" @@ -53,7 +55,7 @@ foreach ($pluginId in @("sai.vn", "norn.graph", "tex.math")) { if ($manifest.commandTransport.schema -ne "gamecult.eve.command.v1") { throw "Unexpected EveTui command schema: $($manifest.commandTransport.schema)" } -if ($manifest.commandTransport.status -ne "pending-runtime-body") { +if ($manifest.commandTransport.status -ne "provider-shell-contract-skeleton") { throw "Unexpected EveTui command transport status: $($manifest.commandTransport.status)" } @@ -116,5 +118,6 @@ foreach ($field in @("ownerRepo", "runtimeId", "captureKind", "artifactKind", "a } & (Join-Path $projectRoot "scripts\run-evetui-split-handoff-smoke.ps1") +& (Join-Path $projectRoot "scripts\run-evetui-provider-shell-smoke.ps1") Write-Host "EveTui lifecycle smoke passed: $absoluteManifestPath" diff --git a/scripts/run-evetui-provider-shell-smoke.ps1 b/scripts/run-evetui-provider-shell-smoke.ps1 index 4b9e8ed..19c9575 100644 --- a/scripts/run-evetui-provider-shell-smoke.ps1 +++ b/scripts/run-evetui-provider-shell-smoke.ps1 @@ -20,8 +20,51 @@ $manifest = Get-Content -LiteralPath $absoluteManifestPath -Raw | ConvertFrom-Js if ($manifest.runtimeId -ne "tui") { throw "Unexpected EveTui runtime id: $($manifest.runtimeId)" } -if ($manifest.lifecycle.test.status -ne "pending-provider-advertisement-tui-smoke") { - throw "EveTui provider shell smoke should remain pending until a generic TUI body exists: $($manifest.lifecycle.test.status)" +if ($manifest.lifecycle.test.status -ne "provider-shell-contract-skeleton") { + throw "Unexpected EveTui provider shell status: $($manifest.lifecycle.test.status)" } -throw "EveTui provider shell smoke is a pending contract, not a runnable proof, until EveTui owns the provider-agnostic terminal/grid lowerer." +foreach ($feature in @("providerAdvertisements", "commandTransport", "terminalGridSummary")) { + if (-not (@($manifest.supportedFeatures) -contains $feature)) { + throw "EveTui provider shell missing supported feature: $feature" + } +} + +$expectedFiles = @( + "runtimes\incubating\eve-tui\package.json", + "runtimes\incubating\eve-tui\src\eve-tui-shell.mjs", + "runtimes\incubating\eve-tui\test\eve-tui-shell.test.mjs" +) + +foreach ($relativePath in $expectedFiles) { + $absolutePath = Join-Path $projectRoot $relativePath + if (-not (Test-Path -LiteralPath $absolutePath)) { + throw "EveTui provider shell missing file: $relativePath" + } +} + +$shellSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-tui\src\eve-tui-shell.mjs") -Raw +foreach ($symbol in @("EveTuiShell", "selectSurface", "createCommandIntent", "renderSummary", "gamecult.eve.tui_grid.v1", "commandBoundary", "receiptSchema")) { + if (-not $shellSource.Contains($symbol)) { + throw "EveTui provider shell source missing symbol: $symbol" + } +} + +$testSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-tui\test\eve-tui-shell.test.mjs") -Raw +foreach ($symbol in @("selects advertised provider surfaces", "command intents carry provider-advertised boundaries", "summary grid is explicitly lossy", "aetheria.daemon.commands")) { + if (-not $testSource.Contains($symbol)) { + throw "EveTui provider shell test missing symbol: $symbol" + } +} + +Push-Location (Join-Path $projectRoot "runtimes\incubating\eve-tui") +try { + npm test + if ($LASTEXITCODE -ne 0) { + throw "EveTui provider shell tests failed with exit code $LASTEXITCODE" + } +} finally { + Pop-Location +} + +Write-Host "EveTui provider shell smoke passed: $absoluteManifestPath" diff --git a/scripts/run-evetui-split-handoff-smoke.ps1 b/scripts/run-evetui-split-handoff-smoke.ps1 index 58e93ab..8517cbb 100644 --- a/scripts/run-evetui-split-handoff-smoke.ps1 +++ b/scripts/run-evetui-split-handoff-smoke.ps1 @@ -61,8 +61,18 @@ foreach ($id in $expectedMoveSets.Keys) { } $currentPaths = if ($null -eq $moveSet.currentPaths) { @() } else { @($moveSet.currentPaths) } $observedProviderPaths = if ($null -eq $moveSet.observedProviderPaths) { @() } else { @($moveSet.observedProviderPaths) } - if ($currentPaths.Count -ne 0) { - throw "EveTui split handoff move set $id must not claim existing Eve source paths before the generic TUI lowerer exists" + if ($id -in @("tui-runtime-body", "tui-command-transport")) { + if ($currentPaths.Count -eq 0) { + throw "EveTui split handoff move set $id must name provider-shell skeleton paths" + } + foreach ($relativePath in $currentPaths) { + $absolutePath = Join-Path $projectRoot $relativePath + if (-not (Test-Path -LiteralPath $absolutePath)) { + throw "EveTui split handoff move set $id references missing current path: $relativePath" + } + } + } elseif ($currentPaths.Count -ne 0) { + throw "EveTui split handoff move set $id must not claim existing Eve source paths before its proof exists" } if ($observedProviderPaths.Count -ne 0) { throw "EveTui split handoff move set $id must not treat provider product paths as generic TUI runtime source" diff --git a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 index 6c03506..625b16a 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -57,6 +57,9 @@ node $consumerScript $consumerExport ` --expect-runtime-feature unity-scene:commandTransport ` --expect-runtime-feature electron-shell:providerAdvertisements ` --expect-runtime-feature electron-shell:commandTransport ` + --expect-runtime-feature tui:providerAdvertisements ` + --expect-runtime-feature tui:commandTransport ` + --expect-runtime-feature tui:terminalGridSummary ` --expect-runtime-feature direct2d:embeddedDocuments ` --expect-runtime-world-target web:web-reference ` --expect-runtime-world-field web:web-reference:supportLevel:reference-dom-canvas-command-boundary ` @@ -142,10 +145,10 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.captureKind:electron-window-png" ` --expect-runtime-lifecycle-field "electron-shell:capture:captureContract.requiredSurface:aetheria.daemon.game" ` --expect-runtime-lifecycle-status tui:release:pending-tui-package ` - --expect-runtime-lifecycle-status tui:test:pending-provider-advertisement-tui-smoke ` + --expect-runtime-lifecycle-status tui:test:provider-shell-contract-skeleton ` --expect-runtime-lifecycle-status tui:capture:pending-terminal-capture ` --expect-runtime-lifecycle-pending "tui:release:TUI package release" ` - --expect-runtime-lifecycle-pending "tui:test:TUI provider-advertisement shell smoke" ` + --expect-runtime-lifecycle-pending "tui:test:TUI provider-advertisement smoke runs from EveTui with durable terminal transcript or cell-grid artifacts" ` --expect-runtime-lifecycle-pending "tui:capture:TUI terminal transcript or cell-grid capture artifact" ` --expect-runtime-lifecycle-field "tui:release:releaseContract.artifactKind:terminal-runtime" ` --expect-runtime-lifecycle-field "tui:test:testContract.runnerKind:terminal-provider-shell-smoke" ` diff --git a/scripts/run-split-target-conformance-consumer-smoke.ps1 b/scripts/run-split-target-conformance-consumer-smoke.ps1 index 7a10ea4..a8ab5f1 100644 --- a/scripts/run-split-target-conformance-consumer-smoke.ps1 +++ b/scripts/run-split-target-conformance-consumer-smoke.ps1 @@ -70,8 +70,10 @@ try { --expect-split-target-proof "EveTui:EveTui split handoff is machine-readable" ` --expect-split-target-proof "EveTui:EveTui lifecycle contract is machine-readable" ` --expect-split-target-blocker "EveTui:runtime:tui:status:pending" ` - --expect-split-target-blocker-record EveTui:runtime-feature:tui:commandTransport ` - --expect-split-target-blocker "EveTui:TUI runtime body exists outside provider product code" + --expect-split-target-blocker-record EveTui:runtime-feature:tui:embeddedDocuments ` + --expect-split-handoff-move EveTui:tui:tui-runtime-body:current:exists:eve-tui-shell.mjs ` + --expect-split-handoff-move EveTui:tui:tui-command-transport:current:exists:eve-tui-shell.mjs ` + --expect-split-target-blocker "EveTui:TUI runtime body graduates to EveTui outside provider product code" if ($LASTEXITCODE -ne 0) { throw "Split target conformance consumer smoke failed with exit code $LASTEXITCODE" } diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index a622b26..ead008a 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -687,13 +687,21 @@ "scripts/run-evetui-lifecycle-smoke.ps1", "scripts/run-evetui-provider-shell-smoke.ps1" ] + }, + { + "description": "EveTui provider-shell skeleton selects advertised surfaces and emits Eve command intents.", + "status": "passed", + "evidencePaths": [ + "runtimes/incubating/eve-tui/package.json", + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs", + "scripts/run-evetui-provider-shell-smoke.ps1" + ] } ], "pendingProofs": [ - "TUI runtime body exists outside provider product code.", - "TUI consumes provider advertisements without provider source-layout knowledge.", + "TUI runtime body graduates to EveTui outside provider product code.", "TUI claims provider-advertised tui world-surface lowering with real transcript evidence.", - "TUI emits gamecult.eve.command.v1 through provider command boundaries.", "TUI terminal transcript or cell-grid captures are attached to conformance output." ] } @@ -769,29 +777,42 @@ "splitHandoffPath": "runtimes/incubating/eve-tui/evetui-split-handoff.json", "requiredFixtures": ["embedded-surface", "aetheria-world"], "pluginFixtures": [], - "supportedFeatures": [], + "supportedFeatures": ["providerAdvertisements", "commandTransport", "terminalGridSummary"], "supportedPlugins": [], "unsupportedPlugins": [ { "pluginId": "sai.vn", - "reason": "TUI has no generic runtime body yet; Sai projection must be a declared lossy terminal projection once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no Sai terminal projection adapter exists in this runtime." }, { "pluginId": "norn.graph", - "reason": "TUI has no generic runtime body yet; Norn graph projection needs explicit text/grid fallback semantics once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no Norn graph terminal fallback exists in this runtime." }, { "pluginId": "tex.math", - "reason": "TUI has no generic runtime body yet; TeX projection needs explicit text/grid fallback semantics once EveTui exists." + "reason": "TUI provider-shell skeleton exists, but no TeX terminal fallback exists in this runtime." } ], "expectedPaths": [ + "runtimes/incubating/eve-tui/package.json", + "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs", "runtimes/incubating/eve-tui/evetui-split-handoff.json", "runtimes/incubating/eve-tui/eve-runtime-capability.json", "scripts/run-evetui-split-handoff-smoke.ps1", "scripts/run-evetui-lifecycle-smoke.ps1", "scripts/run-evetui-provider-shell-smoke.ps1" ], + "expectedSourceSymbols": [ + { + "path": "runtimes/incubating/eve-tui/src/eve-tui-shell.mjs", + "contains": ["EveTuiShell", "selectSurface", "createCommandIntent", "renderSummary", "gamecult.eve.tui_grid.v1", "commandBoundary", "receiptSchema"] + }, + { + "path": "runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs", + "contains": ["selects advertised provider surfaces", "command intents carry provider-advertised boundaries", "summary grid is explicitly lossy", "aetheria.daemon.commands"] + } + ], "capture": { "status": "missing", "note": "TUI transcript or cell-grid capture is a split blocker until EveTui owns a provider-agnostic lowerer."