stylegallery 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -1
- package/DOMAINS.md +2 -6
- package/GOVERNANCE.md +10 -9
- package/README.md +29 -127
- package/consumer-reference/agent-native/v2/admission-policy.json +646 -0
- package/consumer-reference/agent-native/v2/material-registry.json +1 -0
- package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +50 -0
- package/consumer-reference/agent-native/v2/schema/material-manifest.schema.json +17 -0
- package/consumer-reference/agent-native/v2/schema/material-record.schema.json +20 -0
- package/consumer-reference/contract.md +1 -1
- package/consumer-reference/index.md +5 -3
- package/layout/index.md +124 -0
- package/log.md +57 -0
- package/package.json +183 -22
- package/scripts/agent-native/v2/experimental-extension-registry.mjs +143 -0
- package/scripts/agent-native/v2/extensions/a2a-projection.mjs +264 -0
- package/scripts/agent-native/v2/extensions/agui-projection.mjs +191 -0
- package/scripts/agent-native/v2/material-admission.mjs +295 -0
- package/scripts/agent-native/v2/material-cli-adapter.mjs +134 -0
- package/scripts/agent-native/v2/material-context.mjs +251 -0
- package/scripts/agent-native/v2/material-identity.mjs +71 -0
- package/scripts/agent-native/v2/material-mcp-adapter.mjs +253 -0
- package/scripts/agent-native/v2/material-operation-registry.mjs +123 -0
- package/scripts/agent-native/v2/material-queries.mjs +398 -0
- package/scripts/agent-native/v2/material-registry.mjs +319 -0
- package/scripts/sg-material-mcp.mjs +98 -0
- package/scripts/sg-material.mjs +27 -0
- package/consumer-reference/adapters/style-dictionary.config.mjs +0 -36
- package/consumer-reference/baselines/calibration.json +0 -260
- package/consumer-reference/baselines/manifest.json +0 -21
- package/consumer-reference/fixtures/consumer-conformance/e2e-fixture.mjs +0 -282
- package/consumer-reference/fixtures/consumer-conformance/manifest.json +0 -102
- package/consumer-reference/fixtures/consumer-conformance/runtime-proof.mjs +0 -32
- package/consumer-reference/fixtures/consumer-conformance/valid-migration-result.json +0 -18
- package/consumer-reference/fixtures/consumer-conformance/valid-migration.json +0 -142
- package/consumer-reference/fixtures/invalid-stable-ended-support.json +0 -19
- package/consumer-reference/fixtures/promotion/invalid-blocking-evidence.json +0 -26
- package/consumer-reference/fixtures/promotion/invalid-count-only.json +0 -29
- package/consumer-reference/fixtures/promotion/invalid-missing-owner-migration.json +0 -25
- package/consumer-reference/fixtures/promotion/invalid-normative-bypass-no-regression.json +0 -25
- package/consumer-reference/fixtures/promotion/invalid-related-counted-independent.json +0 -45
- package/consumer-reference/fixtures/promotion/invalid-stable-ended-support.json +0 -26
- package/consumer-reference/fixtures/promotion/manifest.json +0 -15
- package/consumer-reference/fixtures/promotion/valid-deferred-example.json +0 -67
- package/consumer-reference/fixtures/promotion/valid-normative-bypass.json +0 -67
- package/consumer-reference/fixtures/token-portability/invalid-cycle.json +0 -7
- package/consumer-reference/fixtures/token-portability/invalid-dangling-alias.json +0 -6
- package/consumer-reference/fixtures/token-portability/invalid-extends.json +0 -4
- package/consumer-reference/fixtures/token-portability/invalid-json-pointer.json +0 -7
- package/consumer-reference/fixtures/token-portability/invalid-resolver.json +0 -9
- package/consumer-reference/fixtures/token-portability/invalid-type-mismatch.json +0 -10
- package/consumer-reference/fixtures/token-portability/invalid-unknown-reserved.json +0 -6
- package/consumer-reference/fixtures/token-portability/invalid-untested-type.json +0 -6
- package/consumer-reference/fixtures/token-portability/valid-border.json +0 -14
- package/consumer-reference/fixtures/token-portability/valid-reference.json +0 -32
- package/consumer-reference/fixtures/token-portability/valid-whole-alias.json +0 -7
- package/consumer-reference/fixtures/valid-deprecated.json +0 -21
- package/consumer-reference/fixtures/valid-experimental.json +0 -19
- package/consumer-reference/generated/manifest.json +0 -40
- package/consumer-reference/generated/tokens.css +0 -12
- package/consumer-reference/policies/shared-experimental.json +0 -37
- package/consumer-reference/schema/ax-evidence.schema.json +0 -30
- package/consumer-reference/schema/baseline-manifest.schema.json +0 -55
- package/consumer-reference/schema/calibration-record.schema.json +0 -190
- package/consumer-reference/schema/capture-session.schema.json +0 -161
- package/consumer-reference/schema/component-state.schema.json +0 -150
- package/consumer-reference/schema/consumer-conformance-record.schema.json +0 -365
- package/consumer-reference/schema/dom-evidence.schema.json +0 -38
- package/consumer-reference/schema/evidence-record.schema.json +0 -81
- package/consumer-reference/schema/fixture-manifest.schema.json +0 -32
- package/consumer-reference/schema/item.schema.json +0 -188
- package/consumer-reference/schema/page-evidence-manifest.schema.json +0 -216
- package/consumer-reference/schema/page-evidence-session.schema.json +0 -119
- package/consumer-reference/schema/portable-tokens.schema.json +0 -104
- package/consumer-reference/schema/promotion-rfc.schema.json +0 -219
- package/consumer-reference/schema/runtime-evidence-manifest.schema.json +0 -33
- package/consumer-reference/schema/visual-evidence.schema.json +0 -31
- package/design-engineering/consumer-migration-readiness.md +0 -124
- package/design-engineering/interface-craft.md +0 -107
- package/design-engineering/reference-profiles/external-adaptation/index.md +0 -12
- package/design-engineering/reference-profiles/governed-local/editorial/components/button.component.json +0 -125
- package/design-engineering/reference-profiles/governed-local/editorial/evidence/button.evidence.json +0 -3504
- package/design-engineering/reference-profiles/governed-local/editorial/fixtures/button.fixture.json +0 -65
- package/design-engineering/reference-profiles/governed-local/editorial/generated/evidence-coverage.md +0 -23
- package/design-engineering/reference-profiles/governed-local/editorial/generated/keyboard-matrix.md +0 -19
- package/design-engineering/reference-profiles/governed-local/editorial/generated/state-matrix.md +0 -21
- package/design-engineering/reference-profiles/governed-local/editorial/local-foundations.json +0 -12
- package/design-engineering/reference-profiles/governed-local/editorial/states/button.states.json +0 -195
- package/design-engineering/reference-profiles/governed-local/editorial/tokens.dtcg.json +0 -17
- package/design-engineering/reference-profiles/governed-local/terminal/components/button.component.json +0 -125
- package/design-engineering/reference-profiles/governed-local/terminal/evidence/button.evidence.json +0 -3504
- package/design-engineering/reference-profiles/governed-local/terminal/fixtures/button.fixture.json +0 -65
- package/design-engineering/reference-profiles/governed-local/terminal/generated/evidence-coverage.md +0 -23
- package/design-engineering/reference-profiles/governed-local/terminal/generated/keyboard-matrix.md +0 -19
- package/design-engineering/reference-profiles/governed-local/terminal/generated/state-matrix.md +0 -21
- package/design-engineering/reference-profiles/governed-local/terminal/local-foundations.json +0 -12
- package/design-engineering/reference-profiles/governed-local/terminal/profile.json +0 -43
- package/design-engineering/reference-profiles/governed-local/terminal/states/button.states.json +0 -195
- package/design-engineering/reference-profiles/governed-local/terminal/tokens.dtcg.json +0 -17
- package/game-ui/classification.md +0 -82
- package/game-ui/reference-record.md +0 -62
- package/game-ui/screen-hierarchy.md +0 -107
- package/game-ui/unity/architecture.md +0 -166
- package/game-ui/unity/cli-loop.md +0 -84
- package/game-ui/unity/data/unity-technologies-public-repositories.json +0 -26654
- package/game-ui/unity/org-wiki.md +0 -146
- package/game-ui/unity/repository-map.md +0 -102
- package/game-ui/unity/ui-systems.md +0 -85
- package/motion/practice-reference.md +0 -145
- package/motion/review-workflow.md +0 -86
- package/motion/vocabulary.md +0 -82
- package/platform-guides/apple-interaction.md +0 -89
- package/scripts/agent-native/events.mjs +0 -113
- package/scripts/agent-native/immutable-store.mjs +0 -102
- package/scripts/artifact-metadata.mjs +0 -20
- package/scripts/audit-evidence-freshness.mjs +0 -308
- package/scripts/baseline-contract.mjs +0 -189
- package/scripts/baseline-schema-parity.mjs +0 -40
- package/scripts/build-reference-artifacts.mjs +0 -127
- package/scripts/calibration-raw-contract.mjs +0 -172
- package/scripts/capture-session-contract.mjs +0 -187
- package/scripts/component-state-artifact-fixture.mjs +0 -44
- package/scripts/component-state-contract.mjs +0 -99
- package/scripts/component-state-semantics.mjs +0 -128
- package/scripts/component-state-workflow-contract.mjs +0 -67
- package/scripts/component-state-workflow-negative-cases.mjs +0 -64
- package/scripts/consumer-conformance-contract.mjs +0 -198
- package/scripts/consumer-evidence-governance-contract.mjs +0 -210
- package/scripts/consumer-reference-case-runner.mjs +0 -93
- package/scripts/consumer-reference-schema.mjs +0 -155
- package/scripts/create-component-state-session.mjs +0 -100
- package/scripts/create-page-evidence-session.mjs +0 -139
- package/scripts/domain-document-boundaries.mjs +0 -40
- package/scripts/domain-validation-checks.mjs +0 -141
- package/scripts/evidence-artifact-contract.mjs +0 -191
- package/scripts/finalize-component-state-evidence.mjs +0 -165
- package/scripts/finalize-page-evidence.mjs +0 -197
- package/scripts/generate-consumer-reference-evidence.mjs +0 -154
- package/scripts/generate-patterns.mjs +0 -218
- package/scripts/governance-matrix-contract.mjs +0 -73
- package/scripts/governance-matrix-negative-cases.mjs +0 -114
- package/scripts/governance-policy-contract.mjs +0 -49
- package/scripts/governance-test-fixture.mjs +0 -321
- package/scripts/governance-workflow-negative-cases.mjs +0 -241
- package/scripts/governed-profile-registry.mjs +0 -125
- package/scripts/json-schema-formats.mjs +0 -31
- package/scripts/markdown-structure.mjs +0 -45
- package/scripts/page-artifact-metadata.mjs +0 -124
- package/scripts/page-evidence-contract.mjs +0 -297
- package/scripts/page-evidence-fixture.mjs +0 -271
- package/scripts/pattern-data.mjs +0 -325
- package/scripts/profile-record-contract.mjs +0 -140
- package/scripts/promotion-attestation-contract.mjs +0 -91
- package/scripts/promotion-boundary-test-contract.mjs +0 -92
- package/scripts/promotion-fixture-inventory.mjs +0 -109
- package/scripts/promotion-governance-contract.mjs +0 -28
- package/scripts/reference-artifact-path-contract.mjs +0 -28
- package/scripts/reference-profile-contract.mjs +0 -114
- package/scripts/reference-token-contract.mjs +0 -156
- package/scripts/run-consumer-page-evidence-ci.mjs +0 -170
- package/scripts/summarize-sentinel-calibration.mjs +0 -98
- package/scripts/test-agent-adapter-conformance.mjs +0 -250
- package/scripts/test-agent-conformance-receipt.mjs +0 -106
- package/scripts/test-agent-events.mjs +0 -81
- package/scripts/test-agent-execution-effects.mjs +0 -114
- package/scripts/test-agent-execution-fixtures.mjs +0 -140
- package/scripts/test-agent-execution-kernel.mjs +0 -39
- package/scripts/test-agent-execution-learning.mjs +0 -130
- package/scripts/test-agent-execution-lifecycle.mjs +0 -143
- package/scripts/test-agent-execution-safety.mjs +0 -158
- package/scripts/test-agent-execution-views.mjs +0 -117
- package/scripts/test-agent-identity-integrity-cases.mjs +0 -160
- package/scripts/test-agent-knowledge-kernel.mjs +0 -183
- package/scripts/test-agent-learning.mjs +0 -246
- package/scripts/test-agent-mcp.mjs +0 -246
- package/scripts/test-agent-native-schemas.mjs +0 -215
- package/scripts/test-agent-projections.mjs +0 -249
- package/scripts/test-agent-registry-mcp-integrity.mjs +0 -215
- package/scripts/test-agent-registry-mutations.mjs +0 -110
- package/scripts/test-audit-evidence-freshness.mjs +0 -177
- package/scripts/test-component-state-sentinel.mjs +0 -35
- package/scripts/test-component-state-source-contract.mjs +0 -83
- package/scripts/test-consumer-conformance-sentinel.mjs +0 -165
- package/scripts/test-consumer-reference-sentinel.mjs +0 -31
- package/scripts/test-generate-consumer-reference-evidence.mjs +0 -124
- package/scripts/test-json-cli-output.mjs +0 -151
- package/scripts/test-json-schema-formats.mjs +0 -40
- package/scripts/test-reference-adapters.mjs +0 -199
- package/scripts/test-renderer-purity.mjs +0 -34
- package/scripts/test-sg-cli.mjs +0 -129
- package/scripts/test-summarize-sentinel-calibration.mjs +0 -226
- package/scripts/test-validate-baseline-manifest.mjs +0 -234
- package/scripts/test-validate-component-state-artifacts.mjs +0 -243
- package/scripts/test-validate-component-state.mjs +0 -106
- package/scripts/test-validate-consumer-conformance.mjs +0 -427
- package/scripts/test-validate-consumer-reference-cli.mjs +0 -69
- package/scripts/test-validate-consumer-reference.mjs +0 -263
- package/scripts/test-validate-domains.mjs +0 -357
- package/scripts/test-validate-governance.mjs +0 -292
- package/scripts/test-validate-ia.mjs +0 -262
- package/scripts/test-validate-okf.mjs +0 -73
- package/scripts/test-validate-page-evidence.mjs +0 -302
- package/scripts/test-validate-patterns.mjs +0 -157
- package/scripts/test-validate-promotion-rfc.mjs +0 -250
- package/scripts/test-validate-reference-profiles.mjs +0 -170
- package/scripts/test-validate-unity-org-wiki.mjs +0 -57
- package/scripts/test-validate-unity-source-contracts.mjs +0 -67
- package/scripts/test-validate-vocabulary.mjs +0 -174
- package/scripts/test-validate-webpage-workflow.mjs +0 -293
- package/scripts/validate-baseline-manifest.mjs +0 -44
- package/scripts/validate-catalog.mjs +0 -65
- package/scripts/validate-component-state.mjs +0 -141
- package/scripts/validate-consumer-conformance.mjs +0 -477
- package/scripts/validate-consumer-reference.mjs +0 -288
- package/scripts/validate-domains.mjs +0 -237
- package/scripts/validate-governance.mjs +0 -248
- package/scripts/validate-ia.mjs +0 -136
- package/scripts/validate-links.mjs +0 -66
- package/scripts/validate-okf.mjs +0 -104
- package/scripts/validate-page-evidence.mjs +0 -191
- package/scripts/validate-patterns.mjs +0 -246
- package/scripts/validate-promotion-rfc.mjs +0 -224
- package/scripts/validate-reference-artifacts.mjs +0 -125
- package/scripts/validate-renderer-purity.mjs +0 -56
- package/scripts/validate-unity-org-wiki.mjs +0 -146
- package/scripts/validate-unity-source-contracts.mjs +0 -107
- package/scripts/validate-vocabulary.mjs +0 -115
- package/scripts/validate-webpage-workflow.mjs +0 -254
- package/scripts/visual-expectation-contract.mjs +0 -20
- package/scripts/workflow-action-contract.mjs +0 -163
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
-
|
|
6
|
-
const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
|
-
const moduleFiles = Object.freeze({
|
|
8
|
-
a2a: path.join(repositoryRoot, "scripts", "agent-native", "a2a-projection.mjs"),
|
|
9
|
-
agui: path.join(repositoryRoot, "scripts", "agent-native", "agui-projection.mjs"),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const domainTask = Object.freeze({
|
|
13
|
-
stableRef: "sg:task/projection-fixture",
|
|
14
|
-
taskId: "sg:task/projection-fixture",
|
|
15
|
-
state: "RUNNING",
|
|
16
|
-
runId: "sg:run/projection-fixture",
|
|
17
|
-
intent: { operation: "resolve", stableRef: "sg:profile/editorial-reference-profile" },
|
|
18
|
-
requiredResult: { type: "profile" },
|
|
19
|
-
});
|
|
20
|
-
const domainRun = Object.freeze({ runId: "sg:run/projection-fixture", taskId: domainTask.taskId, state: "RUNNING" });
|
|
21
|
-
const protocolBinding = Object.freeze({
|
|
22
|
-
bindingId: "sg:binding/a2a-projection-fixture",
|
|
23
|
-
protocolBindingId: "sg:binding/a2a-projection-fixture",
|
|
24
|
-
protocol: "a2a",
|
|
25
|
-
taskId: domainTask.taskId,
|
|
26
|
-
runId: domainRun.runId,
|
|
27
|
-
});
|
|
28
|
-
const message = Object.freeze({
|
|
29
|
-
messageId: "a2a-message-projection-fixture",
|
|
30
|
-
role: "user",
|
|
31
|
-
parts: [{ kind: "text", text: "Resolve the editorial profile." }],
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
function pick(value, ...keys) {
|
|
35
|
-
if (!value || typeof value !== "object") return undefined;
|
|
36
|
-
for (const key of keys) if (Object.hasOwn(value, key)) return value[key];
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function unwrap(value) {
|
|
41
|
-
return value?.ok === true && Object.hasOwn(value, "result") ? value.result : value;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function object(value) {
|
|
45
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function stateOf(value) {
|
|
49
|
-
const status = pick(value, "status");
|
|
50
|
-
return String(pick(status, "state", "status") ?? pick(value, "state", "taskState", "task_state") ?? "").toLowerCase();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function idOf(value, ...keys) {
|
|
54
|
-
return pick(value, ...keys, "id", "taskId", "task_id", "runId", "run_id", "stableRef", "stable_ref");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function load(name) {
|
|
58
|
-
try {
|
|
59
|
-
return { ok: true, module: await import(pathToFileURL(moduleFiles[name]).href) };
|
|
60
|
-
} catch (error) {
|
|
61
|
-
return {
|
|
62
|
-
ok: false,
|
|
63
|
-
error: {
|
|
64
|
-
code: "kernel_module_missing",
|
|
65
|
-
module: name,
|
|
66
|
-
path: moduleFiles[name],
|
|
67
|
-
message: error instanceof Error ? error.message : String(error),
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function findExport(loaded, names, moduleName) {
|
|
74
|
-
if (!loaded.ok) throw Object.assign(new Error(loaded.error.message), loaded.error);
|
|
75
|
-
for (const name of names) if (typeof loaded.module[name] === "function") return loaded.module[name];
|
|
76
|
-
const error = new Error(`${moduleName} must export one of ${names.join(", ")}`);
|
|
77
|
-
error.code = "kernel_export_missing";
|
|
78
|
-
error.module = moduleName;
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function call(loaded, names, moduleName, input) {
|
|
83
|
-
const fn = findExport(loaded, names, moduleName);
|
|
84
|
-
return await fn(input);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function row(name, expected, actual, ok, details) {
|
|
88
|
-
return { actual, expected, name, ok, ...(details ? { details } : {}) };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function failure(error) {
|
|
92
|
-
return { code: error?.code ?? "projection_case_exception", message: error?.message ?? String(error), ...(error?.path ? { path: error.path } : {}) };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function taskProjection(value) {
|
|
96
|
-
const result = unwrap(value);
|
|
97
|
-
return pick(result, "task", "taskProjection", "task_projection") ?? result;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function bindingOf(value) {
|
|
101
|
-
const result = unwrap(value);
|
|
102
|
-
return pick(result, "protocolBinding", "protocol_binding", "binding") ?? {};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function protocolTaskId(value) {
|
|
106
|
-
const task = taskProjection(value);
|
|
107
|
-
return idOf(task, "id", "taskId", "task_id");
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async function testA2A(loaded) {
|
|
111
|
-
const rows = [];
|
|
112
|
-
try {
|
|
113
|
-
const card = unwrap(await call(loaded, ["createAgentCard", "buildAgentCard", "projectAgentCard", "agentCard"], "a2a", { fixture: true }));
|
|
114
|
-
const capabilities = pick(card, "capabilities");
|
|
115
|
-
rows.push(row(
|
|
116
|
-
"a2a_agent_card_is_v1_shaped",
|
|
117
|
-
"Agent Card has protocolVersion, identity, URL, capabilities, input/output modes, and skills",
|
|
118
|
-
card,
|
|
119
|
-
object(card)
|
|
120
|
-
&& typeof pick(card, "protocolVersion", "protocol_version") === "string"
|
|
121
|
-
&& typeof pick(card, "name") === "string"
|
|
122
|
-
&& typeof pick(card, "url") === "string"
|
|
123
|
-
&& object(capabilities)
|
|
124
|
-
&& Array.isArray(pick(card, "defaultInputModes", "default_input_modes"))
|
|
125
|
-
&& Array.isArray(pick(card, "defaultOutputModes", "default_output_modes"))
|
|
126
|
-
&& Array.isArray(pick(card, "skills")),
|
|
127
|
-
));
|
|
128
|
-
|
|
129
|
-
const map = findExport(loaded, ["mapTaskState", "projectTaskState", "toA2ATaskState"], "a2a");
|
|
130
|
-
const mappings = {
|
|
131
|
-
PENDING: "submitted", RUNNING: "working", COMPLETED: "completed", FAILED: "failed",
|
|
132
|
-
CANCELED: "canceled", REJECTED: "rejected", AUTH_REQUIRED: "auth-required", UNKNOWN: "unknown",
|
|
133
|
-
};
|
|
134
|
-
const actualMappings = Object.fromEntries(Object.entries(mappings).map(([input]) => [input, map(input)]));
|
|
135
|
-
rows.push(row("a2a_task_state_mapping_is_total", "all domain terminal/intermediate states map to official A2A states", actualMappings, Object.entries(mappings).every(([input, expected]) => String(actualMappings[input]).toLowerCase() === expected)));
|
|
136
|
-
|
|
137
|
-
const send = unwrap(await call(loaded, ["sendMessage", "projectSendMessage", "handleSendMessage"], "a2a", {
|
|
138
|
-
message,
|
|
139
|
-
task: domainTask,
|
|
140
|
-
run: domainRun,
|
|
141
|
-
protocolBinding,
|
|
142
|
-
}));
|
|
143
|
-
const sentTaskId = protocolTaskId(send);
|
|
144
|
-
const sentBinding = bindingOf(send);
|
|
145
|
-
const bindingId = idOf(sentBinding, "protocolBindingId", "protocol_binding_id", "bindingId", "binding_id");
|
|
146
|
-
const boundTaskId = idOf(sentBinding, "taskId", "task_id", "domainTaskId", "domain_task_id");
|
|
147
|
-
const boundRunId = idOf(sentBinding, "runId", "run_id", "domainRunId", "domain_run_id");
|
|
148
|
-
rows.push(row(
|
|
149
|
-
"a2a_send_message_creates_distinct_protocol_binding",
|
|
150
|
-
"SendMessage returns a submitted A2A task and ProtocolBinding that does not replace domain Task/Run IDs",
|
|
151
|
-
{ taskId: sentTaskId, state: stateOf(send), bindingId, boundTaskId, boundRunId },
|
|
152
|
-
object(send) && typeof sentTaskId === "string" && stateOf(send) === "submitted"
|
|
153
|
-
&& typeof bindingId === "string" && bindingId !== domainTask.taskId && bindingId !== domainRun.runId
|
|
154
|
-
&& boundTaskId === domainTask.taskId && boundRunId === domainRun.runId,
|
|
155
|
-
));
|
|
156
|
-
|
|
157
|
-
const get = unwrap(await call(loaded, ["getTask", "projectGetTask", "handleGetTask"], "a2a", {
|
|
158
|
-
task: send,
|
|
159
|
-
domainTask,
|
|
160
|
-
run: domainRun,
|
|
161
|
-
protocolBinding: sentBinding,
|
|
162
|
-
taskId: sentTaskId,
|
|
163
|
-
}));
|
|
164
|
-
rows.push(row("a2a_get_task_projects_current_domain_state", "GetTask preserves protocol task identity and maps RUNNING to working", { taskId: protocolTaskId(get), state: stateOf(get) }, protocolTaskId(get) === sentTaskId && stateOf(get) === "working"));
|
|
165
|
-
|
|
166
|
-
const canceled = unwrap(await call(loaded, ["cancelTask", "projectCancelTask", "handleCancelTask"], "a2a", {
|
|
167
|
-
task: get,
|
|
168
|
-
domainTask: { ...domainTask, state: "CANCELED" },
|
|
169
|
-
run: domainRun,
|
|
170
|
-
protocolBinding: sentBinding,
|
|
171
|
-
taskId: sentTaskId,
|
|
172
|
-
}));
|
|
173
|
-
rows.push(row("a2a_cancel_task_projects_canceled", "CancelTask returns the same protocol task in canceled state", { taskId: protocolTaskId(canceled), state: stateOf(canceled) }, protocolTaskId(canceled) === sentTaskId && stateOf(canceled) === "canceled"));
|
|
174
|
-
} catch (error) {
|
|
175
|
-
rows.push(row("a2a_projection_kernel_available", "A2A projection module exports the required pure functions", failure(error), false));
|
|
176
|
-
}
|
|
177
|
-
return rows;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function eventType(event) {
|
|
181
|
-
return String(pick(event, "type", "eventType", "event_type", "name") ?? "").toUpperCase();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function eventList(value) {
|
|
185
|
-
const result = unwrap(value);
|
|
186
|
-
return Array.isArray(result) ? result : pick(result, "events", "items") ?? [];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async function testAGUI(loaded) {
|
|
190
|
-
const rows = [];
|
|
191
|
-
try {
|
|
192
|
-
const project = findExport(loaded, ["projectAgUiEvents", "projectAGUIEvents", "projectAguiEvents", "createAgUiEvents"], "agui");
|
|
193
|
-
const projection = await project({
|
|
194
|
-
task: domainTask,
|
|
195
|
-
run: domainRun,
|
|
196
|
-
protocolBinding: { ...protocolBinding, protocol: "ag-ui", bindingId: "sg:binding/agui-projection-fixture" },
|
|
197
|
-
text: "Editorial profile resolved.",
|
|
198
|
-
toolCall: { id: "tool-call-projection-fixture", name: "resolve", args: { stableRef: "sg:profile/editorial-reference-profile" } },
|
|
199
|
-
state: { stableRef: "sg:profile/editorial-reference-profile", status: "resolved" },
|
|
200
|
-
outcome: "COMPLETED",
|
|
201
|
-
});
|
|
202
|
-
const events = eventList(projection);
|
|
203
|
-
const types = events.map(eventType);
|
|
204
|
-
const index = (names) => types.findIndex((type) => names.includes(type));
|
|
205
|
-
const terminal = types.filter((type) => ["RUN_FINISHED", "RUN_ERROR"].includes(type));
|
|
206
|
-
const ordered = index(["RUN_STARTED"]) >= 0
|
|
207
|
-
&& index(["TEXT_MESSAGE_START"]) > index(["RUN_STARTED"])
|
|
208
|
-
&& index(["TEXT_MESSAGE_CONTENT"]) > index(["TEXT_MESSAGE_START"])
|
|
209
|
-
&& index(["TEXT_MESSAGE_END"]) > index(["TEXT_MESSAGE_CONTENT"])
|
|
210
|
-
&& index(["TOOL_CALL_START"]) > index(["TEXT_MESSAGE_END"])
|
|
211
|
-
&& index(["TOOL_CALL_ARGS", "TOOL_CALL_ARGUMENTS"]) > index(["TOOL_CALL_START"])
|
|
212
|
-
&& index(["TOOL_CALL_END"]) > index(["TOOL_CALL_ARGS", "TOOL_CALL_ARGUMENTS"])
|
|
213
|
-
&& index(["STATE_SNAPSHOT", "STATE_DELTA"]) > index(["TOOL_CALL_END"])
|
|
214
|
-
&& terminal.length === 1
|
|
215
|
-
&& types.indexOf(terminal[0]) === types.length - 1;
|
|
216
|
-
rows.push(row("agui_projection_has_ordered_v057_lifecycle", "RUN, text, tool, state, then exactly one terminal event", { types }, ordered));
|
|
217
|
-
|
|
218
|
-
const validate = findExport(loaded, ["validateAgUiTransitions", "validateAGUITransitions", "assertAgUiTransitions", "validateEventSequence"], "agui");
|
|
219
|
-
let rejected = false;
|
|
220
|
-
let rejection;
|
|
221
|
-
try {
|
|
222
|
-
rejection = await validate({ events: [{ type: "RUN_FINISHED", runId: "protocol-run-fixture" }, { type: "RUN_STARTED", runId: "protocol-run-fixture" }] });
|
|
223
|
-
rejected = rejection?.ok === false || rejection?.valid === false;
|
|
224
|
-
} catch (error) {
|
|
225
|
-
rejected = true;
|
|
226
|
-
rejection = failure(error);
|
|
227
|
-
}
|
|
228
|
-
rows.push(row("agui_invalid_transition_is_rejected", "a terminal-before-start sequence is rejected before projection", rejection, rejected));
|
|
229
|
-
} catch (error) {
|
|
230
|
-
rows.push(row("agui_projection_kernel_available", "AG-UI projection module exports ordered event and transition validation functions", failure(error), false));
|
|
231
|
-
}
|
|
232
|
-
return rows;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
async function main() {
|
|
236
|
-
const unsupported = process.argv.slice(2).filter((argument) => argument !== "--json");
|
|
237
|
-
if (unsupported.length > 0) {
|
|
238
|
-
process.stdout.write(`${JSON.stringify({ ok: false, status: "RED", failures: [{ code: "argument_unknown", message: `unknown argument ${unsupported[0]}` }], results: [] }, null, 2)}\n`);
|
|
239
|
-
process.exitCode = 1;
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const modules = { a2a: await load("a2a"), agui: await load("agui") };
|
|
243
|
-
const results = [...await testA2A(modules.a2a), ...await testAGUI(modules.agui)];
|
|
244
|
-
const ok = results.every((result) => result.ok);
|
|
245
|
-
process.stdout.write(`${JSON.stringify({ ok, status: ok ? "GREEN" : "RED", modules: Object.fromEntries(Object.entries(modules).map(([name, loaded]) => [name, loaded.ok ? { ok: true } : { ok: false, error: loaded.error }])), results }, null, 2)}\n`);
|
|
246
|
-
process.exitCode = ok ? 0 : 1;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
await main();
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
4
|
-
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
5
|
-
|
|
6
|
-
import { canonicalize } from "./agent-native/canonical-json.mjs";
|
|
7
|
-
import { createStyleGalleryMcpServer } from "./agent-native/mcp-adapter.mjs";
|
|
8
|
-
import { agentNativeRegistry } from "./agent-native/registry.mjs";
|
|
9
|
-
|
|
10
|
-
const MUTATIONS = [
|
|
11
|
-
"effect.record",
|
|
12
|
-
"effect.reconcile",
|
|
13
|
-
"proposal.create",
|
|
14
|
-
"proposal.decide",
|
|
15
|
-
"proposal.promote",
|
|
16
|
-
"proposal.verify",
|
|
17
|
-
"run.start",
|
|
18
|
-
"task.create",
|
|
19
|
-
];
|
|
20
|
-
const PROFILE_REF = "sg:profile/editorial-reference-profile";
|
|
21
|
-
|
|
22
|
-
function result(name, expected, actual, ok) {
|
|
23
|
-
return { actual, expected, name, ok };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function equal(left, right) {
|
|
27
|
-
return canonicalize(left) === canonicalize(right);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function envelope(response) {
|
|
31
|
-
if (response?.structuredContent && typeof response.structuredContent === "object") return response.structuredContent;
|
|
32
|
-
const text = response?.content?.find((item) => item?.type === "text")?.text;
|
|
33
|
-
try { return JSON.parse(text); } catch { return null; }
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function connected(registry = agentNativeRegistry) {
|
|
37
|
-
const server = createStyleGalleryMcpServer({ registry });
|
|
38
|
-
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
39
|
-
const client = new Client({ name: "stylegallery-registry-mcp-integrity", version: "1.0.0" });
|
|
40
|
-
await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
|
|
41
|
-
return { client, server };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function close(connection) {
|
|
45
|
-
await connection.client.close().catch(() => {});
|
|
46
|
-
const closed = connection.server.close?.();
|
|
47
|
-
if (closed && typeof closed.catch === "function") await closed.catch(() => {});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function rejected(action) {
|
|
51
|
-
try {
|
|
52
|
-
const response = await action();
|
|
53
|
-
return { error: null, response };
|
|
54
|
-
} catch (error) {
|
|
55
|
-
return { error: error instanceof Error ? error.message : String(error), response: null };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function main() {
|
|
60
|
-
const results = [];
|
|
61
|
-
const names = agentNativeRegistry.operations.map((operation) => operation.name).sort();
|
|
62
|
-
const missingMutations = MUTATIONS.filter((name) => !names.includes(name));
|
|
63
|
-
results.push(result(
|
|
64
|
-
"common_registry_contains_governed_mutations",
|
|
65
|
-
"proposal, task, run, effect recording, and effect reconciliation operations exist in the common registry",
|
|
66
|
-
{ missingMutations, names },
|
|
67
|
-
missingMutations.length === 0,
|
|
68
|
-
));
|
|
69
|
-
|
|
70
|
-
const invalidMetadata = agentNativeRegistry.operations
|
|
71
|
-
.filter((operation) => typeof operation.read_only !== "boolean"
|
|
72
|
-
|| (operation.read_only === true && operation.effect_class !== "NONE"))
|
|
73
|
-
.map((operation) => ({ effect_class: operation.effect_class, name: operation.name, read_only: operation.read_only }));
|
|
74
|
-
const registryReads = agentNativeRegistry.operations.filter((operation) => operation.read_only === true).map((operation) => operation.name).sort();
|
|
75
|
-
results.push(result(
|
|
76
|
-
"registry_read_only_metadata_is_closed",
|
|
77
|
-
"every operation declares read_only and no effectful operation is read-only",
|
|
78
|
-
{ invalidMetadata, registryReads },
|
|
79
|
-
invalidMetadata.length === 0 && registryReads.length > 0,
|
|
80
|
-
));
|
|
81
|
-
|
|
82
|
-
for (const name of MUTATIONS.filter((item) => names.includes(item))) {
|
|
83
|
-
const invoked = agentNativeRegistry.invoke(name, {});
|
|
84
|
-
const codes = (invoked.failures ?? []).map((failure) => failure.code);
|
|
85
|
-
results.push(result(
|
|
86
|
-
`registered_handler_${name}`,
|
|
87
|
-
"the registered mutation reaches its schema or handler instead of operation_unknown",
|
|
88
|
-
invoked,
|
|
89
|
-
invoked.operation === name && !codes.includes("operation_unknown"),
|
|
90
|
-
));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const connection = await connected();
|
|
94
|
-
try {
|
|
95
|
-
const tools = (await connection.client.listTools()).tools.map((tool) => tool.name).sort();
|
|
96
|
-
results.push(result(
|
|
97
|
-
"mcp_tools_derive_from_registry_read_only",
|
|
98
|
-
registryReads,
|
|
99
|
-
tools,
|
|
100
|
-
equal(tools, registryReads),
|
|
101
|
-
));
|
|
102
|
-
|
|
103
|
-
const mutationCalls = [];
|
|
104
|
-
for (const name of MUTATIONS) {
|
|
105
|
-
const observed = await rejected(() => connection.client.callTool({ name, arguments: {} }));
|
|
106
|
-
const body = envelope(observed.response);
|
|
107
|
-
mutationCalls.push({ error: observed.error, isError: observed.response?.isError, name, body });
|
|
108
|
-
}
|
|
109
|
-
results.push(result(
|
|
110
|
-
"existing_mutations_are_not_mcp_tools",
|
|
111
|
-
"every mutation that exists in the registry is absent from MCP and denied on direct call",
|
|
112
|
-
mutationCalls,
|
|
113
|
-
mutationCalls.every((call) => !tools.includes(call.name)
|
|
114
|
-
&& (call.error !== null || (call.isError === true && call.body?.failures?.[0]?.code === "operation_not_exposed"))),
|
|
115
|
-
));
|
|
116
|
-
|
|
117
|
-
const templates = (await connection.client.listResourceTemplates()).resourceTemplates ?? [];
|
|
118
|
-
const template = templates.find((item) => item.uriTemplate === "sg://object/{reference}");
|
|
119
|
-
results.push(result(
|
|
120
|
-
"object_resource_template_is_discoverable",
|
|
121
|
-
"sg://object/{reference} is advertised",
|
|
122
|
-
templates,
|
|
123
|
-
Boolean(template),
|
|
124
|
-
));
|
|
125
|
-
|
|
126
|
-
const objectUri = `sg://object/${encodeURIComponent(PROFILE_REF)}`;
|
|
127
|
-
const resources = (await connection.client.listResources()).resources ?? [];
|
|
128
|
-
const listed = resources.some((resource) => resource.uri === objectUri);
|
|
129
|
-
const resource = await rejected(() => connection.client.readResource({ uri: objectUri }));
|
|
130
|
-
const text = resource.response?.contents?.find((item) => item.uri === objectUri)?.text;
|
|
131
|
-
let parsed = null;
|
|
132
|
-
try { parsed = JSON.parse(text); } catch { /* asserted below */ }
|
|
133
|
-
const resolved = agentNativeRegistry.invoke("resolve", { reference: PROFILE_REF });
|
|
134
|
-
results.push(result(
|
|
135
|
-
"object_resource_uses_registry_resolver",
|
|
136
|
-
"the listed encoded object URI returns the exact registry resolve payload",
|
|
137
|
-
{ error: resource.error, listed, parsed, resolved },
|
|
138
|
-
listed && resource.error === null && resolved.ok === true && equal(parsed, resolved.result),
|
|
139
|
-
));
|
|
140
|
-
|
|
141
|
-
const unknown = await rejected(() => connection.client.readResource({
|
|
142
|
-
uri: `sg://object/${encodeURIComponent("sg:profile/does-not-exist")}`,
|
|
143
|
-
}));
|
|
144
|
-
const malformed = await rejected(() => connection.client.readResource({ uri: "sg://object/%E0%A4%A" }));
|
|
145
|
-
const versionId = resolved.ok ? resolved.result.version_id : "";
|
|
146
|
-
const versioned = await rejected(() => connection.client.readResource({
|
|
147
|
-
uri: `sg://object/${encodeURIComponent(versionId)}`,
|
|
148
|
-
}));
|
|
149
|
-
results.push(result(
|
|
150
|
-
"object_resource_accepts_only_encoded_stable_refs",
|
|
151
|
-
"unknown, malformed, and VersionID object references are rejected",
|
|
152
|
-
{ malformed, unknown, versioned },
|
|
153
|
-
unknown.error !== null && malformed.error !== null && versioned.error !== null,
|
|
154
|
-
));
|
|
155
|
-
} finally {
|
|
156
|
-
await close(connection);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const dynamicName = "diagnostics.snapshot";
|
|
160
|
-
const dynamicOperation = Object.freeze({
|
|
161
|
-
adapters: [], description: "Dynamically registered read projection.", effect_class: "NONE",
|
|
162
|
-
idempotent: true, input_schema: { additionalProperties: false, type: "object" },
|
|
163
|
-
name: dynamicName, output_schema: { type: "object" }, read_only: true,
|
|
164
|
-
record_kind: "operation", stable_ref: "sg:operation/diagnostics-snapshot",
|
|
165
|
-
});
|
|
166
|
-
const dynamicRegistry = Object.freeze({
|
|
167
|
-
...agentNativeRegistry,
|
|
168
|
-
invoke: (name, input = {}) => name === dynamicName
|
|
169
|
-
? Object.freeze({ ok: true, operation: name, result: Object.freeze({ input, source: "dynamic-registry" }) })
|
|
170
|
-
: agentNativeRegistry.invoke(name, input),
|
|
171
|
-
operations: Object.freeze([...agentNativeRegistry.operations, dynamicOperation]),
|
|
172
|
-
});
|
|
173
|
-
const dynamic = await connected(dynamicRegistry);
|
|
174
|
-
try {
|
|
175
|
-
const namesFromMcp = (await dynamic.client.listTools()).tools.map((tool) => tool.name);
|
|
176
|
-
const called = await dynamic.client.callTool({ name: dynamicName, arguments: {} });
|
|
177
|
-
results.push(result(
|
|
178
|
-
"new_read_operation_needs_no_adapter_allowlist_change",
|
|
179
|
-
"a new read_only registry operation is automatically listed and callable",
|
|
180
|
-
{ called: envelope(called), namesFromMcp },
|
|
181
|
-
namesFromMcp.includes(dynamicName) && envelope(called)?.ok === true,
|
|
182
|
-
));
|
|
183
|
-
} finally {
|
|
184
|
-
await close(dynamic);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const contradictoryRegistry = {
|
|
188
|
-
...agentNativeRegistry,
|
|
189
|
-
operations: [...agentNativeRegistry.operations, {
|
|
190
|
-
...dynamicOperation,
|
|
191
|
-
effect_class: "EXTERNAL",
|
|
192
|
-
name: "diagnostics.unsafe",
|
|
193
|
-
stable_ref: "sg:operation/diagnostics-unsafe",
|
|
194
|
-
}],
|
|
195
|
-
};
|
|
196
|
-
let contradiction;
|
|
197
|
-
try { createStyleGalleryMcpServer({ registry: contradictoryRegistry }); } catch (error) {
|
|
198
|
-
contradiction = error instanceof Error ? error.message : String(error);
|
|
199
|
-
}
|
|
200
|
-
results.push(result(
|
|
201
|
-
"contradictory_read_only_effect_metadata_is_rejected",
|
|
202
|
-
"read_only:true cannot disguise an EXTERNAL operation",
|
|
203
|
-
{ contradiction },
|
|
204
|
-
typeof contradiction === "string" && contradiction.includes("cannot expose EXTERNAL effects as read-only"),
|
|
205
|
-
));
|
|
206
|
-
|
|
207
|
-
const report = { ok: results.every((item) => item.ok), results };
|
|
208
|
-
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
209
|
-
process.exitCode = report.ok ? 0 : 1;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
await main().catch((error) => {
|
|
213
|
-
process.stdout.write(`${JSON.stringify({ ok: false, results: [result("registry_mcp_integrity_runtime", "structured report", error instanceof Error ? error.message : String(error), false)] }, null, 2)}\n`);
|
|
214
|
-
process.exitCode = 1;
|
|
215
|
-
});
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { agentNativeRegistry as registry } from "./agent-native/registry.mjs";
|
|
4
|
-
|
|
5
|
-
function result(name, expected, actual, ok) {
|
|
6
|
-
return { actual, expected, name, ok };
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function invoke(name, input) {
|
|
10
|
-
const response = registry.invoke(name, input);
|
|
11
|
-
return { name, response };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const claim = registry.fixture.records.find((record) => record.stable_ref === "sg:claim/editorial-profile-addressable");
|
|
15
|
-
const proposal = invoke("proposal.create", {
|
|
16
|
-
changes: [{ op: "replace", path: "/rank", value: 1 }],
|
|
17
|
-
claim,
|
|
18
|
-
evidence: [{
|
|
19
|
-
independence_group: "registry-proposal-source",
|
|
20
|
-
polarity: "SUPPORT",
|
|
21
|
-
source_ref: "sg:artifact/editorial-profile-source",
|
|
22
|
-
stable_ref: "sg:evidence/registry-proposal-source",
|
|
23
|
-
}],
|
|
24
|
-
proposer: "agent:registry-proposer",
|
|
25
|
-
stable_ref: "sg:proposal/registry-invocation-fixture",
|
|
26
|
-
validation: { status: "PASS", validator: "validator:proposal", validator_version: "1" },
|
|
27
|
-
});
|
|
28
|
-
const verification = invoke("proposal.verify", {
|
|
29
|
-
evidence: [{
|
|
30
|
-
independence_group: "registry-independent-source",
|
|
31
|
-
polarity: "SUPPORT",
|
|
32
|
-
source_ref: "sg:artifact/editorial-profile-source",
|
|
33
|
-
stable_ref: "sg:evidence/registry-independent-source",
|
|
34
|
-
}],
|
|
35
|
-
proposal: proposal.response.result,
|
|
36
|
-
validation: { status: "PASS", validator: "validator:independent", validator_version: "1" },
|
|
37
|
-
verifier: "agent:registry-verifier",
|
|
38
|
-
});
|
|
39
|
-
const decision = invoke("proposal.decide", {
|
|
40
|
-
governance_decision: {
|
|
41
|
-
actor: "governor:stylegallery",
|
|
42
|
-
decided_at: "2026-07-23T00:00:00.000Z",
|
|
43
|
-
decision: "ACCEPT",
|
|
44
|
-
},
|
|
45
|
-
proposal: proposal.response.result,
|
|
46
|
-
verification: verification.response.result,
|
|
47
|
-
});
|
|
48
|
-
const promotion = invoke("proposal.promote", {
|
|
49
|
-
governance_decision: decision.response.result,
|
|
50
|
-
proposal: proposal.response.result,
|
|
51
|
-
target_stable_ref: "sg:profile/editorial-reference-profile",
|
|
52
|
-
verification: verification.response.result,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const task = invoke("task.create", {
|
|
56
|
-
intent: { operation: "resolve" },
|
|
57
|
-
required_result: { ok: true },
|
|
58
|
-
stable_ref: "sg:task/registry-invocation-fixture",
|
|
59
|
-
});
|
|
60
|
-
const run = invoke("run.start", {
|
|
61
|
-
input: { reference: "sg:profile/editorial-reference-profile" },
|
|
62
|
-
stable_ref: "sg:run/registry-invocation-fixture",
|
|
63
|
-
task: task.response.result,
|
|
64
|
-
});
|
|
65
|
-
const effect = invoke("effect.record", {
|
|
66
|
-
effect_class: "EXTERNAL",
|
|
67
|
-
run_id: run.response.result?.run_id,
|
|
68
|
-
stable_ref: "sg:effect/registry-invocation-fixture",
|
|
69
|
-
task_id: task.response.result?.task_id,
|
|
70
|
-
});
|
|
71
|
-
const reconciliation = invoke("effect.reconcile", {
|
|
72
|
-
effect: effect.response.result,
|
|
73
|
-
observations: [{ connector_receipt: "sg:receipt/connector-fixture", status: "COMMITTED" }],
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const mutations = [proposal, verification, decision, promotion, task, run, effect, reconciliation];
|
|
77
|
-
const results = [
|
|
78
|
-
result(
|
|
79
|
-
"governed_learning_chain_is_invokable_from_common_registry",
|
|
80
|
-
"PROPOSED -> VERIFIED -> ACCEPT -> PROMOTED",
|
|
81
|
-
mutations.slice(0, 4).map(({ name, response }) => ({ name, ok: response.ok, status: response.result?.status })),
|
|
82
|
-
proposal.response.ok && verification.response.ok && decision.response.ok && promotion.response.ok
|
|
83
|
-
&& proposal.response.result.status === "PROPOSED"
|
|
84
|
-
&& verification.response.result.status === "VERIFIED"
|
|
85
|
-
&& decision.response.result.status === "ACCEPT"
|
|
86
|
-
&& promotion.response.result.status === "PROMOTED",
|
|
87
|
-
),
|
|
88
|
-
result(
|
|
89
|
-
"task_run_effect_reconciliation_is_invokable_from_common_registry",
|
|
90
|
-
"SUBMITTED -> RUNNING -> UNCERTAIN -> COMMITTED",
|
|
91
|
-
mutations.slice(4).map(({ name, response }) => ({ name, ok: response.ok, state: response.result?.state })),
|
|
92
|
-
task.response.ok && run.response.ok && effect.response.ok && reconciliation.response.ok
|
|
93
|
-
&& task.response.result.state === "SUBMITTED"
|
|
94
|
-
&& run.response.result.state === "RUNNING"
|
|
95
|
-
&& effect.response.result.state === "UNCERTAIN"
|
|
96
|
-
&& reconciliation.response.result.state === "COMMITTED",
|
|
97
|
-
),
|
|
98
|
-
result(
|
|
99
|
-
"invokable_mutations_remain_internal",
|
|
100
|
-
"all eight invoked operations declare read_only:false and omit MCP adapter exposure",
|
|
101
|
-
registry.operations.filter((operation) => mutations.some((item) => item.name === operation.name))
|
|
102
|
-
.map((operation) => ({ adapters: operation.adapters, name: operation.name, read_only: operation.read_only })),
|
|
103
|
-
registry.operations.filter((operation) => mutations.some((item) => item.name === operation.name))
|
|
104
|
-
.every((operation) => operation.read_only === false && !operation.adapters.includes("mcp")),
|
|
105
|
-
),
|
|
106
|
-
];
|
|
107
|
-
|
|
108
|
-
const report = { ok: results.every((item) => item.ok), results };
|
|
109
|
-
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
110
|
-
process.exitCode = report.ok ? 0 : 1;
|