From ceb6e005c4e098b40b28397744e4e696bc4a4843 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 9 Jul 2026 09:57:17 +0100 Subject: [PATCH] Type EveUnity capture contract --- docs/eve-migration-roadmap.md | 6 ++ .../eve-runtime-capability.json | 12 ++++ ...cult.eve.runtime_capability.v1.schema.json | 58 +++++++++++++++++++ scripts/run-eveunity-lifecycle-smoke.ps1 | 22 +++++++ ...ntime-owner-conformance-consumer-smoke.ps1 | 7 ++- tools/parity/parity-manifest.json | 12 ++++ tools/parity/run-parity.mjs | 24 ++++++++ 7 files changed, 140 insertions(+), 1 deletion(-) diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 881e255..0908e29 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -421,6 +421,12 @@ Recently cut: compares it against the ledger, and the runtime-owner consumer smoke asserts the exported release fields without pretending the tagged EveUnity release already exists. +- EveUnity capture lifecycle now carries a structured pending capture contract. + `captureContract` names the Unity UI Toolkit runtime, capture kind, PNG + artifact pattern, conformance attachment point, required Aetheria provider + surface, and authority rule. The lifecycle smoke and runtime-owner consumer + smoke assert those fields while keeping the actual capture artifact as a + split blocker for EveUnity. - Runtime-owner conformance consumption now asserts EveUnity lifecycle stage evidence directly. The generic consumer supports `--expect-runtime-lifecycle-status` and diff --git a/packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json b/packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json index 5d48209..aee14fe 100644 --- a/packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json +++ b/packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json @@ -116,6 +116,18 @@ "capture": { "ownerRepo": "EveUnity", "status": "pending-editor-capture", + "captureContract": { + "ownerRepo": "EveUnity", + "runtimeId": "unity-uitoolkit", + "captureKind": "unity-editor-or-batchmode-png", + "artifactKind": "png", + "artifactPattern": "artifacts/eveunity-uitoolkit-capture/{stamp}/unity-uitoolkit.png", + "conformanceAttachment": "runtime.captureArtifacts[]", + "requiredProvider": "aetheria", + "requiredSurface": "aetheria.daemon.game", + "authority": "Capture observes runtime projection only; provider state, command acceptance, and receipts stay provider-owned.", + "publishProof": "Unity editor or batchmode capture artifact is attached to the runtime conformance report from EveUnity." + }, "evidencePaths": [], "pendingProofs": [ "Unity batchmode or editor capture artifact attached to the runtime conformance report." diff --git a/schemas/gamecult.eve.runtime_capability.v1.schema.json b/schemas/gamecult.eve.runtime_capability.v1.schema.json index 601fd4d..eeafb8e 100644 --- a/schemas/gamecult.eve.runtime_capability.v1.schema.json +++ b/schemas/gamecult.eve.runtime_capability.v1.schema.json @@ -378,6 +378,64 @@ "command": { "type": "string" }, + "captureContract": { + "type": "object", + "required": [ + "ownerRepo", + "runtimeId", + "captureKind", + "artifactKind", + "artifactPattern", + "conformanceAttachment", + "requiredProvider", + "requiredSurface", + "authority", + "publishProof" + ], + "properties": { + "ownerRepo": { + "type": "string", + "minLength": 1 + }, + "runtimeId": { + "type": "string", + "minLength": 1 + }, + "captureKind": { + "type": "string", + "minLength": 1 + }, + "artifactKind": { + "type": "string", + "minLength": 1 + }, + "artifactPattern": { + "type": "string", + "minLength": 1 + }, + "conformanceAttachment": { + "type": "string", + "minLength": 1 + }, + "requiredProvider": { + "type": "string", + "minLength": 1 + }, + "requiredSurface": { + "type": "string", + "minLength": 1 + }, + "authority": { + "type": "string", + "minLength": 1 + }, + "publishProof": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": true + }, "evidencePaths": { "type": "array", "items": { diff --git a/scripts/run-eveunity-lifecycle-smoke.ps1 b/scripts/run-eveunity-lifecycle-smoke.ps1 index d9114bc..3a9e346 100644 --- a/scripts/run-eveunity-lifecycle-smoke.ps1 +++ b/scripts/run-eveunity-lifecycle-smoke.ps1 @@ -158,6 +158,28 @@ foreach ($expectedText in @($testContract.packageName, $testContract.testAssembl } } +$captureContract = $manifest.lifecycle.capture.captureContract +if ($null -eq $captureContract) { + throw "EveUnity capture lifecycle missing captureContract" +} +if ($captureContract.ownerRepo -ne "EveUnity") { + throw "EveUnity capture contract has unexpected owner: $($captureContract.ownerRepo)" +} +if ($captureContract.runtimeId -ne "unity-uitoolkit") { + throw "EveUnity capture contract has unexpected runtime: $($captureContract.runtimeId)" +} +if ($captureContract.captureKind -ne "unity-editor-or-batchmode-png") { + throw "EveUnity capture contract has unexpected capture kind: $($captureContract.captureKind)" +} +if ($captureContract.artifactKind -ne "png") { + throw "EveUnity capture contract has unexpected artifact kind: $($captureContract.artifactKind)" +} +foreach ($field in @("artifactPattern", "conformanceAttachment", "requiredProvider", "requiredSurface", "authority", "publishProof")) { + if (-not $captureContract.$field) { + throw "EveUnity capture contract missing $field" + } +} + & (Join-Path $projectRoot "scripts\run-aetheria-unity-package-smoke.ps1") if ($LASTEXITCODE -ne 0) { throw "Aetheria Unity package smoke failed with exit code $LASTEXITCODE" diff --git a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 index fdae57d..32c8507 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -95,7 +95,12 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "unity-uitoolkit:test:testContract.runnerScript:scripts/run-aetheria-unity-editmode-tests.ps1" ` --expect-runtime-lifecycle-field "unity-uitoolkit:test:testContract.packageName:org.gamecult.eve.unity-uitoolkit" ` --expect-runtime-lifecycle-field "unity-uitoolkit:test:testContract.testAssembly:GameCult.Eve.UnityUIToolkit.Tests" ` - --expect-runtime-lifecycle-field "unity-uitoolkit:test:testContract.testPlatform:EditMode" + --expect-runtime-lifecycle-field "unity-uitoolkit:test:testContract.testPlatform:EditMode" ` + --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.captureKind:unity-editor-or-batchmode-png" ` + --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.artifactKind:png" ` + --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.conformanceAttachment:runtime.captureArtifacts[]" ` + --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.requiredProvider:aetheria" ` + --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.requiredSurface:aetheria.daemon.game" if ($LASTEXITCODE -ne 0) { throw "Runtime owner conformance consumer smoke failed with exit code $LASTEXITCODE" diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index 407efed..736b9b1 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -1250,6 +1250,18 @@ "capture": { "ownerRepo": "EveUnity", "status": "pending-editor-capture", + "captureContract": { + "ownerRepo": "EveUnity", + "runtimeId": "unity-uitoolkit", + "captureKind": "unity-editor-or-batchmode-png", + "artifactKind": "png", + "artifactPattern": "artifacts/eveunity-uitoolkit-capture/{stamp}/unity-uitoolkit.png", + "conformanceAttachment": "runtime.captureArtifacts[]", + "requiredProvider": "aetheria", + "requiredSurface": "aetheria.daemon.game", + "authority": "Capture observes runtime projection only; provider state, command acceptance, and receipts stay provider-owned.", + "publishProof": "Unity editor or batchmode capture artifact is attached to the runtime conformance report from EveUnity." + }, "evidencePaths": [], "pendingProofs": [ "Unity batchmode or editor capture artifact attached to the runtime conformance report." diff --git a/tools/parity/run-parity.mjs b/tools/parity/run-parity.mjs index 419ed23..d05115a 100644 --- a/tools/parity/run-parity.mjs +++ b/tools/parity/run-parity.mjs @@ -1254,6 +1254,7 @@ function compareRuntimeLifecycleClaims(expectedLifecycle, actualLifecycle, manif errors.push(...missingMembers(expected.pendingProofs || [], actual.pendingProofs || [], `${label}.pendingProofs`)); errors.push(...compareReleaseContract(expected.releaseContract, actual.releaseContract, `${label}.releaseContract`)); errors.push(...compareTestContract(expected.testContract, actual.testContract, `${label}.testContract`)); + errors.push(...compareCaptureContract(expected.captureContract, actual.captureContract, `${label}.captureContract`)); for (const evidencePath of actual.evidencePaths || []) { if (!existsSync(path.join(repoRoot, evidencePath))) { @@ -1264,6 +1265,29 @@ function compareRuntimeLifecycleClaims(expectedLifecycle, actualLifecycle, manif return errors; } +function compareCaptureContract(expected, actual, label) { + const errors = []; + if (!expected) return errors; + if (!actual) return [`${label}:missing`]; + for (const key of [ + "ownerRepo", + "runtimeId", + "captureKind", + "artifactKind", + "artifactPattern", + "conformanceAttachment", + "requiredProvider", + "requiredSurface", + "authority", + "publishProof", + ]) { + if ((expected[key] || "") !== (actual[key] || "")) { + errors.push(`${label}.${key}:expected ${expected[key] || ""} got ${actual[key] || ""}`); + } + } + return errors; +} + function compareTestContract(expected, actual, label) { const errors = []; if (!expected) return errors;