Graduate Norn plugin ownership from Eve
This commit is contained in:
parent
144ce5a40c
commit
c02a807272
13 changed files with 77 additions and 324 deletions
|
|
@ -867,9 +867,8 @@ Recently cut:
|
|||
graduates. The conformance export carries `conformanceHandoffPath`, and the
|
||||
generic consumer smoke asserts it so EveConformance split readiness is not
|
||||
trapped in Eve's parity manifest.
|
||||
- Sai, Norn, and TeX now have plugin handoff manifests at
|
||||
- Sai and TeX have plugin handoff manifests at
|
||||
`plugins/incubating/sai-vn.plugin-handoff.json`,
|
||||
`plugins/incubating/norn-graph.plugin-handoff.json`, and
|
||||
`plugins/incubating/tex-math.plugin-handoff.json`, plus a shared verifier at
|
||||
`scripts/run-plugin-handoff-smoke.ps1`. The handoffs name the manifest,
|
||||
advertisement, ABI fixture, move sets, contract inputs, forbidden imports,
|
||||
|
|
@ -877,6 +876,13 @@ Recently cut:
|
|||
carries plugin `handoffPath` and `pluginHandoffMoveCoverage[]`, and the
|
||||
plugin-owner smoke asserts them so Sai, Norn, and EvePlugins can consume the
|
||||
plugin boundary without reading Eve's parity manifest.
|
||||
- Norn has crossed that handoff boundary. `Norn/plugins` now publishes the
|
||||
`norn.graph` manifest, advertisement, and ABI fixture, while
|
||||
`Norn/crates/norn-eve-plugin` runs the first executable sidecar over bounded
|
||||
NDJSON stdio. Eve consumes those owner paths directly and no longer carries
|
||||
a duplicate Norn manifest or handoff document. The plugin currently owns
|
||||
`describe`, `validate`, `project`, and solver-backed `measure`; runtime
|
||||
lowering and provider command acceptance remain outside Norn.
|
||||
- Aetheria now has a provider handoff manifest at
|
||||
`web/fixtures/aetheria-provider-handoff.json` and a verifier at
|
||||
`scripts/run-aetheria-provider-handoff-smoke.ps1`. The handoff names the
|
||||
|
|
|
|||
|
|
@ -456,8 +456,14 @@ Runtime projection support is not plugin hosting. A Unity, Electron, Flutter,
|
|||
TUI, or web client may provide an adapter for sidecar-advertised Norn or TeX
|
||||
output, but the sidecar daemon and plugin ABI remain runtime independent. If a
|
||||
Sai surface deploys with nested Norn or TeX, Sai composes the slots and keeps VN
|
||||
stage authority; Norn and TeX still publish, validate, lower, and receive
|
||||
commands through their own plugin contracts.
|
||||
stage authority; Norn and TeX still publish and validate their own semantic
|
||||
contracts. Each plugin advertises only the ABI operations it actually owns.
|
||||
|
||||
The carrier does not define the plugin. The first executable Norn proof uses
|
||||
UTF-8 NDJSON over stdio: one request document per line, one response per
|
||||
request in order, blank lines ignored, diagnostics on stderr. A future
|
||||
CultMesh daemon transport must carry the same typed request and response
|
||||
documents; it must not create a second semantic API.
|
||||
|
||||
Nested availability is a composition fact, not a Sai dependency story. A Sai
|
||||
surface can be deployed with a nested Norn or TeX surface only when that other
|
||||
|
|
@ -474,6 +480,11 @@ Norn plugin responsibilities:
|
|||
- define fallback and capability-gap behavior when a renderer cannot run Norn;
|
||||
- provide graph/map fixtures for Eve parity.
|
||||
|
||||
Norn currently claims `describe`, `validate`, `project`, and `measure`. It does
|
||||
not claim `lower` or `apply`: runtime lowerers own native projection, and
|
||||
providers own command acceptance and receipts. Conformance validates advertised
|
||||
operations rather than forcing every plugin to pretend it owns all ABI verbs.
|
||||
|
||||
TeX plugin responsibilities:
|
||||
|
||||
- define `embed.tex` semantics;
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
{
|
||||
"schema": "gamecult.eve.plugin_abi_fixture.v1",
|
||||
"fixtureId": "norn-graph-plugin-abi",
|
||||
"pluginId": "norn.graph",
|
||||
"ownerRepo": "Norn",
|
||||
"contract": "gamecult.eve.plugin_abi.v1",
|
||||
"requestSchema": "gamecult.eve.plugin_abi.request.v1",
|
||||
"responseSchema": "gamecult.eve.plugin_abi.response.v1",
|
||||
"sourceFixture": "sai-vn",
|
||||
"sourceFixtureRole": "optional-nested-placement-evidence",
|
||||
"authority": "Norn owns graph semantics independently; the Sai fixture only proves a provider surface can nest embed.norn when norn.graph is available.",
|
||||
"operations": [
|
||||
{
|
||||
"operation": "describe",
|
||||
"input": {
|
||||
"manifest": "plugins/incubating/norn-graph.plugin.json",
|
||||
"advertisement": "plugins/incubating/norn-graph.plugin-advertisement.json"
|
||||
},
|
||||
"expect": {
|
||||
"pluginId": "norn.graph",
|
||||
"componentKinds": ["embed.norn"],
|
||||
"commands": ["graph.node.activate", "graph.focus"],
|
||||
"capabilities": ["embed.norn", "graph.node.activate"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "validate",
|
||||
"input": {
|
||||
"surface": "web/fixtures/sai-vn-surface.json",
|
||||
"componentKinds": ["embed.norn"]
|
||||
},
|
||||
"expect": {
|
||||
"acceptedComponentKinds": ["embed.norn"],
|
||||
"rejectedComponentKinds": ["embed.tex", "vn.stage"],
|
||||
"requiredCapabilities": ["embed.norn"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "project",
|
||||
"input": {
|
||||
"surface": "web/fixtures/sai-vn-surface.json",
|
||||
"nodeKind": "embed.norn"
|
||||
},
|
||||
"expect": {
|
||||
"projectionKind": "embedded-semantic-surface",
|
||||
"ownedComponentKinds": ["embed.norn"],
|
||||
"outputSchemas": ["norn.graph.document.v1", "norn.graph.layout_request.v1", "norn.graph.layout_result.v1"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "lower",
|
||||
"input": {
|
||||
"projection": "embedded-semantic-surface",
|
||||
"targetRuntimes": ["web", "unity-uitoolkit"],
|
||||
"componentKinds": ["embed.norn"]
|
||||
},
|
||||
"expect": {
|
||||
"loweringKind": "graph-viewport",
|
||||
"preservedComponentKinds": ["embed.norn"],
|
||||
"requiredSchemas": ["norn.graph.document.v1", "norn.graph.layout_result.v1"],
|
||||
"commandEnvelope": "gamecult.eve.command.v1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "measure",
|
||||
"input": {
|
||||
"projection": "embedded-semantic-surface",
|
||||
"layoutRequestSchema": "norn.graph.layout_request.v1"
|
||||
},
|
||||
"expect": {
|
||||
"measurementKind": "graph-layout-metrics",
|
||||
"measurementOutputs": ["nodeBounds", "edgeRoutes", "viewportBounds"],
|
||||
"preservesProviderAuthority": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"operation": "apply",
|
||||
"input": {
|
||||
"commands": ["graph.node.activate", "graph.focus"]
|
||||
},
|
||||
"expect": {
|
||||
"commandEffects": {
|
||||
"graph.node.activate": "activate-node",
|
||||
"graph.focus": "focus-graph"
|
||||
},
|
||||
"receiptSchema": "gamecult.eve.command_receipt.v1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"schema": "gamecult.eve.plugin_advertisement.v1",
|
||||
"pluginId": "norn.graph",
|
||||
"ownerService": "norn",
|
||||
"version": "0.1.0-incubating",
|
||||
"manifestAddress": "file://plugins/incubating/norn-graph.plugin.json",
|
||||
"runtime": {
|
||||
"invocationModel": "executable-sidecar",
|
||||
"contract": "gamecult.eve.plugin_abi.v1",
|
||||
"transports": ["cultmesh", "stdio"],
|
||||
"authority": [
|
||||
"renderer-independent",
|
||||
"no-provider-state-mutation",
|
||||
"provider-accepts-or-denies-commands"
|
||||
],
|
||||
"sidecar": {
|
||||
"processKind": "long-running-daemon",
|
||||
"protocol": "cultmesh-rpc-with-stdio-dev-transport",
|
||||
"requestSchema": "gamecult.eve.plugin_abi.request.v1",
|
||||
"responseSchema": "gamecult.eve.plugin_abi.response.v1",
|
||||
"operations": ["describe", "validate", "project", "lower", "measure", "apply"],
|
||||
"commandEnvelope": "gamecult.eve.command.v1",
|
||||
"receiptSchema": "gamecult.eve.command_receipt.v1",
|
||||
"stateAuthority": "proposes-plugin-state-only-provider-accepts"
|
||||
}
|
||||
},
|
||||
"schemas": [
|
||||
"norn.graph.document.v1",
|
||||
"norn.graph.layout_request.v1",
|
||||
"norn.graph.layout_result.v1"
|
||||
],
|
||||
"componentKinds": [
|
||||
"embed.norn"
|
||||
],
|
||||
"commands": [
|
||||
"graph.node.activate",
|
||||
"graph.focus"
|
||||
],
|
||||
"fixtures": [
|
||||
"sai-vn"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
{
|
||||
"schema": "gamecult.eve.plugin_handoff.v1",
|
||||
"pluginId": "norn.graph",
|
||||
"ownerRepo": "Norn",
|
||||
"currentHostRepo": "Eve",
|
||||
"splitTarget": "Norn/eve-plugin-graph",
|
||||
"manifestPath": "plugins/incubating/norn-graph.plugin.json",
|
||||
"advertisementPath": "plugins/incubating/norn-graph.plugin-advertisement.json",
|
||||
"abiFixturePath": "plugins/incubating/norn-graph.plugin-abi-fixture.json",
|
||||
"authorityBoundary": "Norn owns graph document semantics, graph layout, graph interaction, fallback behavior, and plugin ABI behavior. Eve owns only plugin manifest, advertisement, ABI, provider requirement, and conformance export contracts.",
|
||||
"moveSets": [
|
||||
{
|
||||
"id": "plugin-manifest",
|
||||
"destinationOwner": "Norn",
|
||||
"currentPaths": [
|
||||
"plugins/incubating/norn-graph.plugin.json",
|
||||
"plugins/incubating/norn-graph.plugin-advertisement.json"
|
||||
],
|
||||
"replacementProof": "Norn publishes norn.graph plugin manifest and advertisement from the Norn repo or sidecar daemon."
|
||||
},
|
||||
{
|
||||
"id": "abi-conformance",
|
||||
"destinationOwner": "Norn",
|
||||
"currentPaths": [
|
||||
"plugins/incubating/norn-graph.plugin-abi-fixture.json",
|
||||
"web/fixtures/sai-vn-surface.json",
|
||||
"web/fixtures/sai-vn-surface.conformance.json"
|
||||
],
|
||||
"replacementProof": "Norn owns embed.norn layout, interaction, fallback, and ABI conformance cases; the Sai fixture is only optional nested placement evidence."
|
||||
}
|
||||
],
|
||||
"contractInputs": [
|
||||
"gamecult.eve.plugin.v1",
|
||||
"gamecult.eve.plugin_advertisement.v1",
|
||||
"gamecult.eve.plugin_abi.v1",
|
||||
"gamecult.eve.plugin_abi.request.v1",
|
||||
"gamecult.eve.plugin_abi.response.v1",
|
||||
"gamecult.eve.plugin_abi_fixture.v1",
|
||||
"gamecult.eve.conformance_export.v1"
|
||||
],
|
||||
"forbiddenImports": [
|
||||
"Aetheria provider state",
|
||||
"Sai story session internals or VN command authority",
|
||||
"renderer-native projection internals",
|
||||
"provider command acceptance or receipt authority"
|
||||
],
|
||||
"requiredExternalProofs": [
|
||||
"Norn publishes the norn.graph sidecar ABI without depending on Eve source layout.",
|
||||
"Norn owns graph layout, interaction, fallback, and conformance fixtures.",
|
||||
"Providers consume norn.graph through plugin advertisements and ABI operations.",
|
||||
"Runtimes declare norn.graph projection support through runtime capability manifests."
|
||||
]
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
{
|
||||
"schema": "gamecult.eve.plugin.v1",
|
||||
"pluginId": "norn.graph",
|
||||
"title": "Norn Graph",
|
||||
"owner": "Norn",
|
||||
"incubation": {
|
||||
"ownerRepo": "Norn",
|
||||
"currentHostRepo": "Eve",
|
||||
"splitTarget": "Norn/eve-plugin-graph",
|
||||
"graduationTrigger": "Split when graph layout, interaction, fallback, and conformance fixtures are stable."
|
||||
},
|
||||
"componentKinds": [
|
||||
"embed.norn"
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command": "graph.node.activate",
|
||||
"schema": "norn.graph.command.v1",
|
||||
"effect": "activate-node"
|
||||
},
|
||||
{
|
||||
"command": "graph.focus",
|
||||
"schema": "norn.graph.command.v1",
|
||||
"effect": "focus-graph"
|
||||
}
|
||||
],
|
||||
"runtime": {
|
||||
"invocationModel": "executable-sidecar",
|
||||
"contract": "gamecult.eve.plugin_abi.v1",
|
||||
"transports": ["cultmesh", "stdio"],
|
||||
"authority": [
|
||||
"renderer-independent",
|
||||
"no-provider-state-mutation",
|
||||
"provider-accepts-or-denies-commands"
|
||||
],
|
||||
"sidecar": {
|
||||
"processKind": "long-running-daemon",
|
||||
"protocol": "cultmesh-rpc-with-stdio-dev-transport",
|
||||
"requestSchema": "gamecult.eve.plugin_abi.request.v1",
|
||||
"responseSchema": "gamecult.eve.plugin_abi.response.v1",
|
||||
"operations": ["describe", "validate", "project", "lower", "measure", "apply"],
|
||||
"commandEnvelope": "gamecult.eve.command.v1",
|
||||
"receiptSchema": "gamecult.eve.command_receipt.v1",
|
||||
"stateAuthority": "proposes-plugin-state-only-provider-accepts"
|
||||
}
|
||||
},
|
||||
"stateSchemas": [
|
||||
"norn.graph.document.v1",
|
||||
"norn.graph.layout_request.v1",
|
||||
"norn.graph.layout_result.v1"
|
||||
],
|
||||
"fixtures": [
|
||||
{
|
||||
"fixtureId": "sai-vn",
|
||||
"schema": "gamecult.eve.surface.v1",
|
||||
"path": "web/fixtures/sai-vn-surface.json",
|
||||
"role": "optional-nested-placement-evidence",
|
||||
"authority": "Norn semantics remain plugin-owned; the Sai fixture only proves a surface can nest embed.norn when norn.graph is available."
|
||||
}
|
||||
],
|
||||
"abiFixtures": [
|
||||
"plugins/incubating/norn-graph.plugin-abi-fixture.json"
|
||||
],
|
||||
"capabilities": {
|
||||
"requires": [
|
||||
"embed.norn"
|
||||
],
|
||||
"optionalCapabilities": [
|
||||
"graph.node.activate",
|
||||
"graph.pan",
|
||||
"graph.zoom"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -144,7 +144,6 @@
|
|||
"runtimeId",
|
||||
"runtimeStatus",
|
||||
"ownerRepo",
|
||||
"splitTarget",
|
||||
"pluginId",
|
||||
"severity",
|
||||
"reason",
|
||||
|
|
@ -982,8 +981,7 @@
|
|||
"minLength": 1
|
||||
},
|
||||
"splitTarget": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
"type": "string"
|
||||
},
|
||||
"manifestPath": {
|
||||
"type": "string",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
"pluginId",
|
||||
"title",
|
||||
"owner",
|
||||
"incubation",
|
||||
"componentKinds",
|
||||
"commands",
|
||||
"runtime",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
param(
|
||||
[string[]] $HandoffPaths = @(
|
||||
"plugins\incubating\sai-vn.plugin-handoff.json",
|
||||
"plugins\incubating\norn-graph.plugin-handoff.json",
|
||||
"plugins\incubating\tex-math.plugin-handoff.json"
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -45,12 +45,9 @@ node $consumerScript $consumerExport `
|
|||
--expect-plugin norn.graph `
|
||||
--expect-plugin tex.math `
|
||||
--expect-plugin-handoff sai.vn `
|
||||
--expect-plugin-handoff norn.graph `
|
||||
--expect-plugin-handoff tex.math `
|
||||
--expect-plugin-handoff-move sai.vn:plugin-manifest:current:exists:sai-vn.plugin.json `
|
||||
--expect-plugin-handoff-move sai.vn:abi-conformance:current:exists:sai-vn.plugin-abi-fixture.json `
|
||||
--expect-plugin-handoff-move norn.graph:plugin-manifest:current:exists:norn-graph.plugin.json `
|
||||
--expect-plugin-handoff-move norn.graph:abi-conformance:current:exists:norn-graph.plugin-abi-fixture.json `
|
||||
--expect-plugin-handoff-move tex.math:plugin-manifest:current:exists:tex-math.plugin.json `
|
||||
--expect-plugin-handoff-move tex.math:abi-conformance:current:exists:tex-math.plugin-abi-fixture.json `
|
||||
--expect-plugin-operation sai.vn:describe `
|
||||
|
|
@ -66,12 +63,8 @@ node $consumerScript $consumerExport `
|
|||
--expect-plugin-operation norn.graph:describe `
|
||||
--expect-plugin-operation norn.graph:validate `
|
||||
--expect-plugin-operation norn.graph:project `
|
||||
--expect-plugin-operation norn.graph:lower `
|
||||
--expect-plugin-operation norn.graph:measure `
|
||||
--expect-plugin-operation norn.graph:apply `
|
||||
--expect-plugin-abi-operation-coverage norn.graph:describe:contracted:Norn `
|
||||
--expect-plugin-abi-operation-coverage norn.graph:lower:contracted:Norn `
|
||||
--expect-plugin-abi-operation-coverage norn.graph:apply:contracted:Norn `
|
||||
--expect-provider-plugin-requirement gamecult.home.vn:sai.visual_novel.surface:norn.graph:optional-satisfied:Norn:optional-nested `
|
||||
--expect-provider-plugin-requirement gamecult.home.vn:sai.visual_novel.surface:tex.math:optional-satisfied:EvePlugins:optional-nested `
|
||||
--expect-independent-nested-plugin gamecult.home.vn:sai.visual_novel.surface:sai.vn:norn.graph:Norn `
|
||||
|
|
@ -96,15 +89,13 @@ node $consumerScript $consumerExport `
|
|||
--expect-plugin-abi-field sai.vn:lower:expect.commandEnvelope:gamecult.eve.command.v1 `
|
||||
--expect-plugin-abi-field sai.vn:apply:expect.receiptSchema:gamecult.eve.command_receipt.v1 `
|
||||
--expect-plugin-runtime norn.graph:executable-sidecar `
|
||||
--expect-plugin-runtime-transport norn.graph:cultmesh `
|
||||
--expect-plugin-runtime-transport norn.graph:stdio `
|
||||
--expect-plugin-runtime-authority norn.graph:no-provider-state-mutation `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.processKind:long-running-daemon `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.protocol:cultmesh-rpc-with-stdio-dev-transport `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.protocol:stdio-ndjson `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.requestSchema:gamecult.eve.plugin_abi.request.v1 `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.responseSchema:gamecult.eve.plugin_abi.response.v1 `
|
||||
--expect-plugin-runtime-field norn.graph:sidecar.stateAuthority:proposes-plugin-state-only-provider-accepts `
|
||||
--expect-plugin-abi-field norn.graph:lower:expect.commandEnvelope:gamecult.eve.command.v1 `
|
||||
--expect-plugin-abi-field norn.graph:apply:expect.receiptSchema:gamecult.eve.command_receipt.v1 `
|
||||
--expect-plugin-operation tex.math:describe `
|
||||
--expect-plugin-operation tex.math:validate `
|
||||
--expect-plugin-operation tex.math:project `
|
||||
|
|
|
|||
|
|
@ -1129,9 +1129,10 @@ function validateWorldSurfaceLoweringGaps(gaps, errors) {
|
|||
function validatePluginRecords(plugins, errors) {
|
||||
for (const plugin of plugins) {
|
||||
const label = `plugins:${plugin.pluginId || "unknown"}`;
|
||||
for (const field of ["pluginId", "status", "ownerRepo", "splitTarget", "manifestPath", "advertisementPath", "abiFixturePath"]) {
|
||||
for (const field of ["pluginId", "status", "ownerRepo", "manifestPath", "advertisementPath", "abiFixturePath"]) {
|
||||
if (!plugin?.[field]) errors.push(`${label}:${field}:missing`);
|
||||
}
|
||||
if (plugin.status !== "active" && !plugin.splitTarget) errors.push(`${label}:splitTarget:missing`);
|
||||
for (const field of ["capabilities", "abiOperations", "optionalPlugins"]) {
|
||||
if (!Array.isArray(plugin?.[field])) errors.push(`${label}:${field}:expected array`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -469,20 +469,18 @@
|
|||
{
|
||||
"pluginId": "norn.graph",
|
||||
"title": "Norn Graph",
|
||||
"kind": "external-owner-planned",
|
||||
"kind": "external-owner",
|
||||
"ownerRepo": "Norn",
|
||||
"repoRole": "plugin-incubating",
|
||||
"splitTarget": "Norn/eve-plugin-graph",
|
||||
"graduationTrigger": "Split when embed.norn graph layout, interaction, fallback, and conformance fixtures are stable.",
|
||||
"repoRole": "plugin-owner",
|
||||
"capabilities": ["embed.norn", "graph.node.activate"],
|
||||
"expectedRuntime": {
|
||||
"invocationModel": "executable-sidecar",
|
||||
"contract": "gamecult.eve.plugin_abi.v1",
|
||||
"transports": ["cultmesh", "stdio"],
|
||||
"transports": ["stdio"],
|
||||
"authority": ["renderer-independent", "no-provider-state-mutation", "provider-accepts-or-denies-commands"],
|
||||
"sidecar": {
|
||||
"processKind": "long-running-daemon",
|
||||
"protocol": "cultmesh-rpc-with-stdio-dev-transport",
|
||||
"protocol": "stdio-ndjson",
|
||||
"requestSchema": "gamecult.eve.plugin_abi.request.v1",
|
||||
"responseSchema": "gamecult.eve.plugin_abi.response.v1",
|
||||
"commandEnvelope": "gamecult.eve.command.v1",
|
||||
|
|
@ -492,17 +490,15 @@
|
|||
},
|
||||
"requiredFixtures": [],
|
||||
"schemaPath": "schemas/gamecult.eve.plugin.v1.schema.json",
|
||||
"manifestPath": "plugins/incubating/norn-graph.plugin.json",
|
||||
"abiFixturePath": "plugins/incubating/norn-graph.plugin-abi-fixture.json",
|
||||
"handoffPath": "plugins/incubating/norn-graph.plugin-handoff.json",
|
||||
"manifestPath": "../Norn/plugins/norn-graph.plugin.json",
|
||||
"abiFixturePath": "../Norn/plugins/norn-graph.plugin-abi-fixture.json",
|
||||
"advertisementSchemaPath": "schemas/gamecult.eve.plugin_advertisement.v1.schema.json",
|
||||
"advertisementPath": "plugins/incubating/norn-graph.plugin-advertisement.json",
|
||||
"advertisementPath": "../Norn/plugins/norn-graph.plugin-advertisement.json",
|
||||
"expectedPaths": [
|
||||
"plugins/incubating/norn-graph.plugin.json",
|
||||
"plugins/incubating/norn-graph.plugin-abi-fixture.json",
|
||||
"plugins/incubating/norn-graph.plugin-advertisement.json",
|
||||
"plugins/incubating/norn-graph.plugin-handoff.json",
|
||||
"scripts/run-plugin-handoff-smoke.ps1"
|
||||
"../Norn/plugins/norn-graph.plugin.json",
|
||||
"../Norn/plugins/norn-graph.plugin-abi-fixture.json",
|
||||
"../Norn/plugins/norn-graph.plugin-advertisement.json",
|
||||
"../Norn/crates/norn-eve-plugin/src/main.rs"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -621,7 +621,9 @@ async function evaluatePlugin(plugin, fixtureResults) {
|
|||
? "invalid-plugin-handoff"
|
||||
: plugin.kind === "incubating"
|
||||
? "incubating"
|
||||
: "external-owner-planned";
|
||||
: plugin.kind === "external-owner"
|
||||
? "active"
|
||||
: "external-owner-planned";
|
||||
|
||||
return {
|
||||
pluginId: plugin.pluginId,
|
||||
|
|
@ -978,7 +980,7 @@ function validateProviderPluginRequirements(provider, requirements, pluginResult
|
|||
if (!optional) errors.push(`${provider.advertisementPath}:${requirement.surfaceId}:plugin:${requirement.pluginId}:missing`);
|
||||
continue;
|
||||
}
|
||||
if (plugin.status !== "incubating" && plugin.status !== "external-owner-planned") {
|
||||
if (!["active", "incubating", "external-owner-planned"].includes(plugin.status)) {
|
||||
errors.push(`${provider.advertisementPath}:${requirement.surfaceId}:plugin:${requirement.pluginId}:status:${plugin.status}`);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1141,7 +1143,8 @@ async function validatePluginAbiFixture(plugin) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const operation of ["describe", "validate", "project", "lower", "measure", "apply"]) {
|
||||
const claimedOperations = pluginManifest.runtime?.sidecar?.operations || [];
|
||||
for (const operation of claimedOperations) {
|
||||
if (!operations.has(operation)) errors.push(`${plugin.abiFixturePath}:operation:${operation}:missing`);
|
||||
}
|
||||
errors.push(...missingMembers(
|
||||
|
|
@ -1150,7 +1153,8 @@ async function validatePluginAbiFixture(plugin) {
|
|||
`${plugin.manifestPath}:runtime.sidecar.operations`,
|
||||
));
|
||||
|
||||
if (!(pluginManifest.abiFixtures || []).includes(plugin.abiFixturePath)) {
|
||||
const fixtureBasename = path.basename(plugin.abiFixturePath);
|
||||
if (!(pluginManifest.abiFixtures || []).some(candidate => path.basename(candidate) === fixtureBasename)) {
|
||||
errors.push(`${plugin.manifestPath}:abiFixtures:${plugin.abiFixturePath}:missing`);
|
||||
}
|
||||
|
||||
|
|
@ -1173,34 +1177,40 @@ async function validatePluginAbiFixture(plugin) {
|
|||
errors.push(...missingMembers(manifestComponentKinds, project.ownedComponentKinds || [], `${plugin.abiFixturePath}:project.ownedComponentKinds`));
|
||||
if (!project.projectionKind) errors.push(`${plugin.abiFixturePath}:project.projectionKind:missing`);
|
||||
|
||||
const lower = operations.get("lower")?.expect || {};
|
||||
errors.push(...missingMembers(manifestComponentKinds, lower.preservedComponentKinds || [], `${plugin.abiFixturePath}:lower.preservedComponentKinds`));
|
||||
if (!lower.loweringKind) errors.push(`${plugin.abiFixturePath}:lower.loweringKind:missing`);
|
||||
|
||||
const measure = operations.get("measure")?.expect || {};
|
||||
if (!measure.measurementKind) errors.push(`${plugin.abiFixturePath}:measure.measurementKind:missing`);
|
||||
if (!(measure.measurementOutputs || []).length) errors.push(`${plugin.abiFixturePath}:measure.measurementOutputs:missing`);
|
||||
if (measure.preservesProviderAuthority !== true) errors.push(`${plugin.abiFixturePath}:measure.preservesProviderAuthority:expected true`);
|
||||
|
||||
const apply = operations.get("apply")?.expect || {};
|
||||
if (apply.receiptSchema !== sidecarReceiptSchema) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.receiptSchema:expected ${sidecarReceiptSchema} got ${apply.receiptSchema || ""}`);
|
||||
if (claimedOperations.includes("lower")) {
|
||||
const lower = operations.get("lower")?.expect || {};
|
||||
errors.push(...missingMembers(manifestComponentKinds, lower.preservedComponentKinds || [], `${plugin.abiFixturePath}:lower.preservedComponentKinds`));
|
||||
if (!lower.loweringKind) errors.push(`${plugin.abiFixturePath}:lower.loweringKind:missing`);
|
||||
}
|
||||
if (manifestCommands.length) {
|
||||
const commandEffects = apply.commandEffects || {};
|
||||
for (const command of manifestCommands) {
|
||||
if (!commandEffects[command]) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.commandEffects:${command}:missing`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const expectedEffect = manifestCommandEffects.get(command);
|
||||
if (commandEffects[command] !== expectedEffect) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.commandEffects:${command}:expected ${expectedEffect} got ${commandEffects[command]}`);
|
||||
}
|
||||
if (claimedOperations.includes("measure")) {
|
||||
const measure = operations.get("measure")?.expect || {};
|
||||
if (!measure.measurementKind) errors.push(`${plugin.abiFixturePath}:measure.measurementKind:missing`);
|
||||
if (!(measure.measurementOutputs || []).length) errors.push(`${plugin.abiFixturePath}:measure.measurementOutputs:missing`);
|
||||
if (measure.preservesProviderAuthority !== true) errors.push(`${plugin.abiFixturePath}:measure.preservesProviderAuthority:expected true`);
|
||||
}
|
||||
|
||||
if (claimedOperations.includes("apply")) {
|
||||
const apply = operations.get("apply")?.expect || {};
|
||||
if (apply.receiptSchema !== sidecarReceiptSchema) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.receiptSchema:expected ${sidecarReceiptSchema} got ${apply.receiptSchema || ""}`);
|
||||
}
|
||||
if (manifestCommands.length) {
|
||||
const commandEffects = apply.commandEffects || {};
|
||||
for (const command of manifestCommands) {
|
||||
if (!commandEffects[command]) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.commandEffects:${command}:missing`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const expectedEffect = manifestCommandEffects.get(command);
|
||||
if (commandEffects[command] !== expectedEffect) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.commandEffects:${command}:expected ${expectedEffect} got ${commandEffects[command]}`);
|
||||
}
|
||||
}
|
||||
} else if (!(apply.stateEffects || []).length) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.stateEffects:missing`);
|
||||
}
|
||||
} else if (!(apply.stateEffects || []).length) {
|
||||
errors.push(`${plugin.abiFixturePath}:apply.stateEffects:missing`);
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push(`${plugin.abiFixturePath}:invalid-json:${error instanceof Error ? error.message : String(error)}`);
|
||||
|
|
@ -1862,6 +1872,7 @@ function evaluateSplitTargets(splitTargets, runtimeResults) {
|
|||
}
|
||||
|
||||
function requiredIncubationFields(entry) {
|
||||
if (entry.kind === "external-owner") return ["ownerRepo", "repoRole"];
|
||||
if (entry.repoRole === "core") return ["ownerRepo", "repoRole"];
|
||||
return ["ownerRepo", "repoRole", "graduationTrigger"];
|
||||
}
|
||||
|
|
@ -1993,8 +2004,8 @@ function summarize(fixtures, runtimes, plugins, providers, splitTargets) {
|
|||
passedFixtures: fixtures.filter(fixture => fixture.status === "pass").length,
|
||||
failedFixtures: fixtures.filter(fixture => fixture.status !== "pass").length,
|
||||
totalPlugins: plugins.length,
|
||||
healthyPlugins: plugins.filter(plugin => plugin.status === "incubating" || plugin.status === "external-owner-planned").length,
|
||||
failedPlugins: plugins.filter(plugin => plugin.status !== "incubating" && plugin.status !== "external-owner-planned").length,
|
||||
healthyPlugins: plugins.filter(plugin => ["active", "incubating", "external-owner-planned"].includes(plugin.status)).length,
|
||||
failedPlugins: plugins.filter(plugin => !["active", "incubating", "external-owner-planned"].includes(plugin.status)).length,
|
||||
totalProviders: providers.length,
|
||||
advertisedProviders: providers.filter(provider => provider.status === "advertised").length,
|
||||
failedProviders: providers.filter(provider => provider.status !== "advertised").length,
|
||||
|
|
|
|||
Loading…
Reference in a new issue