@ggui-ai/protocol-conformance 0.15.0 → 0.16.0
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/README.md +23 -15
- package/dist/cli.d.ts +6 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/domain-error-conformance/cases/amend-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/consume-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/emit-unknown-session.json +9 -0
- package/dist/domain-error-conformance/cases/get-session-unknown-session.json +6 -0
- package/dist/domain-error-conformance/cases/render-unknown-handshake.json +6 -0
- package/dist/domain-error-conformance/cases/update-unknown-session.json +9 -0
- package/dist/domain-error-conformance/index.d.ts +97 -0
- package/dist/domain-error-conformance/index.d.ts.map +1 -0
- package/dist/domain-error-conformance/index.js +97 -0
- package/dist/fixtures/index.d.ts +2 -2
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +3 -3
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/absent-appid-defaults.json +1 -1
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/app-mismatch.json +1 -1
- package/dist/fixtures/subscribe-app-scope/index.d.ts +6 -0
- package/dist/fixtures/subscribe-app-scope/index.d.ts.map +1 -0
- package/dist/fixtures/{subscribe-tenancy → subscribe-app-scope}/index.js +5 -5
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/refusal-envelope-conformance/cases/refuse-after-fix-caller.json +3 -3
- package/dist/refusal-envelope-conformance/cases/refuse-non-render-surface.json +4 -4
- package/dist/run-conformance.d.ts +13 -3
- package/dist/run-conformance.d.ts.map +1 -1
- package/dist/run-conformance.js +61 -7
- package/dist/theme-binding-conformance/cases/app-theme-v1-base.json +18 -0
- package/dist/theme-binding-conformance/cases/app-theme-v1-one-palette.json +11 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-accepted.json +18 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-accepted.json +16 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-keyframes-not-keyframes.json +15 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-label-too-long.json +17 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-missing-dark.json +13 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-no-hash.json +15 -0
- package/dist/theme-binding-conformance/cases/app-theme-v2-platform-pin.json +17 -0
- package/dist/theme-binding-conformance/cases/overlay-hash-canonical.json +17 -0
- package/dist/theme-binding-conformance/cases/theme-mode-absence.json +10 -0
- package/dist/theme-binding-conformance/cases/theme-mode-default-when-silent-host.json +10 -0
- package/dist/theme-binding-conformance/cases/theme-mode-order.json +10 -0
- package/dist/theme-binding-conformance/index.d.ts +59 -0
- package/dist/theme-binding-conformance/index.d.ts.map +1 -0
- package/dist/theme-binding-conformance/index.js +110 -0
- package/dist/transport-refusal-conformance/cases/refuse-deprovisioned-endpoint.json +7 -5
- package/dist/transport-refusal-conformance/cases/refuse-render-only-code.json +3 -2
- package/dist/transport-refusal-conformance/index.d.ts +2 -0
- package/dist/transport-refusal-conformance/index.d.ts.map +1 -1
- package/dist/transport-refusal-conformance/index.js +2 -2
- package/dist/types.d.ts +1 -1
- package/package.json +12 -2
- package/dist/fixtures/subscribe-tenancy/index.d.ts +0 -6
- package/dist/fixtures/subscribe-tenancy/index.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `subscribe-
|
|
2
|
+
* `subscribe-app-scope` fixture sub-module.
|
|
3
3
|
*
|
|
4
|
-
* Exercises the subscribe-time
|
|
4
|
+
* Exercises the subscribe-time app-scope contract (SPEC §12.2 subscribe
|
|
5
5
|
* payload table + §12.2.3 channel-3 error codes):
|
|
6
6
|
*
|
|
7
7
|
* - `app-mismatch` — the GguiSession exists but is bound to a
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* mapping, else the deployment default) and the subscribe acks.
|
|
19
19
|
* Graded as a session-state read-back of the bound `appId` on the
|
|
20
20
|
* provisioned render (hosts expose it via `readSessionField`), so
|
|
21
|
-
* a server that acks but binds an undefined
|
|
21
|
+
* a server that acks but binds an undefined app id — the
|
|
22
22
|
* corrupt-row failure mode — fails rather than passing on the ack
|
|
23
23
|
* alone.
|
|
24
24
|
*
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
*/
|
|
54
54
|
import absentAppidDefaults from './absent-appid-defaults.json' with { type: 'json' };
|
|
55
55
|
import appMismatch from './app-mismatch.json' with { type: 'json' };
|
|
56
|
-
/** All fixtures asserting subscribe-time
|
|
56
|
+
/** All fixtures asserting subscribe-time app scope (SPEC §12.2 field
|
|
57
57
|
* table — identity-default resolution on absent `appId` — and
|
|
58
58
|
* §12.2.3 `APP_MISMATCH`). */
|
|
59
|
-
export const
|
|
59
|
+
export const subscribeAppScopeFixtures = [
|
|
60
60
|
absentAppidDefaults,
|
|
61
61
|
appMismatch,
|
|
62
62
|
];
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export type { TransportConfig, WebSocketTransportConfig, UnknownTransportConfig, AuthConfig, TestCase, SubscribeFrameShaping, SetupStep, CreateGguiSessionStep, ActionSpecEntryDecl, JsonSchemaDecl, RendererUrlOverrideStep, ServerVersionOverrideStep, UiInitializeResponseOverrideStep, EmitEnvelopeStep, TeardownStep, ExpectedBehavior, ActionAckBehavior, ErrorFrameBehavior, StreamUpdateBehavior, BootstrapFailureBehavior, BootstrapSuccessBehavior, VersionMismatchBehavior, PropsUpdateBehavior, SessionStateBehavior, NoOpBehavior, UnknownBehavior, ProtocolError, BootstrapFailureReason, } from './types.js';
|
|
14
14
|
export type { ConformanceHost, SetupStep as HostSetupStep, CreateGguiSessionSetup, RendererUrlOverrideSetup, ServerVersionOverrideSetup, UiInitializeResponseOverrideSetup, EmitEnvelopeSetup, TeardownStep as HostTeardownStep, } from './conformance-host.js';
|
|
15
|
-
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, consumeBufferFixtures, hostContextFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures,
|
|
15
|
+
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, consumeBufferFixtures, hostContextFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures, subscribeAppScopeFixtures, } from './fixtures/index.js';
|
|
16
16
|
export type { ContractSlug } from './fixtures/index.js';
|
|
17
17
|
export { gadgetWireSchemaCases, runSchemaConformance, } from './schema-conformance/index.js';
|
|
18
18
|
export type { SchemaConformanceCase, SchemaConformanceMismatch, SchemaConformanceResult, } from './schema-conformance/index.js';
|
|
@@ -37,4 +37,8 @@ export { runConformance } from './run-conformance.js';
|
|
|
37
37
|
export type { RunConformanceConfig, ConformanceResult, ConformanceFailure, SkippedFixture, ConformanceReporter, InputEnvelopeDispatch, HostContextObservedInputEnvelope, } from './run-conformance.js';
|
|
38
38
|
export { createDefaultReporter, formatScorecard, formatSummary, formatFailures, formatSkips, } from './reporter.js';
|
|
39
39
|
export type { DefaultReporterOptions } from './reporter.js';
|
|
40
|
+
export { domainErrorCases, isRawToolCallResult, runDomainErrorConformance, } from './domain-error-conformance/index.js';
|
|
41
|
+
export type { DomainErrorConformanceCase, DomainErrorConformanceResult, DomainErrorCriterion, DomainErrorMismatch, DomainErrorSkip, RawToolCallResult, RunDomainErrorConformanceOptions, ToolCallArgs, ToolCallContent, ToolCallDriver, ToolCallScenario, } from './domain-error-conformance/index.js';
|
|
42
|
+
export { APP_THEME_CASES, OVERLAY_HASH_CASES, THEME_MODE_CASES, runThemeBindingConformance, } from './theme-binding-conformance/index.js';
|
|
43
|
+
export type { AppThemeCase, OverlayHashCase, ThemeBindingResult, ThemeModeCase, } from './theme-binding-conformance/index.js';
|
|
40
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,YAAY,EAEV,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,UAAU,EAEV,QAAQ,EACR,qBAAqB,EAErB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,EAChC,gBAAgB,EAEhB,YAAY,EAEZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EAEf,aAAa,EACb,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAMpB,YAAY,EACV,eAAe,EAEf,SAAS,IAAI,aAAa,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,iBAAiB,EAEjB,YAAY,IAAI,gBAAgB,GACjC,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,gCAAgC,EAChC,8BAA8B,EAC9B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// Fixture catalog — every authored conformance case, classified by
|
|
14
14
|
// contract. Third-party runners + the kit's own `runConformance()`
|
|
15
15
|
// consume this surface.
|
|
16
|
-
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, consumeBufferFixtures, hostContextFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures,
|
|
16
|
+
export { allFixtures, fixturesByContract, bootstrapProtocolFixtures, consumeBufferFixtures, hostContextFixtures, reservedChannelAuthorityFixtures, schemaVersionHandshakeFixtures, subscribeAppScopeFixtures, } from './fixtures/index.js';
|
|
17
17
|
// Pure-function conformance catalogs — SPEC §7.7.2's gadget
|
|
18
18
|
// obligations are deterministic validation functions, not transport-
|
|
19
19
|
// observable behaviors. Each catalog grades a caller-supplied function
|
|
@@ -73,3 +73,7 @@ export { runConformance } from './run-conformance.js';
|
|
|
73
73
|
// formatters programmatic consumers can reuse when building their
|
|
74
74
|
// own reporter (CI annotations, vitest integration, etc.).
|
|
75
75
|
export { createDefaultReporter, formatScorecard, formatSummary, formatFailures, formatSkips, } from './reporter.js';
|
|
76
|
+
// ── domain-error (SPEC §7.9 Plane 2 on the tools/call wire, ggui#880) ──
|
|
77
|
+
export { domainErrorCases, isRawToolCallResult, runDomainErrorConformance, } from './domain-error-conformance/index.js';
|
|
78
|
+
// ── theme binding (ggui#987 — the theming wave's arbiter; guuey 1.3 judges against it) ──
|
|
79
|
+
export { APP_THEME_CASES, OVERLAY_HASH_CASES, THEME_MODE_CASES, runThemeBindingConformance, } from './theme-binding-conformance/index.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "refuse-after-fix-caller",
|
|
3
3
|
"description": "An after-fix refusal the CALLER can act on itself: the projector emits an isError result whose text leads with the code, carries outcome 'refused' plus the refusal and nothing else, and exposes no _meta. This is the only fixBy class an agent may retry on its own.",
|
|
4
4
|
"refusal": {
|
|
5
|
-
"code": "
|
|
5
|
+
"code": "model_not_allowed",
|
|
6
6
|
"message": "the requested model is not among those this app may use",
|
|
7
7
|
"fix": "pick a model the app is allowed to use and call again with the same handshakeId",
|
|
8
8
|
"retry": "after-fix",
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
},
|
|
11
11
|
"expect": {
|
|
12
12
|
"isError": true,
|
|
13
|
-
"text": "
|
|
13
|
+
"text": "model_not_allowed: the requested model is not among those this app may use pick a model the app is allowed to use and call again with the same handshakeId",
|
|
14
14
|
"structuredContent": {
|
|
15
15
|
"outcome": "refused",
|
|
16
16
|
"refusal": {
|
|
17
|
-
"code": "
|
|
17
|
+
"code": "model_not_allowed",
|
|
18
18
|
"message": "the requested model is not among those this app may use",
|
|
19
19
|
"fix": "pick a model the app is allowed to use and call again with the same handshakeId",
|
|
20
20
|
"retry": "after-fix",
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"name": "refuse-non-render-surface",
|
|
3
3
|
"description": "A REGISTERED code whose surfaces exclude the render gate. It has no render envelope at all, so a conformant projector produces nothing for it. Projecting it anyway is the drift the per-surface namespace rule forbids \u2014 this case is what makes that rule observable rather than prose.",
|
|
4
4
|
"refusal": {
|
|
5
|
-
"code": "
|
|
6
|
-
"message": "
|
|
7
|
-
"fix": "
|
|
8
|
-
"retry": "
|
|
5
|
+
"code": "checkout_unavailable",
|
|
6
|
+
"message": "Top-ups are unavailable right now.",
|
|
7
|
+
"fix": "Try again in a few minutes; if it persists, write to hello@ggui.ai.",
|
|
8
|
+
"retry": "later",
|
|
9
9
|
"handshake": "intact"
|
|
10
10
|
},
|
|
11
11
|
"expect": null
|
|
@@ -5,6 +5,7 @@ import type { AuthConfig, SessionStateBehavior, StreamUpdateBehavior, VersionMis
|
|
|
5
5
|
import { type PreGenerationRefusalInput, type ProjectedRefusalResult } from './refusal-envelope-conformance/index.js';
|
|
6
6
|
import { type RefusalRegistryView } from './registry-completeness/index.js';
|
|
7
7
|
import { type ProjectedTransportRefusal, type TransportRefusalInput } from './transport-refusal-conformance/index.js';
|
|
8
|
+
import { type ToolCallDriver } from './domain-error-conformance/index.js';
|
|
8
9
|
export interface RunConformanceConfig {
|
|
9
10
|
/**
|
|
10
11
|
* URL of the implementation under test. `http://` / `https://`
|
|
@@ -56,14 +57,23 @@ export interface RunConformanceConfig {
|
|
|
56
57
|
* `transport-refusal` catalog is graded; omitted ⇒ SKIPPED, named.
|
|
57
58
|
*/
|
|
58
59
|
readonly transportRefusalProjector?: (refusal: TransportRefusalInput) => ProjectedTransportRefusal | null;
|
|
60
|
+
/**
|
|
61
|
+
* Performs one `tools/call` against the deployment and returns the raw
|
|
62
|
+
* result (or `null` when the tool is not bound). Supplied ⇒ the
|
|
63
|
+
* `domain-error` catalog (SPEC §7.9 Plane 2 on the wire, ggui#880) is
|
|
64
|
+
* graded; omitted ⇒ SKIPPED, named.
|
|
65
|
+
*/
|
|
66
|
+
readonly toolCallDriver?: ToolCallDriver;
|
|
59
67
|
}
|
|
60
68
|
/**
|
|
61
|
-
* Row-name prefixes for the
|
|
62
|
-
*
|
|
69
|
+
* Row-name prefixes for the catalogs the runner folds into a run beside
|
|
70
|
+
* the WebSocket fixtures: three grade an in-process function or a data
|
|
71
|
+
* table; `domain-error` (ggui#880) drives live `tools/call` scenarios
|
|
72
|
+
* through an adopter-supplied driver. Prefixed so a catalog row can never collide with a
|
|
63
73
|
* WebSocket fixture name, and so the reporter can group them without a
|
|
64
74
|
* second registry of names.
|
|
65
75
|
*/
|
|
66
|
-
export declare const PURE_FUNCTION_CATALOG_SLUGS: readonly ["refusal-envelope", "registry-completeness", "transport-refusal"];
|
|
76
|
+
export declare const PURE_FUNCTION_CATALOG_SLUGS: readonly ["refusal-envelope", "registry-completeness", "transport-refusal", "domain-error", "theme-binding"];
|
|
67
77
|
/** One member of {@link PURE_FUNCTION_CATALOG_SLUGS}. */
|
|
68
78
|
export type PureFunctionCatalogSlug = (typeof PURE_FUNCTION_CATALOG_SLUGS)[number];
|
|
69
79
|
export interface ConformanceResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-conformance.d.ts","sourceRoot":"","sources":["../src/run-conformance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-conformance.d.ts","sourceRoot":"","sources":["../src/run-conformance.ts"],"names":[],"mappings":"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"}
|
package/dist/run-conformance.js
CHANGED
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
* loop is empty today.)
|
|
48
48
|
* l. Record the outcome via reporter + accumulate in result.
|
|
49
49
|
* 3. Fold in the PURE-FUNCTION catalogs (ggui#786) —
|
|
50
|
-
* `refusal-envelope`, `registry-completeness
|
|
50
|
+
* `refusal-envelope`, `registry-completeness`, `transport-refusal`,
|
|
51
|
+
* `domain-error` and `theme-binding` (ggui#987). They grade a
|
|
51
52
|
* caller-supplied projector / registry rather than the wire, so
|
|
52
53
|
* they need no transport; when the caller supplies neither, their
|
|
53
54
|
* rows are reported SKIPPED with that reason so an ungraded
|
|
@@ -66,9 +67,13 @@ import { openWsTransport } from './ws-transport.js';
|
|
|
66
67
|
import { refusalEnvelopeCases, runRefusalEnvelopeConformance, } from './refusal-envelope-conformance/index.js';
|
|
67
68
|
import { registryCompletenessPins, runRegistryCompletenessConformance, } from './registry-completeness/index.js';
|
|
68
69
|
import { runTransportRefusalConformance, transportRefusalCases, } from './transport-refusal-conformance/index.js';
|
|
70
|
+
import { runThemeBindingConformance } from './theme-binding-conformance/index.js';
|
|
71
|
+
import { domainErrorCases, runDomainErrorConformance, } from './domain-error-conformance/index.js';
|
|
69
72
|
/**
|
|
70
|
-
* Row-name prefixes for the
|
|
71
|
-
*
|
|
73
|
+
* Row-name prefixes for the catalogs the runner folds into a run beside
|
|
74
|
+
* the WebSocket fixtures: three grade an in-process function or a data
|
|
75
|
+
* table; `domain-error` (ggui#880) drives live `tools/call` scenarios
|
|
76
|
+
* through an adopter-supplied driver. Prefixed so a catalog row can never collide with a
|
|
72
77
|
* WebSocket fixture name, and so the reporter can group them without a
|
|
73
78
|
* second registry of names.
|
|
74
79
|
*/
|
|
@@ -76,6 +81,8 @@ export const PURE_FUNCTION_CATALOG_SLUGS = [
|
|
|
76
81
|
'refusal-envelope',
|
|
77
82
|
'registry-completeness',
|
|
78
83
|
'transport-refusal',
|
|
84
|
+
'domain-error',
|
|
85
|
+
'theme-binding',
|
|
79
86
|
];
|
|
80
87
|
// =============================================================================
|
|
81
88
|
// Runner
|
|
@@ -113,7 +120,7 @@ export async function runConformance(config) {
|
|
|
113
120
|
break;
|
|
114
121
|
}
|
|
115
122
|
}
|
|
116
|
-
runPureFunctionCatalogs(config, reporter, { passed, failed, skipped });
|
|
123
|
+
await runPureFunctionCatalogs(config, reporter, { passed, failed, skipped });
|
|
117
124
|
const result = {
|
|
118
125
|
passed,
|
|
119
126
|
failed,
|
|
@@ -138,7 +145,7 @@ export async function runConformance(config) {
|
|
|
138
145
|
* absent input produces a SKIP row naming what to supply rather than
|
|
139
146
|
* nothing at all.
|
|
140
147
|
*/
|
|
141
|
-
function runPureFunctionCatalogs(config, reporter, buckets) {
|
|
148
|
+
async function runPureFunctionCatalogs(config, reporter, buckets) {
|
|
142
149
|
const only = config.only;
|
|
143
150
|
const wanted = (name) => only === undefined || only.length === 0 || only.includes(name);
|
|
144
151
|
const pass = (name) => {
|
|
@@ -201,6 +208,33 @@ function runPureFunctionCatalogs(config, reporter, buckets) {
|
|
|
201
208
|
});
|
|
202
209
|
}
|
|
203
210
|
}
|
|
211
|
+
// ── domain-error (ggui#880) ──
|
|
212
|
+
const toolCallDriver = config.toolCallDriver;
|
|
213
|
+
if (toolCallDriver === undefined) {
|
|
214
|
+
for (const testCase of domainErrorCases) {
|
|
215
|
+
skip(`domain-error/${testCase.name}`, 'no `toolCallDriver` supplied — pass one to runConformance(), or `--tool-call-driver <module>` on the CLI, to grade SPEC §7.9\u2019s Plane-2 wire text');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// A live driver is real calls: drive only the rows `only` selects.
|
|
220
|
+
const selected = domainErrorCases.filter((testCase) => wanted(`domain-error/${testCase.name}`));
|
|
221
|
+
const graded = selected.length === 0
|
|
222
|
+
? { passed: [], failed: [], skipped: [] }
|
|
223
|
+
: await runDomainErrorConformance(toolCallDriver, { cases: selected });
|
|
224
|
+
for (const name of graded.passed)
|
|
225
|
+
pass(`domain-error/${name}`);
|
|
226
|
+
for (const skipped of graded.skipped)
|
|
227
|
+
skip(`domain-error/${skipped.name}`, skipped.reason);
|
|
228
|
+
for (const mismatch of graded.failed) {
|
|
229
|
+
fail({
|
|
230
|
+
name: `domain-error/${mismatch.name}`,
|
|
231
|
+
criterion: `Plane-2 wire text (SPEC §7.9): ${mismatch.criterion}`,
|
|
232
|
+
expected: mismatch.expected,
|
|
233
|
+
received: mismatch.actual,
|
|
234
|
+
message: 'the raw tools/call result does not carry the registered slug as the leading token of its text',
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
204
238
|
// ── registry-completeness ──
|
|
205
239
|
const registry = config.refusalRegistry;
|
|
206
240
|
if (registry === undefined) {
|
|
@@ -222,6 +256,26 @@ function runPureFunctionCatalogs(config, reporter, buckets) {
|
|
|
222
256
|
});
|
|
223
257
|
}
|
|
224
258
|
}
|
|
259
|
+
// ── theme-binding (ggui#987) ──
|
|
260
|
+
// The theming wave's arbiter: graded against the protocol's own functions
|
|
261
|
+
// (`appThemeSchema`, `effectiveThemeMode`, `canonicalOverlayHash`), so
|
|
262
|
+
// there is no adopter input to supply and no reason to skip — every run
|
|
263
|
+
// reports it. `only` still selects rows.
|
|
264
|
+
for (const graded of await runThemeBindingConformance()) {
|
|
265
|
+
const name = `theme-binding/${graded.name}`;
|
|
266
|
+
if (graded.pass) {
|
|
267
|
+
pass(name);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
fail({
|
|
271
|
+
name,
|
|
272
|
+
criterion: 'theme binding (SPEC "Theme binding — the normative total order", ggui#987)',
|
|
273
|
+
expected: 'the case\u2019s expectation',
|
|
274
|
+
received: graded.detail,
|
|
275
|
+
message: graded.detail,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
225
279
|
}
|
|
226
280
|
async function runOneFixture(fixture, config, _reporter) {
|
|
227
281
|
const fixtureStarted = Date.now();
|
|
@@ -684,8 +738,8 @@ function slugToCriterion(slug) {
|
|
|
684
738
|
return 'SPEC §4.4 reserved-channel authority';
|
|
685
739
|
case 'schema-version-handshake':
|
|
686
740
|
return 'Protocol #3 version negotiation';
|
|
687
|
-
case 'subscribe-
|
|
688
|
-
return 'SPEC §12.2 subscribe
|
|
741
|
+
case 'subscribe-app-scope':
|
|
742
|
+
return 'SPEC §12.2 subscribe app scope — appId MUST match the bound app (§12.2.3 APP_MISMATCH)';
|
|
689
743
|
default:
|
|
690
744
|
return slug;
|
|
691
745
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v1-base",
|
|
3
|
+
"description": "A v1 overlay carrying a registered `base` ladder is REFUSED since ggui#987 (D2 = B): the registration tier and `base` are gone. Accepted before #987 (promoted, then failed \u2014 the \u00a71.1 receipt).",
|
|
4
|
+
"theme": {
|
|
5
|
+
"mode": "dark",
|
|
6
|
+
"cssVariables": {},
|
|
7
|
+
"base": {
|
|
8
|
+
"documentHash": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
9
|
+
"light": {
|
|
10
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
11
|
+
},
|
|
12
|
+
"dark": {
|
|
13
|
+
"--ggui-color-primary-500": "#99aaff"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"expect": "refused"
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v1-one-palette",
|
|
3
|
+
"description": "The v1 overlay wire \u2014 a pinned mode and ONE cssVariables palette \u2014 is REFUSED since ggui#987: an overlay that could not follow the host's mode is not accepted; both projections are required. Accepted before #987 (promoted, then failed \u2014 the \u00a71.1 receipt).",
|
|
4
|
+
"theme": {
|
|
5
|
+
"mode": "light",
|
|
6
|
+
"cssVariables": {
|
|
7
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"expect": "refused"
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-accepted",
|
|
3
|
+
"description": "The v2 overlay: both projections, the attestation, an optional default mode and a label. Accepted.",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlayHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
6
|
+
"overlays": {
|
|
7
|
+
"light": {
|
|
8
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
9
|
+
},
|
|
10
|
+
"dark": {
|
|
11
|
+
"--ggui-color-primary-500": "#99aaff"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"mode": "light",
|
|
15
|
+
"name": "ocean"
|
|
16
|
+
},
|
|
17
|
+
"expect": "accepted"
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-keyframes-accepted",
|
|
3
|
+
"description": "Per-mode keyframes text that is exactly `@keyframes <ident> { … }` blocks (two blocks, a comment, frame selectors of every kind) is ACCEPTED by appThemeSchema — the slot carries what the card injects verbatim after the variables (ggui#987 §3.3, follower D).",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": { "--ggui-color-primary-500": "#3355ff" },
|
|
7
|
+
"dark": { "--ggui-color-primary-500": "#99aaff" }
|
|
8
|
+
},
|
|
9
|
+
"overlayHash": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
10
|
+
"keyframes": {
|
|
11
|
+
"light": "/* entrance */ @keyframes entrance { 0% { opacity: 0; transform: translateY(4px) } 100% { opacity: 1; transform: none } }\n@keyframes accent-pulse{0%,100%{opacity:1}50%{opacity:.7}}",
|
|
12
|
+
"dark": "@keyframes spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"expect": "accepted"
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-keyframes-not-keyframes",
|
|
3
|
+
"description": "Keyframes text that carries anything other than `@keyframes` blocks — here a bare `body { … }` rule after a valid block — is REFUSED by appThemeSchema: the slot is bounded to what it is for, so the theme principal cannot ship arbitrary same-document CSS through it (ggui#987 §3.4, follower D).",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": { "--ggui-color-primary-500": "#3355ff" },
|
|
7
|
+
"dark": { "--ggui-color-primary-500": "#99aaff" }
|
|
8
|
+
},
|
|
9
|
+
"overlayHash": "0000000000000000000000000000000000000000000000000000000000000000",
|
|
10
|
+
"keyframes": {
|
|
11
|
+
"light": "@keyframes spin { to { transform: rotate(360deg) } } body { display: none }"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"expect": "refused"
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-label-too-long",
|
|
3
|
+
"description": "A stamped label carrying a FULL sha256 after the prefix is 77 chars and exceeds appThemeSchema's 64-char `name` cap \u2014 REFUSED at the door. The seam ggui#987 flagged for the platform's pin shape.",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": {
|
|
7
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
8
|
+
},
|
|
9
|
+
"dark": {
|
|
10
|
+
"--ggui-color-primary-500": "#99aaff"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"overlayHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
14
|
+
"name": "guuey-app-v2.dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
|
|
15
|
+
},
|
|
16
|
+
"expect": "refused"
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-missing-dark",
|
|
3
|
+
"description": "An overlay with only one projection cannot follow the host's mode \u2014 REFUSED.",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlayHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
6
|
+
"overlays": {
|
|
7
|
+
"light": {
|
|
8
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"expect": "refused"
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-no-hash",
|
|
3
|
+
"description": "The attestation is REQUIRED: an overlay without `overlayHash` is refused at the door.",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": {
|
|
7
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
8
|
+
},
|
|
9
|
+
"dark": {
|
|
10
|
+
"--ggui-color-primary-500": "#99aaff"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"expect": "refused"
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "app-theme-v2-platform-pin",
|
|
3
|
+
"description": "The exact overlay shape a platform's -v2 composer sends (ggui#987 \u00a79; guuey#1128): both projections, the attestation, and a label of the form `<prefix>.<hash-prefix>`. `name` is capped at 64 chars by appThemeSchema, so a stamped label must keep its hash segment to 51 chars after a 13-char prefix. Accepted.",
|
|
4
|
+
"theme": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": {
|
|
7
|
+
"--ggui-color-primary-500": "#3355ff"
|
|
8
|
+
},
|
|
9
|
+
"dark": {
|
|
10
|
+
"--ggui-color-primary-500": "#99aaff"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"overlayHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
14
|
+
"name": "guuey-app-v2.ccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
|
15
|
+
},
|
|
16
|
+
"expect": "accepted"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "overlay-hash-canonical",
|
|
3
|
+
"description": "canonicalOverlayHash is ONE function on every minter and door: keys sorted recursively, no whitespace, absent fields omitted, sha256 lowercase hex. The expected value was computed independently with node:crypto over the canonical JSON; the input's keys are deliberately unsorted.",
|
|
4
|
+
"input": {
|
|
5
|
+
"overlays": {
|
|
6
|
+
"light": {
|
|
7
|
+
"--ggui-color-primary-500": "#3355ff",
|
|
8
|
+
"--ggui-color-ground": "#ffffff"
|
|
9
|
+
},
|
|
10
|
+
"dark": {
|
|
11
|
+
"--ggui-color-primary-500": "#99aaff",
|
|
12
|
+
"--ggui-color-ground": "#0e1014"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"expect": "7cc8c947beeae43de91a8e3eedc182a739ae134e3a3957958ebee4ec6cf25e96"
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "theme-mode-absence",
|
|
3
|
+
"description": "The absence law (ggui#551): when no layer resolves, the projection is undefined \u2014 never a light default.",
|
|
4
|
+
"sources": {
|
|
5
|
+
"stamped": null,
|
|
6
|
+
"sessionSidecar": null,
|
|
7
|
+
"hostAnnounced": null
|
|
8
|
+
},
|
|
9
|
+
"expect": null
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "theme-mode-default-when-silent-host",
|
|
3
|
+
"description": "A host that announces nothing leaves the stamp (then the sidecar) to fill the mode \u2014 the defaults still apply.",
|
|
4
|
+
"sources": {
|
|
5
|
+
"stamped": "light",
|
|
6
|
+
"sessionSidecar": "dark",
|
|
7
|
+
"hostAnnounced": null
|
|
8
|
+
},
|
|
9
|
+
"expect": "light"
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "theme-mode-order",
|
|
3
|
+
"description": "The client projection of the themeMode total order since ggui#987 (D4 = A, 'follow the widget'): with a stamped mode and a host announce present, the HOST wins \u2014 the embedding host owns runtime mode; the stamp and the sidecar are defaults. Before #987 this case expected 'light' (the stamp); it was promoted into the kit at that version and FAILED when the order flipped \u2014 the VERSION-POLICY \u00a71.1 receipt that names the flip breaking.",
|
|
4
|
+
"sources": {
|
|
5
|
+
"stamped": "light",
|
|
6
|
+
"sessionSidecar": null,
|
|
7
|
+
"hostAnnounced": "dark"
|
|
8
|
+
},
|
|
9
|
+
"expect": "dark"
|
|
10
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme-binding conformance — a pure-function catalog (ggui#987).
|
|
3
|
+
*
|
|
4
|
+
* Three contracts the kit grades directly against `@ggui-ai/protocol`, so
|
|
5
|
+
* their breaking-ness is decided by a fixture and not by prose
|
|
6
|
+
* (VERSION-POLICY §2 — the kit is the arbiter):
|
|
7
|
+
*
|
|
8
|
+
* - `theme-mode-*` — the CLIENT projection of the `themeMode` total
|
|
9
|
+
* order, `effectiveThemeMode` (`integrations/theme-binding.ts`): the
|
|
10
|
+
* embedding host owns runtime mode (D4).
|
|
11
|
+
* - `app-theme-*` — which overlay shapes `appThemeSchema` accepts: both
|
|
12
|
+
* projections and the attestation required; the v1 one-palette wire and
|
|
13
|
+
* `base` refused.
|
|
14
|
+
* - `overlay-hash-*` — `canonicalOverlayHash` against an independently
|
|
15
|
+
* computed vector.
|
|
16
|
+
*
|
|
17
|
+
* History (the §1.1 receipt): `theme-mode-order`, `app-theme-v1-one-palette`
|
|
18
|
+
* and `app-theme-v1-base` were promoted from the unit pins at the version
|
|
19
|
+
* BEFORE the revision, passed there, and failed when it landed — that is
|
|
20
|
+
* what named the revision breaking. Like `../refusal-envelope-conformance`,
|
|
21
|
+
* the cases are raw JSON under `./cases/` and are NOT registered in
|
|
22
|
+
* `fixturesByContract`; the entry point is the runner below and its test.
|
|
23
|
+
*/
|
|
24
|
+
import { canonicalOverlayHash } from '@ggui-ai/protocol';
|
|
25
|
+
type Opinion = 'light' | 'dark';
|
|
26
|
+
export interface ThemeModeCase {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly description: string;
|
|
29
|
+
readonly sources: {
|
|
30
|
+
readonly stamped: Opinion | null;
|
|
31
|
+
readonly sessionSidecar: Opinion | null;
|
|
32
|
+
readonly hostAnnounced: Opinion | null;
|
|
33
|
+
};
|
|
34
|
+
readonly expect: Opinion | null;
|
|
35
|
+
}
|
|
36
|
+
export interface AppThemeCase {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly description: string;
|
|
39
|
+
readonly theme: unknown;
|
|
40
|
+
readonly expect: 'accepted' | 'refused';
|
|
41
|
+
}
|
|
42
|
+
export interface OverlayHashCase {
|
|
43
|
+
readonly name: string;
|
|
44
|
+
readonly description: string;
|
|
45
|
+
readonly input: Parameters<typeof canonicalOverlayHash>[0];
|
|
46
|
+
readonly expect: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const THEME_MODE_CASES: readonly ThemeModeCase[];
|
|
49
|
+
export declare const APP_THEME_CASES: readonly AppThemeCase[];
|
|
50
|
+
export declare const OVERLAY_HASH_CASES: readonly OverlayHashCase[];
|
|
51
|
+
export interface ThemeBindingResult {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly pass: boolean;
|
|
54
|
+
readonly detail: string;
|
|
55
|
+
}
|
|
56
|
+
/** Grade every theme-binding case against the protocol's own functions. */
|
|
57
|
+
export declare function runThemeBindingConformance(): Promise<readonly ThemeBindingResult[]>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme-binding-conformance/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAkB,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAiBzE,KAAK,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;QACjC,QAAQ,CAAC,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;QACxC,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;KACxC,CAAC;IACF,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAkDD,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAA0F,CAAC;AAChJ,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAAuO,CAAC;AAC3R,eAAO,MAAM,kBAAkB,EAAE,SAAS,eAAe,EAAgD,CAAC;AAE1G,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAID,2EAA2E;AAC3E,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAqBzF"}
|