Separate command descriptors from invocations

This commit is contained in:
Meta Vens 2026-07-10 04:03:05 +01:00
commit 80dae63a57
44 changed files with 438 additions and 86 deletions

View file

@ -292,6 +292,12 @@ Exit criteria:
Recently cut: Recently cut:
- Eve core now publishes typed CultCache wire documents for provider
advertisement, command invocation, and provider receipt. Command descriptors
remain `gamecult.eve.command.v1`; executable intents are the distinct
`gamecult.eve.command_invocation.v1` contract. Receipts carry the provider's
source version, and EveUnity withholds terminal receipts until that version
is actually lowered.
- EveUnity now owns a minimal clean `TestProject` that installs CultLib, Eve - EveUnity now owns a minimal clean `TestProject` that installs CultLib, Eve
surface contracts, and the EveUnity scene package without Aetheria code. Its surface contracts, and the EveUnity scene package without Aetheria code. Its
generic `eve.world-smoke` PlayMode test lowers a world, routes a command generic `eve.world-smoke` PlayMode test lowers a world, routes a command

View file

@ -232,12 +232,13 @@ report the degradation.
## Commands ## Commands
Commands use `gamecult.eve.command.v1`: Authored command descriptors use `gamecult.eve.command.v1`. Runtime command
invocations use `gamecult.eve.command_invocation.v1`:
```json ```json
{ {
"type": "surface-command", "type": "surface-command",
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"providerId": "gamecult.home.vn", "providerId": "gamecult.home.vn",
"surfaceId": "sai.visual_novel.surface", "surfaceId": "sai.visual_novel.surface",
"command": "story.choose", "command": "story.choose",

View file

@ -323,7 +323,7 @@ EveCommandIntent createEveCommandIntent(
) { ) {
return EveCommandIntent( return EveCommandIntent(
type: 'surface-command', type: 'surface-command',
schema: 'gamecult.eve.command.v1', schema: 'gamecult.eve.command_invocation.v1',
providerId: state.providerId, providerId: state.providerId,
surfaceId: state.surfaceId, surfaceId: state.surfaceId,
command: command, command: command,

View file

@ -114,7 +114,7 @@ void main() {
await tester.pump(); await tester.pump();
expect(intents, hasLength(1)); expect(intents, hasLength(1));
expect(intents.single.schema, 'gamecult.eve.command.v1'); expect(intents.single.schema, 'gamecult.eve.command_invocation.v1');
expect(intents.single.providerId, 'aetheria'); expect(intents.single.providerId, 'aetheria');
expect(intents.single.surfaceId, 'aetheria.daemon.game'); expect(intents.single.surfaceId, 'aetheria.daemon.game');
expect(intents.single.command, 'aetheria.daemon.commands'); expect(intents.single.command, 'aetheria.daemon.commands');

View file

@ -35,7 +35,7 @@ export type EveSurfaceStyles = {
}>; }>;
export interface EveCommandIntent { export interface EveCommandIntent {
type: "surface-command"; type: "surface-command";
schema: "gamecult.eve.command.v1"; schema: "gamecult.eve.command_invocation.v1";
providerId: string; providerId: string;
surfaceId: string; surfaceId: string;
command: string; command: string;

View file

@ -1847,7 +1847,7 @@ export function createEveCommandIntent(commandId, props = {}, options = currentO
const receiptSchema = firstString(worldInteraction.receiptSchema, props.receiptSchema, action.receiptSchema); const receiptSchema = firstString(worldInteraction.receiptSchema, props.receiptSchema, action.receiptSchema);
const intent = { const intent = {
type: "surface-command", type: "surface-command",
schema: "gamecult.eve.command.v1", schema: "gamecult.eve.command_invocation.v1",
providerId, providerId,
surfaceId, surfaceId,
command: commandId || stringProp(action.type, "invoke"), command: commandId || stringProp(action.type, "invoke"),

View file

@ -33,7 +33,7 @@ export type EveSurfaceStyles =
export interface EveCommandIntent { export interface EveCommandIntent {
type: "surface-command"; type: "surface-command";
schema: "gamecult.eve.command.v1"; schema: "gamecult.eve.command_invocation.v1";
providerId: string; providerId: string;
surfaceId: string; surfaceId: string;
command: string; command: string;
@ -2200,7 +2200,7 @@ export function createEveCommandIntent(
const receiptSchema = firstString(worldInteraction.receiptSchema, props.receiptSchema, action.receiptSchema); const receiptSchema = firstString(worldInteraction.receiptSchema, props.receiptSchema, action.receiptSchema);
const intent: EveCommandIntent = { const intent: EveCommandIntent = {
type: "surface-command", type: "surface-command",
schema: "gamecult.eve.command.v1", schema: "gamecult.eve.command_invocation.v1",
providerId, providerId,
surfaceId, surfaceId,
command: commandId || stringProp(action.type, "invoke"), command: commandId || stringProp(action.type, "invoke"),

View file

@ -0,0 +1,261 @@
using System;
using System.Collections.Generic;
using GameCult.Caching;
using MessagePack;
#nullable enable
namespace GameCult.Eve.Surface
{
[CultDocument("gamecult.eve.provider_advertisement", SchemaId)]
[MessagePackObject]
public sealed class EveProviderAdvertisementDocument
{
public const string SchemaId = "gamecult.eve.provider_advertisement.v1";
public EveProviderAdvertisementDocument(
string providerId,
string serviceId,
string verseId,
string title,
string kind,
string cultMeshAddress,
string updatedAtUtc,
EveProviderFreshness freshness,
IReadOnlyList<string> schemas,
IReadOnlyList<EveProviderWitness> witnesses,
IReadOnlyList<EveAdvertisedSurface> surfaces,
IReadOnlyList<EveAdvertisedCommand> commands)
: this(SchemaId, providerId, serviceId, verseId, title, kind, cultMeshAddress, updatedAtUtc, freshness, schemas, witnesses, surfaces, commands)
{
}
[SerializationConstructor]
public EveProviderAdvertisementDocument(
string schema,
string providerId,
string serviceId,
string verseId,
string title,
string kind,
string cultMeshAddress,
string updatedAtUtc,
EveProviderFreshness freshness,
IReadOnlyList<string> schemas,
IReadOnlyList<EveProviderWitness> witnesses,
IReadOnlyList<EveAdvertisedSurface> surfaces,
IReadOnlyList<EveAdvertisedCommand> commands)
{
Schema = string.IsNullOrWhiteSpace(schema) ? SchemaId : schema;
ProviderId = providerId ?? "";
ServiceId = serviceId ?? "";
VerseId = verseId ?? "";
Title = title ?? "";
Kind = kind ?? "";
CultMeshAddress = cultMeshAddress ?? "";
UpdatedAtUtc = updatedAtUtc ?? "";
Freshness = freshness ?? new EveProviderFreshness("unknown", "", 0);
Schemas = schemas ?? Array.Empty<string>();
Witnesses = witnesses ?? Array.Empty<EveProviderWitness>();
Surfaces = surfaces ?? Array.Empty<EveAdvertisedSurface>();
Commands = commands ?? Array.Empty<EveAdvertisedCommand>();
}
[Key(0)] public string Schema { get; }
[Key(1)] public string ProviderId { get; }
[Key(2)] public string ServiceId { get; }
[Key(3)] public string VerseId { get; }
[Key(4)] public string Title { get; }
[Key(5)] public string Kind { get; }
[Key(6)] public string CultMeshAddress { get; }
[Key(7)] public string UpdatedAtUtc { get; }
[Key(8)] public EveProviderFreshness Freshness { get; }
[Key(9)] public IReadOnlyList<string> Schemas { get; }
[Key(10)] public IReadOnlyList<EveProviderWitness> Witnesses { get; }
[Key(11)] public IReadOnlyList<EveAdvertisedSurface> Surfaces { get; }
[Key(12)] public IReadOnlyList<EveAdvertisedCommand> Commands { get; }
}
[MessagePackObject]
public sealed class EveProviderFreshness
{
[SerializationConstructor]
public EveProviderFreshness(string state, string lastSeenAtUtc, long maxAgeMs)
{
State = state ?? "";
LastSeenAtUtc = lastSeenAtUtc ?? "";
MaxAgeMs = maxAgeMs;
}
[Key(0)] public string State { get; }
[Key(1)] public string LastSeenAtUtc { get; }
[Key(2)] public long MaxAgeMs { get; }
}
[MessagePackObject]
public sealed class EveProviderWitness
{
[SerializationConstructor]
public EveProviderWitness(string kind, string reference, string summary)
{
Kind = kind ?? "";
Reference = reference ?? "";
Summary = summary ?? "";
}
[Key(0)] public string Kind { get; }
[Key(1)] public string Reference { get; }
[Key(2)] public string Summary { get; }
}
[MessagePackObject]
public sealed class EveAdvertisedSurface
{
[SerializationConstructor]
public EveAdvertisedSurface(
string surfaceId,
string schema,
string recordRef,
string transport,
string status,
string surfaceKind,
EveWorldInteractionAdvertisement? worldInteraction = null)
{
SurfaceId = surfaceId ?? "";
Schema = schema ?? "";
RecordRef = recordRef ?? "";
Transport = transport ?? "";
Status = status ?? "";
SurfaceKind = surfaceKind ?? "";
WorldInteraction = worldInteraction;
}
[Key(0)] public string SurfaceId { get; }
[Key(1)] public string Schema { get; }
[Key(2)] public string RecordRef { get; }
[Key(3)] public string Transport { get; }
[Key(4)] public string Status { get; }
[Key(5)] public string SurfaceKind { get; }
[Key(6)] public EveWorldInteractionAdvertisement? WorldInteraction { get; }
}
[MessagePackObject]
public sealed class EveWorldInteractionAdvertisement
{
[SerializationConstructor]
public EveWorldInteractionAdvertisement(
string projectionKind,
IReadOnlyList<string> stateSchemas,
string commandBoundary,
string commandRecordRef,
string receiptSchema,
string receiptRecordRef,
string assetManifestRecordRef,
IReadOnlyList<string> loweringTargets,
string ownership)
{
ProjectionKind = projectionKind ?? "";
StateSchemas = stateSchemas ?? Array.Empty<string>();
CommandBoundary = commandBoundary ?? "";
CommandRecordRef = commandRecordRef ?? "";
ReceiptSchema = receiptSchema ?? "";
ReceiptRecordRef = receiptRecordRef ?? "";
AssetManifestRecordRef = assetManifestRecordRef ?? "";
LoweringTargets = loweringTargets ?? Array.Empty<string>();
Ownership = ownership ?? "";
}
[Key(0)] public string ProjectionKind { get; }
[Key(1)] public IReadOnlyList<string> StateSchemas { get; }
[Key(2)] public string CommandBoundary { get; }
[Key(3)] public string CommandRecordRef { get; }
[Key(4)] public string ReceiptSchema { get; }
[Key(5)] public string ReceiptRecordRef { get; }
[Key(6)] public string AssetManifestRecordRef { get; }
[Key(7)] public IReadOnlyList<string> LoweringTargets { get; }
[Key(8)] public string Ownership { get; }
}
[MessagePackObject]
public sealed class EveAdvertisedCommand
{
[SerializationConstructor]
public EveAdvertisedCommand(string command, string surfaceId, string transport, string summary)
{
Command = command ?? "";
SurfaceId = surfaceId ?? "";
Transport = transport ?? "";
Summary = summary ?? "";
}
[Key(0)] public string Command { get; }
[Key(1)] public string SurfaceId { get; }
[Key(2)] public string Transport { get; }
[Key(3)] public string Summary { get; }
}
[CultDocument("gamecult.eve.command_receipt", SchemaId)]
[MessagePackObject]
public sealed class EveCommandReceiptDocument
{
public const string SchemaId = "gamecult.eve.command_receipt.v1";
public EveCommandReceiptDocument(
string receiptId,
string commandId,
string command,
string state,
string ownerRepo,
string authority,
string providerId,
string surfaceId,
string message,
string issuedAtUtc,
long sourceVersion)
: this(SchemaId, receiptId, commandId, command, state, ownerRepo, authority, providerId, surfaceId, message, issuedAtUtc, sourceVersion)
{
}
[SerializationConstructor]
public EveCommandReceiptDocument(
string schema,
string receiptId,
string commandId,
string command,
string state,
string ownerRepo,
string authority,
string providerId,
string surfaceId,
string message,
string issuedAtUtc,
long sourceVersion)
{
Schema = string.IsNullOrWhiteSpace(schema) ? SchemaId : schema;
ReceiptId = receiptId ?? "";
CommandId = commandId ?? "";
Command = command ?? "";
State = state ?? "";
OwnerRepo = ownerRepo ?? "";
Authority = authority ?? "";
ProviderId = providerId ?? "";
SurfaceId = surfaceId ?? "";
Message = message ?? "";
IssuedAtUtc = issuedAtUtc ?? "";
SourceVersion = sourceVersion;
}
[Key(0)] public string Schema { get; }
[Key(1)] public string ReceiptId { get; }
[Key(2)] public string CommandId { get; }
[Key(3)] public string Command { get; }
[Key(4)] public string State { get; }
[Key(5)] public string OwnerRepo { get; }
[Key(6)] public string Authority { get; }
[Key(7)] public string ProviderId { get; }
[Key(8)] public string SurfaceId { get; }
[Key(9)] public string Message { get; }
[Key(10)] public string IssuedAtUtc { get; }
[Key(11)] public long SourceVersion { get; }
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f7ea0cd07c4d5da4099b5acf8d44ca2e

View file

@ -269,9 +269,11 @@ namespace GameCult.Eve.Surface
public string Transport => Operation.RouteHint.Description ?? ""; public string Transport => Operation.RouteHint.Description ?? "";
} }
[CultDocument("gamecult.eve.command", SchemaId)]
[MessagePackObject]
public sealed class EveSurfaceCommandRequest public sealed class EveSurfaceCommandRequest
{ {
public const string SchemaId = "gamecult.eve.command.v1"; public const string SchemaId = "gamecult.eve.command_invocation.v1";
public EveSurfaceCommandRequest( public EveSurfaceCommandRequest(
string providerId, string providerId,
@ -282,7 +284,23 @@ namespace GameCult.Eve.Surface
string clientId, string clientId,
string commandBoundary = "", string commandBoundary = "",
string receiptSchema = "") string receiptSchema = "")
: this(SchemaId, providerId, surfaceId, operation, payload, issuedAt, clientId, commandBoundary, receiptSchema)
{ {
}
[SerializationConstructor]
public EveSurfaceCommandRequest(
string schema,
string providerId,
string surfaceId,
CultMeshOperationInvocationDescriptor operation,
CultMeshOperationPayload payload,
DateTimeOffset issuedAt,
string clientId,
string commandBoundary,
string receiptSchema)
{
Schema = string.IsNullOrWhiteSpace(schema) ? SchemaId : schema;
ProviderId = providerId; ProviderId = providerId;
SurfaceId = surfaceId; SurfaceId = surfaceId;
Operation = operation ?? throw new ArgumentNullException(nameof(operation)); Operation = operation ?? throw new ArgumentNullException(nameof(operation));
@ -293,24 +311,37 @@ namespace GameCult.Eve.Surface
ReceiptSchema = receiptSchema ?? ""; ReceiptSchema = receiptSchema ?? "";
} }
public string Schema => SchemaId; [Key(0)]
public string Schema { get; }
[Key(1)]
public string ProviderId { get; } public string ProviderId { get; }
[Key(2)]
public string SurfaceId { get; } public string SurfaceId { get; }
[Key(3)]
public CultMeshOperationInvocationDescriptor Operation { get; } public CultMeshOperationInvocationDescriptor Operation { get; }
[IgnoreMember]
public string Command => Operation.OperationId; public string Command => Operation.OperationId;
[Key(4)]
public CultMeshOperationPayload Payload { get; } public CultMeshOperationPayload Payload { get; }
[Key(5)]
public DateTimeOffset IssuedAt { get; } public DateTimeOffset IssuedAt { get; }
[Key(6)]
public string ClientId { get; } public string ClientId { get; }
[Key(7)]
public string CommandBoundary { get; } public string CommandBoundary { get; }
[Key(8)]
public string ReceiptSchema { get; } public string ReceiptSchema { get; }
[IgnoreMember]
public string CommandId => Operation.IdempotencyKey ?? "";
} }
} }

View file

@ -46,7 +46,7 @@
], ],
"unsupportedPlugins": [], "unsupportedPlugins": [],
"commandTransport": { "commandTransport": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"emitter": "EveUiToolkitSurfaceLowerer.EmitCommand", "emitter": "EveUiToolkitSurfaceLowerer.EmitCommand",
"clientId": "unity-uitoolkit" "clientId": "unity-uitoolkit"
}, },

View file

@ -75,6 +75,7 @@
"contractInputs": [ "contractInputs": [
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1", "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1",
"gamecult.eve.provider_advertisement.v1", "gamecult.eve.provider_advertisement.v1",
"gamecult.eve.plugin_advertisement.v1", "gamecult.eve.plugin_advertisement.v1",
"gamecult.eve.plugin.v1", "gamecult.eve.plugin.v1",

View file

@ -56,7 +56,7 @@
"loweringKind": "runtime-neutral-stage-parts", "loweringKind": "runtime-neutral-stage-parts",
"preservedComponentKinds": ["vn.stage", "panel.dialogue", "text.dialogue", "rail.actions"], "preservedComponentKinds": ["vn.stage", "panel.dialogue", "text.dialogue", "rail.actions"],
"delegatedPlugins": ["norn.graph", "tex.math"], "delegatedPlugins": ["norn.graph", "tex.math"],
"commandEnvelope": "gamecult.eve.command.v1" "commandEnvelope": "gamecult.eve.command_invocation.v1"
} }
}, },
{ {

View file

@ -19,7 +19,7 @@
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"operations": ["describe", "validate", "project", "lower", "measure", "apply"], "operations": ["describe", "validate", "project", "lower", "measure", "apply"],
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.command_receipt.v1", "receiptSchema": "gamecult.eve.command_receipt.v1",
"stateAuthority": "proposes-plugin-state-only-provider-accepts" "stateAuthority": "proposes-plugin-state-only-provider-accepts"
} }

View file

@ -47,7 +47,7 @@
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"operations": ["describe", "validate", "project", "lower", "measure", "apply"], "operations": ["describe", "validate", "project", "lower", "measure", "apply"],
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.command_receipt.v1", "receiptSchema": "gamecult.eve.command_receipt.v1",
"stateAuthority": "proposes-plugin-state-only-provider-accepts" "stateAuthority": "proposes-plugin-state-only-provider-accepts"
} }

View file

@ -19,7 +19,7 @@
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"operations": ["describe", "validate", "project", "lower", "measure", "apply"], "operations": ["describe", "validate", "project", "lower", "measure", "apply"],
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.plugin_receipt.v1", "receiptSchema": "gamecult.eve.plugin_receipt.v1",
"stateAuthority": "emits-render-results-only-provider-owns-source-state" "stateAuthority": "emits-render-results-only-provider-owns-source-state"
} }

View file

@ -28,7 +28,7 @@
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"operations": ["describe", "validate", "project", "lower", "measure", "apply"], "operations": ["describe", "validate", "project", "lower", "measure", "apply"],
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.plugin_receipt.v1", "receiptSchema": "gamecult.eve.plugin_receipt.v1",
"stateAuthority": "emits-render-results-only-provider-owns-source-state" "stateAuthority": "emits-render-results-only-provider-owns-source-state"
} }

View file

@ -66,7 +66,7 @@
} }
], ],
"commandTransport": { "commandTransport": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"status": "provider-shell-contract-skeleton", "status": "provider-shell-contract-skeleton",
"emitter": "EveElectronShell.createCommandIntent", "emitter": "EveElectronShell.createCommandIntent",
"clientId": "electron-shell", "clientId": "electron-shell",

View file

@ -61,7 +61,7 @@ export class EveElectronShell {
const intent = { const intent = {
type: "surface-command", type: "surface-command",
schema: "gamecult.eve.command.v1", schema: "gamecult.eve.command_invocation.v1",
providerId: selected.providerId, providerId: selected.providerId,
surfaceId: selected.surfaceId, surfaceId: selected.surfaceId,
command, command,

View file

@ -38,7 +38,7 @@ test("command intents carry provider-advertised boundaries over component fallba
}, },
); );
assert.equal(intent.schema, "gamecult.eve.command.v1"); assert.equal(intent.schema, "gamecult.eve.command_invocation.v1");
assert.equal(intent.providerId, "aetheria"); assert.equal(intent.providerId, "aetheria");
assert.equal(intent.surfaceId, "aetheria.daemon.game"); assert.equal(intent.surfaceId, "aetheria.daemon.game");
assert.equal(intent.commandBoundary, "aetheria.daemon.commands"); assert.equal(intent.commandBoundary, "aetheria.daemon.commands");

View file

@ -71,7 +71,7 @@
} }
], ],
"commandTransport": { "commandTransport": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"status": "provider-shell-contract-skeleton", "status": "provider-shell-contract-skeleton",
"emitter": "EveTuiShell.createCommandIntent", "emitter": "EveTuiShell.createCommandIntent",
"clientId": "tui", "clientId": "tui",

View file

@ -39,7 +39,7 @@ export class EveTuiShell {
); );
const intent = { const intent = {
type: "surface-command", type: "surface-command",
schema: "gamecult.eve.command.v1", schema: "gamecult.eve.command_invocation.v1",
providerId: selected.providerId, providerId: selected.providerId,
surfaceId: selected.surfaceId, surfaceId: selected.surfaceId,
command, command,

View file

@ -38,7 +38,7 @@ test("command intents carry provider-advertised boundaries", () => {
}, },
); );
assert.equal(intent.schema, "gamecult.eve.command.v1"); assert.equal(intent.schema, "gamecult.eve.command_invocation.v1");
assert.equal(intent.providerId, "aetheria"); assert.equal(intent.providerId, "aetheria");
assert.equal(intent.surfaceId, "aetheria.daemon.game"); assert.equal(intent.surfaceId, "aetheria.daemon.game");
assert.equal(intent.commandBoundary, "aetheria.daemon.commands"); assert.equal(intent.commandBoundary, "aetheria.daemon.commands");

View file

@ -5,31 +5,14 @@
"type": "object", "type": "object",
"required": ["schema", "command"], "required": ["schema", "command"],
"properties": { "properties": {
"schema": { "schema": { "const": "gamecult.eve.command.v1" },
"const": "gamecult.eve.command.v1" "command": { "type": "string", "minLength": 1 },
}, "label": { "type": "string" },
"command": { "surfaceId": { "type": "string" },
"type": "string", "transport": { "type": "string" },
"minLength": 1 "authority": { "type": "string" },
}, "result": { "type": "string" },
"label": { "payloadSchema": { "type": "string" }
"type": "string"
},
"surfaceId": {
"type": "string"
},
"transport": {
"type": "string"
},
"authority": {
"type": "string"
},
"result": {
"type": "string"
},
"payloadSchema": {
"type": "string"
}
}, },
"additionalProperties": true "additionalProperties": true
} }

View file

@ -0,0 +1,39 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "gamecult.eve.command_invocation.v1",
"title": "Eve Command Invocation",
"type": "object",
"required": [
"schema",
"providerId",
"surfaceId",
"operation",
"payload",
"issuedAt",
"clientId",
"commandBoundary",
"receiptSchema"
],
"properties": {
"schema": { "const": "gamecult.eve.command_invocation.v1" },
"providerId": { "type": "string", "minLength": 1 },
"surfaceId": { "type": "string", "minLength": 1 },
"operation": {
"type": "object",
"required": ["operationId"],
"properties": {
"operationId": { "type": "string", "minLength": 1 },
"schemaId": { "type": "string" },
"idempotencyKey": { "type": "string" },
"routeHint": { "type": "object" }
},
"additionalProperties": true
},
"payload": { "type": "object" },
"issuedAt": { "type": "string" },
"clientId": { "type": "string", "minLength": 1 },
"commandBoundary": { "type": "string", "minLength": 1 },
"receiptSchema": { "type": "string", "minLength": 1 }
},
"additionalProperties": false
}

View file

@ -6,10 +6,14 @@
"required": [ "required": [
"schema", "schema",
"receiptId", "receiptId",
"commandId",
"command", "command",
"state", "state",
"ownerRepo", "ownerRepo",
"authority" "authority",
"providerId",
"surfaceId",
"sourceVersion"
], ],
"properties": { "properties": {
"schema": { "schema": {
@ -60,6 +64,10 @@
}, },
"issuedAtUtc": { "issuedAtUtc": {
"type": "string" "type": "string"
},
"sourceVersion": {
"type": "integer",
"minimum": 0
} }
}, },
"additionalProperties": true "additionalProperties": true

View file

@ -125,6 +125,9 @@
"key": { "key": {
"type": "string" "type": "string"
}, },
"recordRef": {
"type": "string"
},
"url": { "url": {
"type": "string" "type": "string"
}, },
@ -170,10 +173,19 @@
"type": "string", "type": "string",
"minLength": 1 "minLength": 1
}, },
"commandRecordRef": {
"type": "string"
},
"receiptSchema": { "receiptSchema": {
"type": "string", "type": "string",
"minLength": 1 "minLength": 1
}, },
"receiptRecordRef": {
"type": "string"
},
"assetManifestRecordRef": {
"type": "string"
},
"loweringTargets": { "loweringTargets": {
"type": "array", "type": "array",
"items": { "items": {

View file

@ -96,7 +96,7 @@ foreach ($pluginId in $expectedPlugins.Keys) {
} }
} }
if ($manifest.commandTransport.schema -ne "gamecult.eve.command.v1") { if ($manifest.commandTransport.schema -ne "gamecult.eve.command_invocation.v1") {
throw "Unexpected EveElectron command schema: $($manifest.commandTransport.schema)" throw "Unexpected EveElectron command schema: $($manifest.commandTransport.schema)"
} }
if ($manifest.commandTransport.status -ne "provider-shell-contract-skeleton") { if ($manifest.commandTransport.status -ne "provider-shell-contract-skeleton") {

View file

@ -51,7 +51,7 @@ try {
--expect-runtime android-flutter ` --expect-runtime android-flutter `
--expect-runtime-status windows-flutter:active ` --expect-runtime-status windows-flutter:active `
--expect-runtime-feature windows-flutter:embeddedDocuments ` --expect-runtime-feature windows-flutter:embeddedDocuments `
--expect-runtime-command-schema windows-flutter:gamecult.eve.command.v1 ` --expect-runtime-command-schema windows-flutter:gamecult.eve.command_invocation.v1 `
--expect-runtime-capture-status windows-flutter:golden ` --expect-runtime-capture-status windows-flutter:golden `
--expect-split-target EveFlutter --expect-split-target EveFlutter
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {

View file

@ -93,7 +93,7 @@ foreach ($pluginId in $expectedPlugins.Keys) {
} }
} }
if ($manifest.commandTransport.schema -ne "gamecult.eve.command.v1") { if ($manifest.commandTransport.schema -ne "gamecult.eve.command_invocation.v1") {
throw "Unexpected EveTui command schema: $($manifest.commandTransport.schema)" throw "Unexpected EveTui command schema: $($manifest.commandTransport.schema)"
} }
if ($manifest.commandTransport.status -ne "provider-shell-contract-skeleton") { if ($manifest.commandTransport.status -ne "provider-shell-contract-skeleton") {

View file

@ -65,7 +65,7 @@ foreach ($claim in @(
} }
} }
if ($manifest.commandTransport.schema -ne "gamecult.eve.command.v1") { if ($manifest.commandTransport.schema -ne "gamecult.eve.command_invocation.v1") {
throw "Unexpected EveUnity command schema: $($manifest.commandTransport.schema)" throw "Unexpected EveUnity command schema: $($manifest.commandTransport.schema)"
} }

View file

@ -86,7 +86,7 @@ node $consumerScript $consumerExport `
--expect-plugin-runtime-field sai.vn:sidecar.requestSchema:gamecult.eve.plugin_abi.request.v1 ` --expect-plugin-runtime-field sai.vn:sidecar.requestSchema:gamecult.eve.plugin_abi.request.v1 `
--expect-plugin-runtime-field sai.vn:sidecar.responseSchema:gamecult.eve.plugin_abi.response.v1 ` --expect-plugin-runtime-field sai.vn:sidecar.responseSchema:gamecult.eve.plugin_abi.response.v1 `
--expect-plugin-runtime-field sai.vn:sidecar.stateAuthority:proposes-plugin-state-only-provider-accepts ` --expect-plugin-runtime-field sai.vn:sidecar.stateAuthority:proposes-plugin-state-only-provider-accepts `
--expect-plugin-abi-field sai.vn:lower:expect.commandEnvelope:gamecult.eve.command.v1 ` --expect-plugin-abi-field sai.vn:lower:expect.commandEnvelope:gamecult.eve.command_invocation.v1 `
--expect-plugin-abi-field sai.vn:apply:expect.receiptSchema:gamecult.eve.command_receipt.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 norn.graph:executable-sidecar `
--expect-plugin-runtime-transport norn.graph:stdio ` --expect-plugin-runtime-transport norn.graph:stdio `

View file

@ -151,12 +151,12 @@ node $consumerScript $consumerExport `
--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: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:tui:tex.math:optional-supported:EveTui `
--expect-runtime-handoff unity-uitoolkit ` --expect-runtime-handoff unity-uitoolkit `
--expect-runtime-command-schema web:gamecult.eve.command.v1 ` --expect-runtime-command-schema web:gamecult.eve.command_invocation.v1 `
--expect-runtime-command-schema windows-flutter:gamecult.eve.command.v1 ` --expect-runtime-command-schema windows-flutter:gamecult.eve.command_invocation.v1 `
--expect-runtime-command-schema unity-uitoolkit:gamecult.eve.command.v1 ` --expect-runtime-command-schema unity-uitoolkit:gamecult.eve.command_invocation.v1 `
--expect-runtime-command-schema unity-scene:gamecult.eve.command.v1 ` --expect-runtime-command-schema unity-scene:gamecult.eve.command_invocation.v1 `
--expect-runtime-command-schema electron-shell:gamecult.eve.command.v1 ` --expect-runtime-command-schema electron-shell:gamecult.eve.command_invocation.v1 `
--expect-runtime-command-schema tui:gamecult.eve.command.v1 ` --expect-runtime-command-schema tui:gamecult.eve.command_invocation.v1 `
--expect-runtime-capture-status web:chrome-headless ` --expect-runtime-capture-status web:chrome-headless `
--expect-runtime-capture-status windows-flutter:golden ` --expect-runtime-capture-status windows-flutter:golden `
--expect-runtime-capture-status linux-flutter:ssh-golden ` --expect-runtime-capture-status linux-flutter:ssh-golden `

View file

@ -850,7 +850,7 @@ function validateIndex(index, directory, expectations, errors) {
if (!providers.some(provider => provider.providerId === "aetheria" && provider.scenarioPath)) { if (!providers.some(provider => provider.providerId === "aetheria" && provider.scenarioPath)) {
errors.push("providers:aetheria:scenarioPath:missing"); errors.push("providers:aetheria:scenarioPath:missing");
} }
if (!runtimes.some(runtime => runtime.runtimeId === "unity-uitoolkit" && runtime.commandTransportSchema === "gamecult.eve.command.v1")) { if (!runtimes.some(runtime => runtime.runtimeId === "unity-uitoolkit" && runtime.commandTransportSchema === "gamecult.eve.command_invocation.v1")) {
errors.push("runtimes:unity-uitoolkit:commandTransportSchema:missing"); errors.push("runtimes:unity-uitoolkit:commandTransportSchema:missing");
} }
if (!splitTargets.some(target => target.id === "EveUnity")) { if (!splitTargets.some(target => target.id === "EveUnity")) {
@ -1061,8 +1061,8 @@ function validateCommandBoundaryCoverage(records, errors) {
for (const field of ["providerId", "providerOwnerRepo", "surfaceId", "targetId", "runtimeId", "runtimeOwnerRepo", "status", "severity", "commandBoundary", "receiptSchema"]) { for (const field of ["providerId", "providerOwnerRepo", "surfaceId", "targetId", "runtimeId", "runtimeOwnerRepo", "status", "severity", "commandBoundary", "receiptSchema"]) {
if (!record?.[field]) errors.push(`commandBoundaryCoverage:${index}:${field}:missing`); if (!record?.[field]) errors.push(`commandBoundaryCoverage:${index}:${field}:missing`);
} }
if (record?.status === "covered" && record.runtimeCommandSchema !== "gamecult.eve.command.v1") { if (record?.status === "covered" && record.runtimeCommandSchema !== "gamecult.eve.command_invocation.v1") {
errors.push(`commandBoundaryCoverage:${index}:runtimeCommandSchema:expected gamecult.eve.command.v1 got ${record.runtimeCommandSchema || ""}`); errors.push(`commandBoundaryCoverage:${index}:runtimeCommandSchema:expected gamecult.eve.command_invocation.v1 got ${record.runtimeCommandSchema || ""}`);
} }
} }
} }

View file

@ -76,6 +76,7 @@
"contractInputs": [ "contractInputs": [
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1", "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1",
"gamecult.eve.command_receipt.v1", "gamecult.eve.command_receipt.v1",
"gamecult.eve.conformance_export.v1", "gamecult.eve.conformance_export.v1",
"gamecult.eve.conformance_handoff.v1", "gamecult.eve.conformance_handoff.v1",

View file

@ -11,6 +11,7 @@
"gamecult.eve.conformance_export.v1": "schemas/gamecult.eve.conformance_export.v1.schema.json", "gamecult.eve.conformance_export.v1": "schemas/gamecult.eve.conformance_export.v1.schema.json",
"gamecult.eve.capability_matrix.v1": "schemas/gamecult.eve.capability_matrix.v1.schema.json", "gamecult.eve.capability_matrix.v1": "schemas/gamecult.eve.capability_matrix.v1.schema.json",
"gamecult.eve.command.v1": "schemas/gamecult.eve.command.v1.schema.json", "gamecult.eve.command.v1": "schemas/gamecult.eve.command.v1.schema.json",
"gamecult.eve.command_invocation.v1": "schemas/gamecult.eve.command_invocation.v1.schema.json",
"gamecult.eve.command_receipt.v1": "schemas/gamecult.eve.command_receipt.v1.schema.json", "gamecult.eve.command_receipt.v1": "schemas/gamecult.eve.command_receipt.v1.schema.json",
"gamecult.eve.plugin.v1": "schemas/gamecult.eve.plugin.v1.schema.json", "gamecult.eve.plugin.v1": "schemas/gamecult.eve.plugin.v1.schema.json",
"gamecult.eve.plugin_receipt.v1": "schemas/gamecult.eve.plugin_receipt.v1.schema.json", "gamecult.eve.plugin_receipt.v1": "schemas/gamecult.eve.plugin_receipt.v1.schema.json",
@ -372,7 +373,7 @@
"schemaPath": "schemas/gamecult.eve.provider_advertisement.v1.schema.json", "schemaPath": "schemas/gamecult.eve.provider_advertisement.v1.schema.json",
"advertisementPath": "web/fixtures/sai-vn.provider-advertisement.json", "advertisementPath": "web/fixtures/sai-vn.provider-advertisement.json",
"requiredFixtures": [], "requiredFixtures": [],
"expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "sai.vn.story_session.v1"], "expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.command_invocation.v1", "sai.vn.story_session.v1"],
"expectedSurfaces": ["sai.visual_novel.surface"], "expectedSurfaces": ["sai.visual_novel.surface"],
"expectedCommands": ["story.continue", "story.choose", "story.jump", "style.patch"] "expectedCommands": ["story.continue", "story.choose", "story.jump", "style.patch"]
}, },
@ -388,7 +389,7 @@
"scenarioPath": "web/fixtures/aetheria-world-scenario.json", "scenarioPath": "web/fixtures/aetheria-world-scenario.json",
"handoffPath": "web/fixtures/aetheria-provider-handoff.json", "handoffPath": "web/fixtures/aetheria-provider-handoff.json",
"requiredFixtures": ["aetheria-world"], "requiredFixtures": ["aetheria-world"],
"expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.unity_playable_world_asset_manifest.v1", "aetheria.runtime.daemon.frame.v1"], "expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.command_invocation.v1", "gamecult.eve.unity_playable_world_asset_manifest.v1", "aetheria.runtime.daemon.frame.v1"],
"expectedSurfaces": ["aetheria.daemon.game", "aetheria.daemon.editor"], "expectedSurfaces": ["aetheria.daemon.game", "aetheria.daemon.editor"],
"expectedSurfaceKinds": { "expectedSurfaceKinds": {
"aetheria.daemon.game": "interactive-world", "aetheria.daemon.game": "interactive-world",
@ -412,7 +413,7 @@
"advertisementPath": "web/fixtures/eve-world-smoke.provider-advertisement.json", "advertisementPath": "web/fixtures/eve-world-smoke.provider-advertisement.json",
"scenarioPath": "web/fixtures/eve-world-smoke-scenario.json", "scenarioPath": "web/fixtures/eve-world-smoke-scenario.json",
"requiredFixtures": ["eve-world-smoke"], "requiredFixtures": ["eve-world-smoke"],
"expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "eve.world_smoke.frame.v1", "eve.world_smoke.command_receipt.v1"], "expectedSchemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.command_invocation.v1", "eve.world_smoke.frame.v1", "eve.world_smoke.command_receipt.v1"],
"expectedSurfaces": ["eve.world-smoke.surface"], "expectedSurfaces": ["eve.world-smoke.surface"],
"expectedSurfaceKinds": { "expectedSurfaceKinds": {
"eve.world-smoke.surface": "interactive-world" "eve.world-smoke.surface": "interactive-world"
@ -446,7 +447,7 @@
"protocol": "cultmesh-rpc-with-stdio-dev-transport", "protocol": "cultmesh-rpc-with-stdio-dev-transport",
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.command_receipt.v1", "receiptSchema": "gamecult.eve.command_receipt.v1",
"stateAuthority": "proposes-plugin-state-only-provider-accepts" "stateAuthority": "proposes-plugin-state-only-provider-accepts"
} }
@ -472,6 +473,8 @@
"kind": "external-owner", "kind": "external-owner",
"ownerRepo": "Norn", "ownerRepo": "Norn",
"repoRole": "plugin-owner", "repoRole": "plugin-owner",
"splitTarget": "Norn",
"graduationTrigger": "Graduated: Norn owns graph semantics, fixtures, ABI sidecar, and release lifecycle.",
"capabilities": ["embed.norn", "graph.node.activate"], "capabilities": ["embed.norn", "graph.node.activate"],
"expectedRuntime": { "expectedRuntime": {
"invocationModel": "executable-sidecar", "invocationModel": "executable-sidecar",
@ -483,7 +486,7 @@
"protocol": "stdio-ndjson", "protocol": "stdio-ndjson",
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.command_receipt.v1", "receiptSchema": "gamecult.eve.command_receipt.v1",
"stateAuthority": "proposes-plugin-state-only-provider-accepts" "stateAuthority": "proposes-plugin-state-only-provider-accepts"
} }
@ -520,7 +523,7 @@
"protocol": "cultmesh-rpc-with-stdio-dev-transport", "protocol": "cultmesh-rpc-with-stdio-dev-transport",
"requestSchema": "gamecult.eve.plugin_abi.request.v1", "requestSchema": "gamecult.eve.plugin_abi.request.v1",
"responseSchema": "gamecult.eve.plugin_abi.response.v1", "responseSchema": "gamecult.eve.plugin_abi.response.v1",
"commandEnvelope": "gamecult.eve.command.v1", "commandEnvelope": "gamecult.eve.command_invocation.v1",
"receiptSchema": "gamecult.eve.plugin_receipt.v1", "receiptSchema": "gamecult.eve.plugin_receipt.v1",
"stateAuthority": "emits-render-results-only-provider-owns-source-state" "stateAuthority": "emits-render-results-only-provider-owns-source-state"
} }
@ -1281,12 +1284,12 @@
} }
], ],
"commandTransportSmoke": { "commandTransportSmoke": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"expectedPaths": ["packages/eve-browser-lowering/src/index.ts", "packages/eve-browser-lowering/test/browser-lowering.test.mjs", "web/surface.js"], "expectedPaths": ["packages/eve-browser-lowering/src/index.ts", "packages/eve-browser-lowering/test/browser-lowering.test.mjs", "web/surface.js"],
"expectedSourceSymbols": [ "expectedSourceSymbols": [
{ {
"path": "packages/eve-browser-lowering/src/index.ts", "path": "packages/eve-browser-lowering/src/index.ts",
"contains": ["EveCommandIntent", "createEveCommandIntent", "schema: \"gamecult.eve.command.v1\"", "clientId", "commandBoundary", "receiptSchema", "activeSurfaceId"] "contains": ["EveCommandIntent", "createEveCommandIntent", "schema: \"gamecult.eve.command_invocation.v1\"", "clientId", "commandBoundary", "receiptSchema", "activeSurfaceId"]
}, },
{ {
"path": "packages/eve-browser-lowering/test/browser-lowering.test.mjs", "path": "packages/eve-browser-lowering/test/browser-lowering.test.mjs",
@ -1404,12 +1407,12 @@
} }
], ],
"commandTransportSmoke": { "commandTransportSmoke": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"], "expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"],
"expectedSourceSymbols": [ "expectedSourceSymbols": [
{ {
"path": "flutter/eve_parity/lib/main.dart", "path": "flutter/eve_parity/lib/main.dart",
"contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command.v1", "flutter-parity"] "contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command_invocation.v1", "flutter-parity"]
}, },
{ {
"path": "flutter/eve_parity/test/parity_smoke_test.dart", "path": "flutter/eve_parity/test/parity_smoke_test.dart",
@ -1459,12 +1462,12 @@
} }
], ],
"commandTransportSmoke": { "commandTransportSmoke": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"], "expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"],
"expectedSourceSymbols": [ "expectedSourceSymbols": [
{ {
"path": "flutter/eve_parity/lib/main.dart", "path": "flutter/eve_parity/lib/main.dart",
"contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command.v1", "flutter-parity"] "contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command_invocation.v1", "flutter-parity"]
}, },
{ {
"path": "flutter/eve_parity/test/parity_smoke_test.dart", "path": "flutter/eve_parity/test/parity_smoke_test.dart",
@ -1538,12 +1541,12 @@
} }
], ],
"commandTransportSmoke": { "commandTransportSmoke": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"], "expectedPaths": ["flutter/eve_parity/lib/main.dart", "flutter/eve_parity/test/parity_smoke_test.dart"],
"expectedSourceSymbols": [ "expectedSourceSymbols": [
{ {
"path": "flutter/eve_parity/lib/main.dart", "path": "flutter/eve_parity/lib/main.dart",
"contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command.v1", "flutter-parity"] "contains": ["EveCommandIntent", "createEveCommandIntent", "resolveComponentCommandId", "commandSink", "gamecult.eve.command_invocation.v1", "flutter-parity"]
}, },
{ {
"path": "flutter/eve_parity/test/parity_smoke_test.dart", "path": "flutter/eve_parity/test/parity_smoke_test.dart",
@ -1675,7 +1678,7 @@
} }
], ],
"commandTransportSmoke": { "commandTransportSmoke": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"expectedPaths": [ "expectedPaths": [
"packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs", "packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs",
"packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs" "packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs"
@ -1683,7 +1686,7 @@
"expectedSourceSymbols": [ "expectedSourceSymbols": [
{ {
"path": "packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs", "path": "packages/org.gamecult.eve.surface/Runtime/EveSurfaceDocument.cs",
"contains": ["EveSurfaceCommandRequest", "SchemaId", "gamecult.eve.command.v1", "ClientId"] "contains": ["EveSurfaceCommandRequest", "SchemaId", "gamecult.eve.command_invocation.v1", "ClientId"]
}, },
{ {
"path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs", "path": "packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs",
@ -1895,7 +1898,7 @@
"demotionReason": "Fensalir has an external Aquarium.EveSurface adapter spike and a recorded gamecult.eve.surface.v1 adapter fixture, but Eve still has no Direct2D frame capture or runtime-owned command smoke.", "demotionReason": "Fensalir has an external Aquarium.EveSurface adapter spike and a recorded gamecult.eve.surface.v1 adapter fixture, but Eve still has no Direct2D frame capture or runtime-owned command smoke.",
"activationCriteria": [ "activationCriteria": [
"Fensalir runs recorded gamecult.eve.surface.v1 fixtures without provider-specific renderer knowledge.", "Fensalir runs recorded gamecult.eve.surface.v1 fixtures without provider-specific renderer knowledge.",
"Fensalir emits gamecult.eve.command.v1 intents through the advertised provider command boundary.", "Fensalir emits gamecult.eve.command_invocation.v1 intents through the advertised provider command boundary.",
"Direct2D capture artifacts are produced and attached to the parity report." "Direct2D capture artifacts are produced and attached to the parity report."
], ],
"requiredFixtures": ["fensalir-direct2d"], "requiredFixtures": ["fensalir-direct2d"],

View file

@ -1400,8 +1400,8 @@ async function validateRuntimeCommandTransportSmoke(runtime) {
if (!smoke) return []; if (!smoke) return [];
const errors = []; const errors = [];
if (smoke.schema !== "gamecult.eve.command.v1") { if (smoke.schema !== "gamecult.eve.command_invocation.v1") {
errors.push(`schema:expected gamecult.eve.command.v1 got ${smoke.schema || ""}`); errors.push(`schema:expected gamecult.eve.command_invocation.v1 got ${smoke.schema || ""}`);
} }
for (const candidate of smoke.expectedPaths || []) { for (const candidate of smoke.expectedPaths || []) {
@ -3261,7 +3261,7 @@ function collectCommandBoundaryCoverage(report) {
status = "missing-runtime-claim"; status = "missing-runtime-claim";
} else if (missingProviderBoundary) { } else if (missingProviderBoundary) {
status = "missing-provider-boundary"; status = "missing-provider-boundary";
} else if (runtimeCommandSchema !== "gamecult.eve.command.v1") { } else if (runtimeCommandSchema !== "gamecult.eve.command_invocation.v1") {
status = "missing-command-transport"; status = "missing-command-transport";
} }
coverage.push({ coverage.push({

View file

@ -44,7 +44,7 @@
], ],
"unsupportedPlugins": [], "unsupportedPlugins": [],
"commandTransport": { "commandTransport": {
"schema": "gamecult.eve.command.v1", "schema": "gamecult.eve.command_invocation.v1",
"emitter": "createEveCommandIntent", "emitter": "createEveCommandIntent",
"clientId": "browser.reference" "clientId": "browser.reference"
}, },

View file

@ -48,6 +48,7 @@
"contractInputs": [ "contractInputs": [
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1", "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1",
"gamecult.eve.unity_playable_world_asset_manifest.v1", "gamecult.eve.unity_playable_world_asset_manifest.v1",
"gamecult.eve.provider_advertisement.v1", "gamecult.eve.provider_advertisement.v1",
"gamecult.eve.provider_scenario.v1", "gamecult.eve.provider_scenario.v1",

View file

@ -26,7 +26,7 @@
} }
], ],
"commands": ["aetheria.daemon.commands"], "commands": ["aetheria.daemon.commands"],
"schemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "aetheria.eve_command_acceptance_status.v1"] "schemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.command_invocation.v1", "aetheria.eve_command_acceptance_status.v1"]
}, },
"commandIntents": [ "commandIntents": [
{ {

View file

@ -39,6 +39,7 @@
"aetheria.runtime.daemon.command.v1", "aetheria.runtime.daemon.command.v1",
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1", "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1",
"gamecult.eve.unity_playable_world_asset_manifest.v1" "gamecult.eve.unity_playable_world_asset_manifest.v1"
], ],
"witnesses": [ "witnesses": [

View file

@ -19,7 +19,7 @@
} }
], ],
"commands": ["eve.world-smoke.commands"], "commands": ["eve.world-smoke.commands"],
"schemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "eve.world_smoke.command_receipt.v1"] "schemas": ["gamecult.eve.surface.v1", "gamecult.eve.command.v1", "gamecult.eve.command_invocation.v1", "eve.world_smoke.command_receipt.v1"]
}, },
"commandIntents": [ "commandIntents": [
{ {

View file

@ -19,7 +19,8 @@
"eve.world_smoke.frame.v1", "eve.world_smoke.frame.v1",
"eve.world_smoke.command_receipt.v1", "eve.world_smoke.command_receipt.v1",
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1" "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1"
], ],
"witnesses": [ "witnesses": [
{ {

View file

@ -18,6 +18,7 @@
"schemas": [ "schemas": [
"gamecult.eve.surface.v1", "gamecult.eve.surface.v1",
"gamecult.eve.command.v1", "gamecult.eve.command.v1",
"gamecult.eve.command_invocation.v1",
"sai.vn.story_session.v1", "sai.vn.story_session.v1",
"sai.vn.visual_manifest.v1", "sai.vn.visual_manifest.v1",
"norn.graph.document.v1", "norn.graph.document.v1",