Clarify optional nested plugin projection boundaries

This commit is contained in:
Meta Vens 2026-07-09 13:30:40 +01:00
commit 0e2516e256
8 changed files with 47 additions and 55 deletions

View file

@ -398,15 +398,15 @@ Recently cut:
- Provider/runtime/plugin projection coverage is now exported as
`providerRuntimePluginProjectionCoverage[]`. The runtime-owner smoke proves
the Sai VN provider surface lowers fully in web, lowers in Unity UI Toolkit
with optional independent Norn and TeX nested plugin projection when those
plugins are available, and does not let UIKit's generic embedded-document path
impersonate required Sai VN, optional Norn graph, or optional TeX math
projection.
and Android Flutter with optional independent Norn and TeX nested plugin
projection when those plugins are available, and does not let UIKit's generic
embedded-document path impersonate required Sai VN, optional Norn graph, or
optional TeX math projection.
- Runtime/plugin projection gaps are now exported as
`runtimePluginProjectionGaps[]`. The runtime-owner smoke asserts remaining
device-edge plugin gaps as typed records, so missing Sai, Norn, or TeX
projection support is owned by the runtime split target and does not imply
those plugin semantics should move into Eve core or Aetheria product code.
`runtimePluginProjectionGaps[]`. Device-edge runtimes no longer consume the
Sai fixture as failed projection clients; missing Sai, Norn, or TeX support is
recorded only on runtimes that actually claim plugin projection work, so plugin
semantics do not drift into Eve core or Aetheria product code.
- Split target blockers are now exported as `splitTargetBlockers[]` and as
per-target `blockerRecords[]` with blocker kind, subject, owner, and source
text. The split-target consumer smoke asserts Unity scene status/plugin
@ -761,12 +761,11 @@ Recently cut:
the parity harness validates embedded-slot preservation, command descriptors,
runtime authority witnesses, and style tokens. Direct2D capture and
runtime-owned command smoke remain the activation blockers.
- UIKit and Kotlin device-edge runtimes now declare unsupported plugin
projection explicitly for separate Sai, Norn, and TeX capabilities. They
remain generic embedded-document and device-edge proofs; plugin projection
authority belongs to EveFlutter, EveUnity, or future runtime-specific
projection adapters instead of being reported as unexplained active capability
gaps.
- UIKit and Kotlin device-edge runtimes no longer consume the Sai plugin fixture
as projection acceptance targets. They remain generic embedded-document and
device-edge proofs; plugin projection authority belongs to EveFlutter,
EveUnity, EveElectron, EveTui, or future runtime-specific adapters when those
bodies earn the claim.
- The web reference no longer hardcodes the local provider list in
`web/surface.js`. It loads `web/local-provider-catalog.json`, then opens
advertisement-backed entries for Aetheria, Repixelizer, and Sai through the

View file

@ -145,9 +145,11 @@ reference probe provider source layout.
Declared runtime/plugin projection gaps are exported as
`runtimePluginProjectionGaps[]`. These records carry runtime id, runtime owner,
split target, plugin id, reason, severity, and fixture lists so EveUnity,
EveElectron, Sai, Norn, and TeX owners can distinguish "runtime cannot project
this plugin yet" from "plugin semantics belong in Eve core." Consumer smokes can
assert them with `--expect-runtime-plugin-gap <runtimeId:pluginId:ownerRepo>`.
EveElectron, Sai, Norn, and TeX owners can distinguish "this projection runtime
cannot project the plugin yet" from "plugin semantics belong in Eve core."
Device-edge dashboard proofs that do not claim plugin projection are not listed
as failed plugin clients. Consumer smokes can assert real projection gaps with
`--expect-runtime-plugin-gap <runtimeId:pluginId:ownerRepo>`.
The same claims are exported as `runtimePluginProjectionCoverage[]`, including
positive `supported` projection adapters and declared `unsupported` gaps. This
lets runtime and plugin owners consume one ledger for "Unity UI Toolkit has
@ -510,7 +512,9 @@ The harness tracks every target runtime:
`android/app/src/main/java/org/gamecult/eve/MainActivity.kt` renders
`surface.slot` with a content description containing the embedded slot
identity, and `node tools/parity/run-parity.mjs` reports
`embeddedDocuments` support for `android-kotlin`.
`embeddedDocuments` support for `android-kotlin`. It does not consume plugin
fixtures until EveAndroid grows a plugin projection adapter; Android Flutter
is the Android-side plugin projection acceptance target.
- Rust / CultMesh: typed document runtime rather than a CultUI renderer.
Required nested-surface evidence: `cargo test -p cultnet-rs
rust_preserves_cultui_embedded_surface_slots_through_typed_document_sync`

View file

@ -35,8 +35,8 @@ proves the same contract at the CultMesh typed document sync layer.
| Windows / Flutter | Active shared graphical smoke target | `flutter/eve_parity` loads exported `gamecult.eve.surface.v1` fixture JSON, including `embedded-surface`, and emits phone/tablet/desktop golden PNGs through `capture-flutter-parity.ps1` | Needs native window capture and tighter text/style normalization |
| Linux / Flutter | Active shared graphical smoke target | Nightwing runs the Flutter parity goldens, including embedded surface slots, over SSH and returns phone/tablet/desktop PNGs | Needs native window capture and runner health checks |
| Android / Flutter | Active shared graphical smoke target | The same Flutter parity app is built as an APK, installed on Periwinkle, and captured at phone/tablet/desktop plus native physical-panel orientations | Needs live provider picker and command transport beyond fixture assets |
| iOS / UIKit | Active native screenshot target | SSH capture stages selected fixture JSON, EveCanvas renders it, and emits a PNG from `/var/mobile/Library/EveCanvas/latest-screenshot.png`; `embedded-surface` is part of the required fixture matrix | Plugin projection is explicitly unsupported until EveIOS owns adapters; still needs provider picker and command transport |
| Android / Kotlin device edge | Active lightweight renderer | Native APK consumes CultMesh dashboard/sensor documents and preserves `surface.slot` / `embeddedDocuments` identity in the dashboard renderer | Plugin projection is explicitly unsupported; full graphical parity belongs to Flutter unless EveAndroid grows adapters |
| iOS / UIKit | Active native screenshot target | SSH capture stages selected fixture JSON, EveCanvas renders it, and emits a PNG from `/var/mobile/Library/EveCanvas/latest-screenshot.png`; `embedded-surface` is part of the required fixture matrix | Not a plugin projection acceptance target until EveIOS owns adapters; still needs provider picker and command transport |
| Android / Kotlin device edge | Active lightweight renderer | Native APK consumes CultMesh dashboard/sensor documents and preserves `surface.slot` / `embeddedDocuments` identity in the dashboard renderer | Not a plugin projection acceptance target; Android Flutter owns full graphical/plugin parity unless EveAndroid grows adapters |
| Rust / CultMesh | Document-sync contract runtime | CultLib replicates the `gamecult.eve.surface.v1` embedded slot contract through typed document sync | Not a pixel renderer |
| Fensalir Direct2D | External adapter spike, not active parity runtime | Fensalir has `src/Aquarium.EveSurface/EveSurfaceRuntime.cs`, reads an Eve broker, lowers into `AquariumUiDocument` / `DirectWriteOverlay`, and now has a runtime-pack `gamecult.eve.surface.v1` fixture in Eve | Needs runtime-owned command smoke, DirectWrite/Direct2D frame capture, and a clear reason to stay separate from Flutter for desktop UI |

View file

@ -71,6 +71,13 @@
"minLength": 1
}
},
"optionalNestedPlugins": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"splitTarget": {
"type": "string"
}

View file

@ -105,6 +105,9 @@ node $consumerScript $consumerExport `
--expect-runtime-plugin-projection tui:tex.math:supported:EveTui `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:web:sai.vn:supported:Eve `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:web:tex.math:optional-supported:Eve `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:android-flutter:sai.vn:supported:EveFlutter `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:android-flutter:norn.graph:optional-supported:EveFlutter `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:android-flutter:tex.math:optional-supported:EveFlutter `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:unity-uitoolkit:sai.vn:supported:EveUnity `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:unity-uitoolkit:norn.graph:optional-supported:EveUnity `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:unity-uitoolkit:tex.math:optional-supported:EveUnity `
@ -117,8 +120,6 @@ node $consumerScript $consumerExport `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:tui:sai.vn:supported:EveTui `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:tui:norn.graph:optional-supported:EveTui `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:tui:tex.math:optional-supported:EveTui `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:ios-uikit:sai.vn:unsupported-runtime-projection:EveIOS `
--expect-provider-runtime-plugin-projection gamecult.home.vn:sai.visual_novel.surface:ios-uikit:norn.graph:optional-unsupported-runtime-projection:EveIOS `
--expect-runtime-handoff unity-uitoolkit `
--expect-runtime-command-schema web:gamecult.eve.command.v1 `
--expect-runtime-command-schema windows-flutter:gamecult.eve.command.v1 `

View file

@ -156,7 +156,9 @@
{
"pluginId": "sai.vn",
"capabilities": ["vn.stage", "story.choose", "story.continue", "story.jump"]
},
}
],
"optionalNestedPlugins": [
{
"pluginId": "norn.graph",
"capabilities": ["embed.norn"]
@ -1301,22 +1303,9 @@
"splitTarget": "EveIOS",
"graduationTrigger": "Split when UIKit renderer has generic surface lowering, sensor edge release flow, and device CI independent of Eve core.",
"requiredFixtures": ["embedded-surface"],
"pluginFixtures": ["sai-vn"],
"pluginFixtures": [],
"supportedFeatures": ["embeddedDocuments"],
"unsupportedPlugins": [
{
"pluginId": "sai.vn",
"reason": "UIKit smoke proves generic embedded document lowering and capture only; Sai VN projection belongs to EveFlutter/EveUnity or a future EveIOS projection adapter."
},
{
"pluginId": "norn.graph",
"reason": "UIKit smoke preserves embed.norn as generic Eve structure; Norn graph projection is not implemented in this runtime."
},
{
"pluginId": "tex.math",
"reason": "UIKit smoke preserves embed.tex as generic Eve structure; TeX projection is not implemented in this runtime."
}
],
"unsupportedPlugins": [],
"expectedPaths": ["Sources/EVEViewController.mm", "scripts/capture-eve-screenshot.ps1"],
"expectedSourceSymbols": [
{
@ -1393,22 +1382,9 @@
"splitTarget": "EveAndroid",
"graduationTrigger": "Split when Kotlin device edge has generic surface traversal, sensor release flow, and Android-specific CI.",
"requiredFixtures": ["embedded-surface"],
"pluginFixtures": ["sai-vn"],
"pluginFixtures": [],
"supportedFeatures": ["cultmesh-dashboard-documents", "sensor-uplink", "embeddedDocuments"],
"unsupportedPlugins": [
{
"pluginId": "sai.vn",
"reason": "Kotlin device edge is a lightweight CultMesh/sensor dashboard proof; Sai VN projection belongs to Flutter, Unity, or a future Android projection adapter."
},
{
"pluginId": "norn.graph",
"reason": "Kotlin device edge preserves embed.norn as generic Eve structure; Norn graph projection is not implemented in this runtime."
},
{
"pluginId": "tex.math",
"reason": "Kotlin device edge preserves embed.tex as generic Eve structure; TeX projection is not implemented in this runtime."
}
],
"unsupportedPlugins": [],
"expectedPaths": ["android/app/src/main/java/org/gamecult/eve/MainActivity.kt", "scripts/build-android.ps1"],
"expectedSourceSymbols": [
{

View file

@ -235,6 +235,7 @@ async function evaluateFixture(fixture) {
ownerRepo: fixture.ownerRepo || "",
surface: fixture.surface || {},
requiredPlugins: fixture.requiredPlugins || [],
optionalNestedPlugins: fixture.optionalNestedPlugins || [],
status: checks.every(check => check.pass) ? "pass" : "fail",
durationMs: Date.now() - startedAt,
providerId: state.providerId,
@ -1899,6 +1900,7 @@ function buildConformanceExport(report) {
exitCriteria: fixture.metadata?.exitCriteria || "",
asserts: fixture.metadata?.asserts || [],
requiredPlugins: fixture.requiredPlugins || [],
optionalNestedPlugins: fixture.optionalNestedPlugins || fixture.metadata?.optionalNestedPlugins || [],
}));
const runtimeTargets = pack.id === "runtime"
? (report.runtimes || []).map(runtime => ({

View file

@ -15,10 +15,13 @@
"embed.norn component",
"embed.tex component",
"story command descriptors",
"plugin capability requirements"
"required Sai plugin capability",
"optional nested plugin composition"
],
"requiredPlugins": [
"sai.vn",
"sai.vn"
],
"optionalNestedPlugins": [
"norn.graph",
"tex.math"
],