Add Eve authority witness fixture
This commit is contained in:
parent
c93ad5519c
commit
d68ff3c6ce
5 changed files with 304 additions and 4 deletions
|
|
@ -274,14 +274,17 @@ Exit criteria:
|
|||
|
||||
## Active Work Queue
|
||||
|
||||
1. Add authority/staleness witness fixture to browser reference.
|
||||
2. Add conformance-pack metadata files beside fixtures.
|
||||
3. Add a Direct2D adapter spike or explicitly demote Direct2D until Fensalir owns
|
||||
1. Add conformance-pack metadata files beside fixtures.
|
||||
2. Add a Direct2D adapter spike or explicitly demote Direct2D until Fensalir owns
|
||||
the body.
|
||||
4. Add split-readiness reports for EveFlutter and EveUnity.
|
||||
3. Add split-readiness reports for EveFlutter and EveUnity.
|
||||
|
||||
Recently cut:
|
||||
|
||||
- The browser reference now has an authority/staleness witness fixture. The
|
||||
parity report verifies visible `fresh`, `accepted`, `stale`, `missing`,
|
||||
`pending`, `denied`, `predicted`, and `reconciled` states, with provider and
|
||||
renderer ownership kept separate.
|
||||
- Command descriptor validation now runs for strict fixtures. Sai proves
|
||||
`story.*`/`style.patch`; Aetheria proves the daemon command boundary; the web
|
||||
lowerer resolves authored `action.command` through the shared Eve command
|
||||
|
|
|
|||
|
|
@ -192,6 +192,35 @@
|
|||
"commandReferencesDeclared": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "authority-staleness",
|
||||
"title": "Authority And Staleness Witness",
|
||||
"pack": "core",
|
||||
"ownerRepo": "Eve",
|
||||
"surface": {
|
||||
"transport": "local-json",
|
||||
"path": "web/fixtures/authority-staleness-witness.json"
|
||||
},
|
||||
"expect": {
|
||||
"providerId": "gamecult.eve.authority-witness",
|
||||
"componentKinds": ["surface", "card", "text", "metric", "partition"],
|
||||
"styleTokens": ["colorBackground", "colorPanel", "colorText", "colorMuted", "colorAccent", "colorWarning", "colorDanger"],
|
||||
"bindings": [
|
||||
"authority.temperature.accepted",
|
||||
"authority.sensor.echo",
|
||||
"authority.missing.field",
|
||||
"authority.orbit.predicted",
|
||||
"authority.orbit.accepted"
|
||||
],
|
||||
"commandDescriptors": ["authority.fixture.patch"],
|
||||
"commandDescriptorSchema": "gamecult.eve.command.v1",
|
||||
"commandReferencesDeclared": true,
|
||||
"authorityStates": ["accepted", "denied", "fresh", "missing", "pending", "predicted", "reconciled", "stale"],
|
||||
"authorityOwners": ["provider", "renderer"],
|
||||
"witnessRefs": 8,
|
||||
"receiptRefs": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "reactive-dsl",
|
||||
"title": "Reactive DSL",
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ async function evaluateFixture(fixture) {
|
|||
const commandIds = commandDescriptors.map(command => command.command).sort();
|
||||
const commandReferences = readCommandReferences(nodes);
|
||||
const commandDescriptorErrors = await validateCommandDescriptors(fixture, commandDescriptors);
|
||||
const authorityWitnesses = readAuthorityWitnesses(nodes);
|
||||
const authorityStates = [...new Set(authorityWitnesses.map(witness => witness.state))].filter(Boolean).sort();
|
||||
const authorityOwners = [...new Set(authorityWitnesses.map(witness => witness.owner))].filter(Boolean).sort();
|
||||
const receiptRefs = [...new Set(authorityWitnesses.map(witness => witness.receiptRef))].filter(Boolean).sort();
|
||||
const witnessRefs = [...new Set(authorityWitnesses.map(witness => witness.witnessRef))].filter(Boolean).sort();
|
||||
const checks = [];
|
||||
|
||||
addCheck(checks, "providerId", state.providerId === fixture.expect.providerId, {
|
||||
|
|
@ -149,6 +154,34 @@ async function evaluateFixture(fixture) {
|
|||
}
|
||||
}
|
||||
|
||||
for (const state of fixture.expect.authorityStates || []) {
|
||||
addCheck(checks, `authorityState:${state}`, authorityStates.includes(state), {
|
||||
expected: "present",
|
||||
actual: authorityStates,
|
||||
});
|
||||
}
|
||||
|
||||
for (const owner of fixture.expect.authorityOwners || []) {
|
||||
addCheck(checks, `authorityOwner:${owner}`, authorityOwners.includes(owner), {
|
||||
expected: "present",
|
||||
actual: authorityOwners,
|
||||
});
|
||||
}
|
||||
|
||||
if (fixture.expect.receiptRefs) {
|
||||
addCheck(checks, "receiptRefs", receiptRefs.length >= fixture.expect.receiptRefs, {
|
||||
expected: fixture.expect.receiptRefs,
|
||||
actual: receiptRefs.length,
|
||||
});
|
||||
}
|
||||
|
||||
if (fixture.expect.witnessRefs) {
|
||||
addCheck(checks, "witnessRefs", witnessRefs.length >= fixture.expect.witnessRefs, {
|
||||
expected: fixture.expect.witnessRefs,
|
||||
actual: witnessRefs.length,
|
||||
});
|
||||
}
|
||||
|
||||
const knownPacks = new Set((manifest.conformancePacks || []).map(pack => pack.id));
|
||||
if (fixture.pack) {
|
||||
addCheck(checks, "conformancePack", knownPacks.has(fixture.pack), {
|
||||
|
|
@ -181,6 +214,11 @@ async function evaluateFixture(fixture) {
|
|||
commands: commandIds,
|
||||
commandReferences,
|
||||
commandDescriptorErrors,
|
||||
authorityStates,
|
||||
authorityOwners,
|
||||
receiptRefs,
|
||||
witnessRefs,
|
||||
authorityWitnesses,
|
||||
checks,
|
||||
};
|
||||
}
|
||||
|
|
@ -552,6 +590,26 @@ function readCommandReferences(nodes) {
|
|||
}).sort((a, b) => `${a.nodeId}:${a.command}`.localeCompare(`${b.nodeId}:${b.command}`));
|
||||
}
|
||||
|
||||
function readAuthorityWitnesses(nodes) {
|
||||
return nodes.flatMap(node => {
|
||||
const props = node.props || {};
|
||||
const freshness = objectProps(props.freshness);
|
||||
const state = firstNonEmptyString(props.authorityState, props.truthState, props.commandState, freshness.state);
|
||||
const owner = firstNonEmptyString(props.authorityOwner, props.owner, props.authority);
|
||||
const witnessRef = firstNonEmptyString(props.witnessRef, props.sourceId);
|
||||
const receiptRef = firstNonEmptyString(props.receiptRef, props.receiptId);
|
||||
if (!state && !owner && !witnessRef && !receiptRef) return [];
|
||||
return [{
|
||||
nodeId: node.id || "",
|
||||
kind: node.kind || "",
|
||||
state,
|
||||
owner,
|
||||
witnessRef,
|
||||
receiptRef,
|
||||
}];
|
||||
}).sort((a, b) => `${a.nodeId}:${a.state}`.localeCompare(`${b.nodeId}:${b.state}`));
|
||||
}
|
||||
|
||||
function firstNonEmptyString(...values) {
|
||||
for (const value of values) {
|
||||
if (typeof value === "string" && value.trim()) return value;
|
||||
|
|
@ -651,6 +709,11 @@ function renderMarkdown(report) {
|
|||
lines.push(`| ${fixture.title} | ${fixture.commands.join(", ")} | ${refs} | ${fixture.commandDescriptorErrors.join(", ")} |`);
|
||||
}
|
||||
|
||||
lines.push("", "## Authority Witnesses", "", "| Fixture | States | Owners | Witness Refs | Receipt Refs |", "| --- | --- | --- | ---: | ---: |");
|
||||
for (const fixture of report.fixtures) {
|
||||
lines.push(`| ${fixture.title} | ${fixture.authorityStates.join(", ")} | ${fixture.authorityOwners.join(", ")} | ${fixture.witnessRefs.length} | ${fixture.receiptRefs.length} |`);
|
||||
}
|
||||
|
||||
lines.push("", "## Plugins", "", "| Plugin | Status | Owner | Capabilities | Missing |", "| --- | --- | --- | --- | --- |");
|
||||
for (const plugin of report.plugins || []) {
|
||||
const missing = [
|
||||
|
|
|
|||
198
web/fixtures/authority-staleness-witness.json
Normal file
198
web/fixtures/authority-staleness-witness.json
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
{
|
||||
"type": "surface-state",
|
||||
"schema": "gamecult.eve.surface.v1",
|
||||
"providerId": "gamecult.eve.authority-witness",
|
||||
"providerKind": "surface.fixture",
|
||||
"title": "Authority And Staleness Witness",
|
||||
"version": 1,
|
||||
"updatedAtUtc": "2026-07-08T00:00:00Z",
|
||||
"surface": {
|
||||
"id": "gamecult.eve.authority-witness",
|
||||
"root": {
|
||||
"id": "authority.root",
|
||||
"kind": "surface",
|
||||
"props": {
|
||||
"authorityModel": "provider-truth-with-local-prediction"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "authority.summary",
|
||||
"kind": "card",
|
||||
"props": {
|
||||
"title": "Truth Boundary",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "fresh",
|
||||
"freshness": {
|
||||
"state": "fresh",
|
||||
"lastSeenAtUtc": "2026-07-08T00:00:00Z"
|
||||
},
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/fresh"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "authority.summary.text",
|
||||
"kind": "text",
|
||||
"props": {
|
||||
"text": "Provider state is the accepted truth. Eve may preview local pressure, but preview is not authority."
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "authority.grid",
|
||||
"kind": "partition",
|
||||
"props": {
|
||||
"direction": "vertical"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "authority.field.fresh",
|
||||
"kind": "metric",
|
||||
"props": {
|
||||
"label": "Accepted Temperature",
|
||||
"value": "298 K",
|
||||
"bind": "authority.temperature.accepted",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "accepted",
|
||||
"freshness": {
|
||||
"state": "fresh",
|
||||
"lastSeenAtUtc": "2026-07-08T00:00:00Z"
|
||||
},
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/temperature"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "authority.field.stale",
|
||||
"kind": "metric",
|
||||
"props": {
|
||||
"label": "Sensor Echo",
|
||||
"value": "14.2 m/s",
|
||||
"bind": "authority.sensor.echo",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "stale",
|
||||
"freshness": {
|
||||
"state": "stale",
|
||||
"lastSeenAtUtc": "2026-07-08T00:00:00Z",
|
||||
"maxAgeMs": 5000
|
||||
},
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/sensor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "authority.field.missing",
|
||||
"kind": "metric",
|
||||
"props": {
|
||||
"label": "Missing Provider Field",
|
||||
"value": "unresolved",
|
||||
"bind": "authority.missing.field",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "missing",
|
||||
"freshness": {
|
||||
"state": "missing"
|
||||
},
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/missing"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "authority.command.pending",
|
||||
"kind": "card",
|
||||
"props": {
|
||||
"title": "Local Command Pressure",
|
||||
"authorityOwner": "renderer",
|
||||
"authorityState": "pending",
|
||||
"commandId": "authority.fixture.patch",
|
||||
"commandBoundary": "provider-receipt-required",
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/pending"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "authority.command.pending.text",
|
||||
"kind": "text",
|
||||
"props": {
|
||||
"text": "The renderer can show the pending intent. It cannot mark the provider value accepted."
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "authority.command.denied",
|
||||
"kind": "card",
|
||||
"props": {
|
||||
"title": "Denied Intent",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "denied",
|
||||
"receiptRef": "cultmesh://eve/fixtures/authority/receipts/denied",
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/denied"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "authority.command.denied.text",
|
||||
"kind": "text",
|
||||
"props": {
|
||||
"text": "Denied commands remain visible so local preview cannot erase provider refusal."
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "authority.prediction",
|
||||
"kind": "metric",
|
||||
"props": {
|
||||
"label": "Predicted Orbit",
|
||||
"value": "0.74 AU",
|
||||
"bind": "authority.orbit.predicted",
|
||||
"authorityOwner": "renderer",
|
||||
"authorityState": "predicted",
|
||||
"reconcilesWith": "authority.orbit.accepted",
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/predicted"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "authority.reconciled",
|
||||
"kind": "metric",
|
||||
"props": {
|
||||
"label": "Reconciled Orbit",
|
||||
"value": "0.72 AU",
|
||||
"bind": "authority.orbit.accepted",
|
||||
"authorityOwner": "provider",
|
||||
"authorityState": "reconciled",
|
||||
"reconciledFrom": "authority.orbit.predicted",
|
||||
"receiptRef": "cultmesh://eve/fixtures/authority/receipts/reconciled",
|
||||
"witnessRef": "cultmesh://eve/fixtures/authority/reconciled"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {
|
||||
"tokens": {
|
||||
"colorBackground": "#0B1114",
|
||||
"colorPanel": "#162022",
|
||||
"colorText": "#F2F7F1",
|
||||
"colorMuted": "#9AA8A2",
|
||||
"colorAccent": "#78D6A3",
|
||||
"colorWarning": "#D6B24A",
|
||||
"colorDanger": "#C95D63"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"schema": "gamecult.eve.command.v1",
|
||||
"command": "authority.fixture.patch",
|
||||
"label": "Patch witness value",
|
||||
"transport": "fixture-receipt",
|
||||
"authority": "provider",
|
||||
"result": "accepted-denied-or-reconciled"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -61,6 +61,13 @@ const localProviders = [
|
|||
freshness: { state: "fixture" },
|
||||
surfaces: [{ transport: "local-eve-dsl", surfaceId: "eve.reactive.dsl", url: "./fixtures/reactive-composition.eve" }],
|
||||
},
|
||||
{
|
||||
providerId: "gamecult.eve.authority-witness",
|
||||
title: "Authority Witness",
|
||||
kind: "surface.fixture",
|
||||
freshness: { state: "fixture" },
|
||||
surfaces: [{ transport: "local-json", surfaceId: "gamecult.eve.authority-witness", url: "./fixtures/authority-staleness-witness.json" }],
|
||||
},
|
||||
{
|
||||
providerId: "eve.cultui.inspector",
|
||||
title: "CultUI Inspector",
|
||||
|
|
|
|||
Loading…
Reference in a new issue