diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 6a19560..adad79d 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -969,6 +969,11 @@ Recently cut: fallback catalog only advertises the Sai provider surface; independent Norn and TeX availability is discovered through that provider's plugin requirements and the separate plugin advertisements. +- Electron shell and compact TUI projection artifacts now carry the same + availability split as Unity projection artifacts: `sai.vn` projection is + required for the VN surface, while `norn.graph` and `tex.math` are + `optional-nested` independent sidecar plugin projections. This keeps + runtime projection support from becoming an implied Sai dependency story. - 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 diff --git a/runtimes/incubating/eve-electron/src/eve-electron-shell.mjs b/runtimes/incubating/eve-electron/src/eve-electron-shell.mjs index ede8379..49be2da 100644 --- a/runtimes/incubating/eve-electron/src/eve-electron-shell.mjs +++ b/runtimes/incubating/eve-electron/src/eve-electron-shell.mjs @@ -170,6 +170,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["vn.stage", "story.choose", "story.continue", "story.jump"], documentId: firstString(component.props?.storyId, component.id), semanticOwner: "Sai", + availability: "required", }; } @@ -182,6 +183,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["embed.norn"], documentId: firstString(component.props?.sourceUri, component.props?.documentId, component.id), semanticOwner: "Norn", + availability: "optional-nested", }; } @@ -194,6 +196,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["embed.tex", "tex.inline", "tex.block"], documentId: firstString(component.props?.sourceUri, component.props?.source, component.id), semanticOwner: "EvePlugins", + availability: "optional-nested", }; } diff --git a/runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs b/runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs index 06621c3..892471f 100644 --- a/runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs +++ b/runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs @@ -89,6 +89,7 @@ test("lowers Sai, Norn, and TeX sidecar plugin shells without owning semantics", assert.equal(projection.root.shellElementKind, "sai-vn-stage-shell"); assert.equal(projection.root.pluginProjection.pluginId, "sai.vn"); assert.equal(projection.root.pluginProjection.semanticOwner, "Sai"); + assert.equal(projection.root.pluginProjection.availability, "required"); assert.equal(projection.root.pluginProjection.commandBoundary, "sidecar-advertised-plugin-abi"); assert.deepEqual(projection.root.pluginProjection.capabilities, [ "vn.stage", @@ -102,6 +103,7 @@ test("lowers Sai, Norn, and TeX sidecar plugin shells without owning semantics", assert.equal(norn.pluginProjection.pluginId, "norn.graph"); assert.equal(norn.pluginProjection.projectionKind, "norn-graph-electron-overlay-shell"); assert.equal(norn.pluginProjection.semanticOwner, "Norn"); + assert.equal(norn.pluginProjection.availability, "optional-nested"); assert.deepEqual(norn.pluginProjection.capabilities, ["embed.norn"]); const tex = findNode(projection.root, "sai.tex.log-power"); @@ -109,6 +111,7 @@ test("lowers Sai, Norn, and TeX sidecar plugin shells without owning semantics", assert.equal(tex.pluginProjection.pluginId, "tex.math"); assert.equal(tex.pluginProjection.projectionKind, "tex-math-electron-block-source-shell"); assert.equal(tex.pluginProjection.semanticOwner, "EvePlugins"); + assert.equal(tex.pluginProjection.availability, "optional-nested"); assert.equal(tex.pluginProjection.documentId, "\\\\mathrm{votes}(p)=1+\\\\lfloor\\\\log_b(1+p)\\\\rfloor"); assert.deepEqual(tex.pluginProjection.capabilities, ["embed.tex", "tex.inline", "tex.block"]); }); diff --git a/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs b/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs index 39485d3..1d358a9 100644 --- a/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs +++ b/runtimes/incubating/eve-tui/src/eve-tui-shell.mjs @@ -235,6 +235,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["vn.stage", "story.choose", "story.continue", "story.jump"], documentId: firstString(props.storyId, component.id), semanticOwner: "Sai", + availability: "required", fallbackKind: "terminal-summary", }; } @@ -248,6 +249,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["embed.norn"], documentId: firstString(props.sourceUri, props.documentId, component.id), semanticOwner: "Norn", + availability: "optional-nested", fallbackKind: "terminal-outline", }; } @@ -261,6 +263,7 @@ function buildPluginProjection(componentKind, component) { capabilities: ["embed.tex", "tex.inline", "tex.block"], documentId: firstString(props.sourceUri, props.source, component.id), semanticOwner: "EvePlugins", + availability: "optional-nested", fallbackKind: "source-text", }; } diff --git a/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs b/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs index 4181ac8..cdc4530 100644 --- a/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs +++ b/runtimes/incubating/eve-tui/test/eve-tui-shell.test.mjs @@ -86,6 +86,7 @@ test("lowers provider surface trees into a terminal grid", () => { capabilities: ["embed.norn"], documentId: "aetheria.daemon.game.norn", semanticOwner: "Norn", + availability: "optional-nested", fallbackKind: "terminal-outline", }, ]); @@ -123,6 +124,7 @@ test("lowers Sai, Norn, and TeX plugin surfaces into compact terminal fallbacks" const byPlugin = new Map(grid.pluginProjections.map(projection => [projection.pluginId, projection])); assert.equal(byPlugin.get("sai.vn").semanticOwner, "Sai"); + assert.equal(byPlugin.get("sai.vn").availability, "required"); assert.equal(byPlugin.get("sai.vn").projectionKind, "sai-vn-terminal-stage-summary"); assert.deepEqual(byPlugin.get("sai.vn").capabilities, [ "vn.stage", @@ -131,8 +133,10 @@ test("lowers Sai, Norn, and TeX plugin surfaces into compact terminal fallbacks" "story.jump", ]); assert.equal(byPlugin.get("norn.graph").semanticOwner, "Norn"); + assert.equal(byPlugin.get("norn.graph").availability, "optional-nested"); assert.equal(byPlugin.get("norn.graph").fallbackKind, "terminal-outline"); assert.equal(byPlugin.get("tex.math").semanticOwner, "EvePlugins"); + assert.equal(byPlugin.get("tex.math").availability, "optional-nested"); assert.equal(byPlugin.get("tex.math").projectionKind, "tex-math-terminal-block-source"); assert.equal(byPlugin.get("tex.math").fallbackKind, "source-text"); assert.equal(byPlugin.get("tex.math").documentId, "\\\\mathrm{votes}(p)=1+\\\\lfloor\\\\log_b(1+p)\\\\rfloor"); diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index e44f0f3..a5d93d8 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -800,7 +800,7 @@ }, { "path": "runtimes/incubating/eve-electron/test/eve-electron-shell.test.mjs", - "contains": ["selects the active advertised provider surface", "lowers provider surface trees into an Electron shell projection", "lowers Sai, Norn, and TeX sidecar plugin shells without owning semantics", "embeddedDocuments", "norn.map", "sai-vn-stage-shell", "norn-graph-shell", "tex-math-shell", "rejects surface documents that do not match the advertised target", "command intents carry provider-advertised boundaries", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1"] + "contains": ["selects the active advertised provider surface", "lowers provider surface trees into an Electron shell projection", "lowers Sai, Norn, and TeX sidecar plugin shells without owning semantics", "embeddedDocuments", "norn.map", "sai-vn-stage-shell", "norn-graph-shell", "tex-math-shell", "optional-nested", "rejects surface documents that do not match the advertised target", "command intents carry provider-advertised boundaries", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1"] }, { "path": "tools/eveelectron/eveelectron-capture-contract.mjs", @@ -917,7 +917,7 @@ }, { "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", "lowers provider surface trees into a terminal grid", "lowers Sai, Norn, and TeX plugin surfaces into compact terminal fallbacks", "embeddedDocumentSlots", "pluginProjections", "norn.map", "sai-vn-terminal-stage-summary", "norn-graph-terminal-outline", "tex-math-terminal-block-source", "rejects surface documents that do not match the advertised TUI target", "aetheria.daemon.commands"] + "contains": ["selects advertised provider surfaces", "command intents carry provider-advertised boundaries", "summary grid is explicitly lossy", "lowers provider surface trees into a terminal grid", "lowers Sai, Norn, and TeX plugin surfaces into compact terminal fallbacks", "embeddedDocumentSlots", "pluginProjections", "optional-nested", "norn.map", "sai-vn-terminal-stage-summary", "norn-graph-terminal-outline", "tex-math-terminal-block-source", "rejects surface documents that do not match the advertised TUI target", "aetheria.daemon.commands"] }, { "path": "tools/evetui/evetui-capture-contract.mjs",