Graduate Norn graph semantics from Eve
This commit is contained in:
parent
be6aeb8bf8
commit
f9a2b6a6d6
6 changed files with 58 additions and 61 deletions
|
|
@ -52,16 +52,16 @@ advertisements and typed command/receipt documents are the boundary.
|
|||
- EveUnity's clean `TestProject` owns generic scene and UI Toolkit package
|
||||
verification; ordinary runtime tests no longer open or mutate Aetheria.
|
||||
- EveUnity publishes immutable `0.1.0` Git package tags for surface and UI
|
||||
Toolkit plus scene `0.1.1`, whose generic CultMesh composition root discovers
|
||||
Toolkit plus scene `0.1.4`, whose generic CultMesh composition root discovers
|
||||
playable worlds without product identifiers. Its release-only consumer
|
||||
resolves those tags plus CultLib's assembled Unity package and passes 26
|
||||
resolves those tags plus CultLib's assembled Unity package and passes 30
|
||||
Unity EditMode tests without sibling package paths. Aetheria pins the same
|
||||
released sources.
|
||||
- The same released-package consumer cold-starts from Aetheria's CultMesh
|
||||
rendezvous endpoint with no configured provider or surface ID, discovers the
|
||||
daemon's `interactive-world`, loads provider-owned assets, and reconciles
|
||||
movement, targeting, and action receipts without importing Aetheria code.
|
||||
- Aetheria pins the same scene `0.1.1` release; no Aetheria Unity component
|
||||
- Aetheria pins the same scene `0.1.4` release; no Aetheria Unity component
|
||||
constructs the generic CultMesh client transport used by that witness.
|
||||
- EveUnity can start from one CultMesh rendezvous endpoint, discover a Verse,
|
||||
select an advertised `interactive-world` surface, and connect without
|
||||
|
|
@ -106,6 +106,9 @@ advertisements and typed command/receipt documents are the boundary.
|
|||
sessions and Norn serves graph projection and measurement through CultNet
|
||||
RUDP operation envelopes. A Sai surface may request
|
||||
nested Norn or TeX capabilities when those plugins are available.
|
||||
- Norn owns the nested graph document, layout semantics, runtime advertisement,
|
||||
ABI fixture, and conformance evidence. Eve's Sai contract fixture carries only
|
||||
an `embed.norn` capability request and Norn-owned CultMesh document reference.
|
||||
- EvePlugins owns the TeX sidecar and KaTeX-backed semantic witness.
|
||||
- EvePlugins owns the independent `fields.surface` sidecar, generic
|
||||
`gamecult.fields.*` document model, fixtures, tests, and CultNet witness.
|
||||
|
|
@ -114,7 +117,8 @@ advertisements and typed command/receipt documents are the boundary.
|
|||
- Aetheria publishes objects, gravity, and render splats as
|
||||
`gamecult.fields.*` documents and advertises `fields.surface` on graphical
|
||||
surfaces that use them. Hermodr carries decoded MessagePack values without
|
||||
interpreting field tuples; the browser fields adapter owns that conversion.
|
||||
interpreting field schemas or tuples; each runtime's Fields adapter owns
|
||||
conversion and projection.
|
||||
- The browser fields adapter owns field component matching, canvas lifecycle,
|
||||
provider-document polling, tuple conversion, Canvas/WebGL projection, GPU
|
||||
resources, asset overlays, and capability-gap reporting. The general CultUI
|
||||
|
|
@ -172,8 +176,6 @@ advertisements and typed command/receipt documents are the boundary.
|
|||
- Publish the shared TypeScript and Rust CultNet operation hosts from tagged
|
||||
CultLib releases. Sai, Norn, and TeX prove the same operation envelope across
|
||||
both language implementations; stdio remains a local diagnostic adapter.
|
||||
- Graduate remaining graph fixture ownership fully to Norn once no Eve fixture
|
||||
is its semantic owner. Sai already owns VN/Ink execution and its live witness.
|
||||
- Keep nested plugin availability explicit and non-transitive: Sai does not own
|
||||
Norn or TeX.
|
||||
- Move any remaining provider-specific field source composition only when it
|
||||
|
|
|
|||
|
|
@ -169,27 +169,24 @@ typesetting semantics.
|
|||
`embed.norn` means "run Norn here." It is not a request to draw a static graph
|
||||
with whatever local widget happens to be nearby.
|
||||
|
||||
Minimum props:
|
||||
Minimum boundary:
|
||||
|
||||
- `engine.id`: `norn`
|
||||
- `engine.contract`: Norn surface contract id, currently
|
||||
`gamecult.norn.surface.v1`.
|
||||
- `engine.web.wasm`: optional WASM asset for browser clients.
|
||||
- `engine.native.rustCrate`: native solver crate, usually `norn-rs`.
|
||||
- `layout`: layout mode and solver knobs.
|
||||
- `graph.nodes` and `graph.edges`: provider graph state.
|
||||
- `interaction.nodeAction`: command emitted when a node is activated.
|
||||
- `placement`: scene placement instructions.
|
||||
- `pluginId`: `norn.graph`.
|
||||
- `capability`: `embed.norn`.
|
||||
- an embedded-document slot with `schemaId: norn.graph.document.v1` and a
|
||||
provider/Norn-owned CultMesh `documentId`.
|
||||
- `interaction.nodeAction`: command emitted to the composing provider when a
|
||||
node is activated.
|
||||
- `placement`: scene placement instructions owned by the composing surface.
|
||||
|
||||
Each target renderer embeds Norn by using the strongest local path available:
|
||||
Graph nodes, edges, solver settings, runtime packages, WASM assets, and native
|
||||
crate hints belong to Norn's document and plugin advertisement. They are not
|
||||
inline Eve or Sai surface semantics.
|
||||
|
||||
- Web: Norn WASM / `@gamecult/norn-viewer`.
|
||||
- iOS: native graph view using the Norn layout output, eventually Rust FFI.
|
||||
- Android: native graph view using the same Norn contract, eventually Rust FFI.
|
||||
- Windows Direct2D: Norn layout lowered to Direct2D/DirectWrite primitives.
|
||||
|
||||
If a client cannot run Norn, it must report a capability gap. It may show a
|
||||
read-only fallback, but it must not silently pretend the fallback is full Norn.
|
||||
The Norn plugin advertisement declares its invocation and projection paths. A
|
||||
runtime resolves the advertised `embed.norn` capability without importing Norn
|
||||
internals. If it cannot do so, it must report a capability gap. It may show a
|
||||
read-only fallback, but it must not silently claim full Norn support.
|
||||
|
||||
### `embed.tex`
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,11 @@
|
|||
"path": "web/fixtures/sai-vn-surface.json"
|
||||
},
|
||||
"purpose": "Proves a Sai-owned visual-novel plugin surface can compose independently-owned Norn and TeX nested surfaces.",
|
||||
"exitCriteria": "Provider scenarios remain in Eve only as contract fixtures; Sai owns VN/Ink story state, commands, projection, and plugin ABI cases.",
|
||||
"exitCriteria": "Provider scenarios remain in Eve only as contract fixtures; Sai owns VN/Ink state and commands, while Norn and TeX own their nested documents, semantics, runtime advertisements, and plugin ABI cases.",
|
||||
"asserts": [
|
||||
"vn.stage component",
|
||||
"embed.norn component",
|
||||
"Norn-owned embedded graph document reference",
|
||||
"embed.tex component",
|
||||
"story command descriptors",
|
||||
"required Sai plugin capability",
|
||||
|
|
|
|||
|
|
@ -57,43 +57,21 @@
|
|||
{
|
||||
"id": "sai.graph",
|
||||
"kind": "embed.norn",
|
||||
"embeddedDocuments": [
|
||||
{
|
||||
"slotId": "graph",
|
||||
"documentId": "cultmesh://norn/graphs/sai-nested-norn",
|
||||
"schemaId": "norn.graph.document.v1",
|
||||
"presentationKind": "embed.norn"
|
||||
}
|
||||
],
|
||||
"props": {
|
||||
"label": "GameCult Ink Knot Graph",
|
||||
"engine": {
|
||||
"id": "norn",
|
||||
"contract": "gamecult.norn.surface.v1",
|
||||
"web": {
|
||||
"wasm": "/static/interactive/norn/norn-rs.wasm",
|
||||
"package": "@gamecult/norn-viewer"
|
||||
},
|
||||
"native": {
|
||||
"rustCrate": "norn-rs",
|
||||
"direct2dAdapter": "fensalir.norn.direct2d"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"mode": "norn.2d",
|
||||
"iterations": 220,
|
||||
"rankGap": 150,
|
||||
"nodeGap": 88,
|
||||
"edgeLength": 132
|
||||
},
|
||||
"graph": {
|
||||
"nodes": [
|
||||
{ "id": "hub", "label": "Hub", "target": "hub", "x": 0.2, "y": 0.2, "current": true },
|
||||
{ "id": "eve", "label": "Eve", "target": "eve", "x": 0.72, "y": 0.24 },
|
||||
{ "id": "sai", "label": "Sai", "target": "sai", "x": 0.48, "y": 0.55 }
|
||||
],
|
||||
"edges": [
|
||||
{ "source": "hub", "target": "eve" },
|
||||
{ "source": "hub", "target": "sai" },
|
||||
{ "source": "sai", "target": "eve" }
|
||||
]
|
||||
},
|
||||
"pluginId": "norn.graph",
|
||||
"capability": "embed.norn",
|
||||
"interaction": {
|
||||
"nodeAction": "story.jump",
|
||||
"focusFollowsStory": true,
|
||||
"rendererMustUseNorn": true
|
||||
"focusFollowsStory": true
|
||||
},
|
||||
"placement": {
|
||||
"space": "scene",
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@
|
|||
"kind": "owner-repo",
|
||||
"ref": "Sai",
|
||||
"summary": "Sai owns VN/Ink semantics once the plugin ABI graduates; Eve only hosts this fixture while the contract is forming."
|
||||
},
|
||||
{
|
||||
"kind": "plugin-advertisement",
|
||||
"ref": "Norn/plugins/norn-graph.plugin-advertisement.json",
|
||||
"summary": "Norn owns graph documents, layout semantics, runtime hints, and graph conformance fixtures."
|
||||
}
|
||||
],
|
||||
"surfaces": [
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { findProviderCatalogEntry, mergeProviderAdvertisement } from "./provider
|
|||
const catalog = JSON.parse(readFileSync(new URL("./local-provider-catalog.json", import.meta.url), "utf8"));
|
||||
const worldSmokeAdvertisement = JSON.parse(readFileSync(new URL("./fixtures/eve-world-smoke.provider-advertisement.json", import.meta.url), "utf8"));
|
||||
const saiAdvertisement = JSON.parse(readFileSync(new URL("./fixtures/sai-vn.provider-advertisement.json", import.meta.url), "utf8"));
|
||||
const saiSurface = JSON.parse(readFileSync(new URL("./fixtures/sai-vn-surface.json", import.meta.url), "utf8"));
|
||||
|
||||
test("merges generic world fixture transport with advertised world interaction", () => {
|
||||
const catalogProvider = findProviderCatalogEntry(catalog, "eve.world-smoke");
|
||||
|
|
@ -43,3 +44,16 @@ test("preserves Sai required and optional nested plugin requirements from advert
|
|||
assert.deepEqual(byPlugin.get("tex.math").requiredCapabilities, []);
|
||||
assert.deepEqual(byPlugin.get("tex.math").optionalCapabilities, ["embed.tex"]);
|
||||
});
|
||||
|
||||
test("composes Norn by advertised capability and owner document", () => {
|
||||
const norn = saiSurface.surface.root.children.find(component => component.kind === "embed.norn");
|
||||
const [graphDocument] = norn.embeddedDocuments;
|
||||
|
||||
assert.equal(norn.props.pluginId, "norn.graph");
|
||||
assert.equal(norn.props.capability, "embed.norn");
|
||||
assert.equal(graphDocument.schemaId, "norn.graph.document.v1");
|
||||
assert.equal(graphDocument.documentId, "cultmesh://norn/graphs/sai-nested-norn");
|
||||
assert.equal("engine" in norn.props, false);
|
||||
assert.equal("layout" in norn.props, false);
|
||||
assert.equal("graph" in norn.props, false);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue