Normalize C# provider advertisements at Eve boundary

This commit is contained in:
Meta Vens 2026-08-22 00:13:25 +02:00
commit cdea1c8f9e
4 changed files with 175 additions and 2 deletions

View file

@ -52,3 +52,9 @@ export declare const parseEveCommandInvocation: (value: unknown) => EveCommandIn
export declare const parseEveCommandReceipt: (value: unknown) => EveCommandReceipt;
export declare const parseEveCommandResult: (value: unknown) => EveCommandResult;
export declare const parseEveInputCapability: (value: unknown) => EveInputCapability;
/**
* Converts the canonical positional MessagePack representation used by the C#
* Eve package into the JSON-shaped provider contract used at browser/model
* boundaries. This is serialization lowering, not a second advertisement DTO.
*/
export declare function normalizeEveProviderAdvertisement(value: unknown): unknown;

View file

@ -44,7 +44,7 @@ export const isEveCommandInvocation = (value) => isEveContract("commandInvocatio
export const isEveCommandReceipt = (value) => isEveContract("commandReceipt", value);
export const isEveCommandResult = (value) => isEveContract("commandResult", value);
export const isEveInputCapability = (value) => isEveContract("inputCapability", value);
export const parseEveProviderAdvertisement = (value) => parseEveContract("providerAdvertisement", value);
export const parseEveProviderAdvertisement = (value) => parseEveContract("providerAdvertisement", normalizeEveProviderAdvertisement(value));
export const parseEveSurfaceDocument = (value) => parseEveContract("surface", value);
export const parseEveCommandDescriptor = (value) => parseEveContract("commandDescriptor", value);
export const parseEveCommandInvocation = (value) => parseEveContract("commandInvocation", value);
@ -62,3 +62,74 @@ function requiredValidator(schemaId) {
throw new Error(`Eve contract schema ${schemaId} was not registered.`);
return validator;
}
/**
* Converts the canonical positional MessagePack representation used by the C#
* Eve package into the JSON-shaped provider contract used at browser/model
* boundaries. This is serialization lowering, not a second advertisement DTO.
*/
export function normalizeEveProviderAdvertisement(value) {
if (!Array.isArray(value))
return value;
if (value.length < 13)
return value;
const [schema, providerId, serviceId, verseId, title, kind, cultMeshAddress, updatedAtUtc, freshness, schemas, witnesses, surfaces, commands, authorizedBodyProducerIds] = value;
return {
schema,
providerId,
serviceId,
verseId,
title,
kind,
cultMeshAddress,
updatedAtUtc,
freshness: normalizeFreshness(freshness),
schemas,
witnesses: Array.isArray(witnesses) ? witnesses.map(normalizeWitness) : witnesses,
surfaces: Array.isArray(surfaces) ? surfaces.map(normalizeSurfaceAdvertisement) : surfaces,
commands: Array.isArray(commands) ? commands.map(normalizeAdvertisedCommand) : commands,
...(Array.isArray(authorizedBodyProducerIds) ? { authorizedBodyProducerIds } : {}),
};
}
function normalizeFreshness(value) {
return Array.isArray(value)
? { state: value[0], lastSeenAtUtc: value[1], maxAgeMs: value[2] }
: value;
}
function normalizeWitness(value) {
return Array.isArray(value)
? { kind: value[0], ref: value[1], summary: value[2] }
: value;
}
function normalizeSurfaceAdvertisement(value) {
if (!Array.isArray(value))
return value;
return {
surfaceId: value[0],
schema: value[1],
recordRef: value[2],
transport: value[3],
status: value[4],
surfaceKind: value[5],
...(value[6] ? { worldInteraction: normalizeWorldInteraction(value[6]) } : {}),
};
}
function normalizeWorldInteraction(value) {
if (!Array.isArray(value))
return value;
return {
projectionKind: value[0],
stateSchemas: value[1],
commandBoundary: value[2],
commandRecordRef: value[3],
receiptSchema: value[4],
receiptRecordRef: value[5],
assetManifestRecordRef: value[6],
loweringTargets: value[7],
ownership: value[8],
};
}
function normalizeAdvertisedCommand(value) {
return Array.isArray(value)
? { command: value[0], surfaceId: value[1], transport: value[2], summary: value[3] }
: value;
}

View file

@ -92,7 +92,7 @@ export const isEveInputCapability = (value: unknown): value is EveInputCapabilit
isEveContract("inputCapability", value);
export const parseEveProviderAdvertisement = (value: unknown): EveProviderAdvertisement =>
parseEveContract("providerAdvertisement", value);
parseEveContract("providerAdvertisement", normalizeEveProviderAdvertisement(value));
export const parseEveSurfaceDocument = (value: unknown): EveSurfaceDocument =>
parseEveContract("surface", value);
export const parseEveCommandDescriptor = (value: unknown): EveCommandDescriptor =>
@ -114,3 +114,77 @@ function requiredValidator(schemaId: string): ValidateFunction {
if (!validator) throw new Error(`Eve contract schema ${schemaId} was not registered.`);
return validator;
}
/**
* Converts the canonical positional MessagePack representation used by the C#
* Eve package into the JSON-shaped provider contract used at browser/model
* boundaries. This is serialization lowering, not a second advertisement DTO.
*/
export function normalizeEveProviderAdvertisement(value: unknown): unknown {
if (!Array.isArray(value)) return value;
if (value.length < 13) return value;
const [schema, providerId, serviceId, verseId, title, kind, cultMeshAddress, updatedAtUtc,
freshness, schemas, witnesses, surfaces, commands, authorizedBodyProducerIds] = value;
return {
schema,
providerId,
serviceId,
verseId,
title,
kind,
cultMeshAddress,
updatedAtUtc,
freshness: normalizeFreshness(freshness),
schemas,
witnesses: Array.isArray(witnesses) ? witnesses.map(normalizeWitness) : witnesses,
surfaces: Array.isArray(surfaces) ? surfaces.map(normalizeSurfaceAdvertisement) : surfaces,
commands: Array.isArray(commands) ? commands.map(normalizeAdvertisedCommand) : commands,
...(Array.isArray(authorizedBodyProducerIds) ? { authorizedBodyProducerIds } : {}),
};
}
function normalizeFreshness(value: unknown): unknown {
return Array.isArray(value)
? { state: value[0], lastSeenAtUtc: value[1], maxAgeMs: value[2] }
: value;
}
function normalizeWitness(value: unknown): unknown {
return Array.isArray(value)
? { kind: value[0], ref: value[1], summary: value[2] }
: value;
}
function normalizeSurfaceAdvertisement(value: unknown): unknown {
if (!Array.isArray(value)) return value;
return {
surfaceId: value[0],
schema: value[1],
recordRef: value[2],
transport: value[3],
status: value[4],
surfaceKind: value[5],
...(value[6] ? { worldInteraction: normalizeWorldInteraction(value[6]) } : {}),
};
}
function normalizeWorldInteraction(value: unknown): unknown {
if (!Array.isArray(value)) return value;
return {
projectionKind: value[0],
stateSchemas: value[1],
commandBoundary: value[2],
commandRecordRef: value[3],
receiptSchema: value[4],
receiptRecordRef: value[5],
assetManifestRecordRef: value[6],
loweringTargets: value[7],
ownership: value[8],
};
}
function normalizeAdvertisedCommand(value: unknown): unknown {
return Array.isArray(value)
? { command: value[0], surfaceId: value[1], transport: value[2], summary: value[3] }
: value;
}

View file

@ -195,6 +195,28 @@ test("validates an existing canonical Eve surface fixture", async () => {
assert.equal(parseEveSurfaceDocument(fixture).providerId, "eve.world-smoke");
});
test("provider parser lowers the canonical C# MessagePack tuple without app-specific decoding", () => {
const advertisement = parseEveProviderAdvertisement([
"gamecult.eve.provider_advertisement.v1",
"aetheria",
"aetheria-daemon",
"aetheria.local",
"Aetheria",
"game.runtime",
"cultmesh://aetheria",
"2026-08-22T00:00:00Z",
["fresh", "2026-08-22T00:00:00Z", 15_000],
["gamecult.eve.surface.v1"],
[["cultcache", "aetheria.cc", "typed state"]],
[["aetheria.hangar", "gamecult.eve.surface.v1", "eve:surface:aetheria.hangar", "cultmesh-record", "active", "interactive-world",
["provider-authored-world-surface", ["aetheria.frame.v1"], "aetheria.daemon.commands", "eve:commands", "gamecult.eve.command_receipt.v1", "eve:receipts", "eve:assets", ["web-reference"], "provider owns truth"]]],
[["hangar.select_verse", "aetheria.hangar", "cultmesh", "Select Verse"]],
["aetheria-daemon.soa"],
]);
assert.equal(advertisement.surfaces[0].worldInteraction.commandBoundary, "aetheria.daemon.commands");
assert.equal(advertisement.witnesses[0].ref, "aetheria.cc");
});
test("command results validate persisted receipts and transient Eve projections together", () => {
const result = parseEveCommandResult({
schema: "gamecult.eve.command_result.v1",