@ggui-ai/protocol-conformance 0.2.0-alpha.4 → 0.4.0-rc.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.
Files changed (83) hide show
  1. package/README.md +32 -13
  2. package/dist/cli.d.ts +11 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +48 -20
  5. package/dist/conformance-host.d.ts +81 -76
  6. package/dist/conformance-host.d.ts.map +1 -1
  7. package/dist/conformance-host.js +0 -44
  8. package/dist/fixtures/bootstrap-protocol/bootstrap-bundle-fetch-failed.json +3 -3
  9. package/dist/fixtures/bootstrap-protocol/bootstrap-meta-missing.json +3 -3
  10. package/dist/fixtures/bootstrap-protocol/bootstrap-success.json +3 -3
  11. package/dist/fixtures/consume-buffer/action-ack-sequence.json +28 -0
  12. package/dist/fixtures/consume-buffer/action-payload-schema-violation.json +37 -0
  13. package/dist/fixtures/consume-buffer/index.d.ts +6 -0
  14. package/dist/fixtures/consume-buffer/index.d.ts.map +1 -0
  15. package/dist/fixtures/consume-buffer/index.js +41 -0
  16. package/dist/fixtures/consume-buffer/undeclared-action-rejected.json +29 -0
  17. package/dist/fixtures/host-context/host-context-observed-persists.json +34 -0
  18. package/dist/fixtures/host-context/index.d.ts +5 -0
  19. package/dist/fixtures/host-context/index.d.ts.map +1 -0
  20. package/dist/fixtures/host-context/index.js +40 -0
  21. package/dist/fixtures/index.d.ts +28 -9
  22. package/dist/fixtures/index.d.ts.map +1 -1
  23. package/dist/fixtures/index.js +33 -14
  24. package/dist/fixtures/reserved-channel-authority/index.d.ts.map +1 -1
  25. package/dist/fixtures/reserved-channel-authority/index.js +17 -7
  26. package/dist/fixtures/reserved-channel-authority/props-update-roundtrip.json +4 -4
  27. package/dist/fixtures/schema-version-handshake/index.d.ts.map +1 -1
  28. package/dist/fixtures/schema-version-handshake/index.js +12 -4
  29. package/dist/fixtures/schema-version-handshake/version-match.json +7 -5
  30. package/dist/fixtures/schema-version-handshake/version-mismatch.json +9 -10
  31. package/dist/fixtures/subscribe-tenancy/absent-appid-defaults.json +18 -0
  32. package/dist/fixtures/subscribe-tenancy/app-mismatch.json +20 -0
  33. package/dist/fixtures/subscribe-tenancy/index.d.ts +6 -0
  34. package/dist/fixtures/subscribe-tenancy/index.d.ts.map +1 -0
  35. package/dist/fixtures/subscribe-tenancy/index.js +62 -0
  36. package/dist/index.d.ts +4 -4
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +4 -4
  39. package/dist/match-behavior.d.ts +19 -100
  40. package/dist/match-behavior.d.ts.map +1 -1
  41. package/dist/match-behavior.js +289 -246
  42. package/dist/registration-conformance/cases/gate-duplicate-hook.json +26 -0
  43. package/dist/registration-conformance/cases/gate-export-not-registered.json +1 -0
  44. package/dist/registration-conformance/cases/gate-multi-package-distinct-names-accept.json +26 -0
  45. package/dist/registration-conformance/cases/gate-no-gadgets-accept.json +1 -0
  46. package/dist/registration-conformance/cases/gate-package-mismatch.json +1 -0
  47. package/dist/registration-conformance/cases/gate-priority-not-registered-outranks-mismatch.json +1 -0
  48. package/dist/registration-conformance/cases/gate-priority-registry-outranks-public-env.json +22 -0
  49. package/dist/registration-conformance/cases/gate-public-env-missing.json +21 -0
  50. package/dist/registration-conformance/cases/gate-public-env-satisfied-accept.json +21 -0
  51. package/dist/registration-conformance/cases/gate-public-env-undeclared-wrapper-accept.json +26 -0
  52. package/dist/registration-conformance/cases/gate-registered-resolves-accept.json +1 -0
  53. package/dist/registration-conformance/cases/gate-stdlib-hook-accept.json +1 -0
  54. package/dist/registration-conformance/cases/gate-typo-classifies-as-not-registered.json +1 -0
  55. package/dist/registration-conformance/index.d.ts +64 -33
  56. package/dist/registration-conformance/index.d.ts.map +1 -1
  57. package/dist/registration-conformance/index.js +24 -8
  58. package/dist/run-conformance.d.ts +145 -6
  59. package/dist/run-conformance.d.ts.map +1 -1
  60. package/dist/run-conformance.js +531 -93
  61. package/dist/types.d.ts +319 -165
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js +27 -23
  64. package/dist/ws-transport.d.ts.map +1 -1
  65. package/dist/ws-transport.js +3 -2
  66. package/package.json +4 -4
  67. package/dist/fixtures/observability-events/index.d.ts +0 -5
  68. package/dist/fixtures/observability-events/index.d.ts.map +0 -1
  69. package/dist/fixtures/observability-events/index.js +0 -22
  70. package/dist/fixtures/observability-events/observability-contract-error-emitted.json +0 -28
  71. package/dist/fixtures/observability-events/observability-wired-tool-invoked.json +0 -27
  72. package/dist/fixtures/refresh-semantics/index.d.ts +0 -5
  73. package/dist/fixtures/refresh-semantics/index.d.ts.map +0 -1
  74. package/dist/fixtures/refresh-semantics/index.js +0 -19
  75. package/dist/fixtures/refresh-semantics/stream-refresh-success.json +0 -39
  76. package/dist/fixtures/reserved-channel-authority/stream-schema-violation.json +0 -44
  77. package/dist/fixtures/wired-action-dispatch/index.d.ts +0 -5
  78. package/dist/fixtures/wired-action-dispatch/index.d.ts.map +0 -1
  79. package/dist/fixtures/wired-action-dispatch/index.js +0 -29
  80. package/dist/fixtures/wired-action-dispatch/wired-action-success.json +0 -35
  81. package/dist/fixtures/wired-action-dispatch/wired-action-tool-not-found.json +0 -30
  82. package/dist/fixtures/wired-action-dispatch/wired-action-tool-threw.json +0 -31
  83. package/dist/fixtures/wired-action-dispatch/wired-action-tool-timeout.json +0 -31
@@ -15,5 +15,6 @@
15
15
  "exports": [{ "hook": "useLeafletMap" }]
16
16
  }
17
17
  ],
18
+ "appPublicEnv": {},
18
19
  "expect": { "outcome": "reject", "code": "gadget_not_registered" }
19
20
  }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "gate-multi-package-distinct-names-accept",
3
+ "description": "The duplicate-hook check fires on the same export NAME across packages — not on multi-package contracts per se. The contract declares two DIFFERENT export names from two different packages (`useCheckout` under `@stripe/ggui-checkout`, `useShippingEstimate` under `@acme/shipping`); both `(package, export)` pairs are registered and neither descriptor has `requires`. The composed gate MUST accept. Guards against an over-eager duplicate check that rejects any contract spanning more than one gadget package.",
4
+ "contract": {
5
+ "clientCapabilities": {
6
+ "gadgets": {
7
+ "@stripe/ggui-checkout": { "useCheckout": {} },
8
+ "@acme/shipping": { "useShippingEstimate": {} }
9
+ }
10
+ }
11
+ },
12
+ "appGadgets": [
13
+ {
14
+ "package": "@stripe/ggui-checkout",
15
+ "version": "1.0.0",
16
+ "exports": [{ "hook": "useCheckout" }]
17
+ },
18
+ {
19
+ "package": "@acme/shipping",
20
+ "version": "1.0.0",
21
+ "exports": [{ "hook": "useShippingEstimate" }]
22
+ }
23
+ ],
24
+ "appPublicEnv": {},
25
+ "expect": { "outcome": "accept" }
26
+ }
@@ -9,5 +9,6 @@
9
9
  "exports": [{ "hook": "useLeafletMap" }]
10
10
  }
11
11
  ],
12
+ "appPublicEnv": {},
12
13
  "expect": { "outcome": "accept" }
13
14
  }
@@ -15,5 +15,6 @@
15
15
  "exports": [{ "hook": "useLeafletMap" }]
16
16
  }
17
17
  ],
18
+ "appPublicEnv": {},
18
19
  "expect": { "outcome": "reject", "code": "gadget_package_mismatch" }
19
20
  }
@@ -16,5 +16,6 @@
16
16
  "exports": [{ "hook": "useLeafletMap" }]
17
17
  }
18
18
  ],
19
+ "appPublicEnv": {},
19
20
  "expect": { "outcome": "reject", "code": "gadget_not_registered" }
20
21
  }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "gate-priority-registry-outranks-public-env",
3
+ "description": "A single push that fails BOTH gadget gates: it references an export absent from every registered package (`useTurnstile` under `@acme/turnstile`) AND a registered wrapper whose `requires` is unsatisfied (`useMapboxMap` under `@acme/mapbox`, requiring `GGUI_PUBLIC_APP_MAPBOX_TOKEN` while `App.publicEnv` is empty). SPEC §7.7.3 pins the order: the registry gate runs FIRST so the operator gets the right diagnostic when both fail — an author who referenced an unknown export needs the registration miss, not a downstream env complaint. The composed gate MUST reject with `gadget_not_registered`.",
4
+ "contract": {
5
+ "clientCapabilities": {
6
+ "gadgets": {
7
+ "@acme/turnstile": { "useTurnstile": {} },
8
+ "@acme/mapbox": { "useMapboxMap": {} }
9
+ }
10
+ }
11
+ },
12
+ "appGadgets": [
13
+ {
14
+ "package": "@acme/mapbox",
15
+ "version": "1.0.0",
16
+ "exports": [{ "hook": "useMapboxMap" }],
17
+ "requires": ["GGUI_PUBLIC_APP_MAPBOX_TOKEN"]
18
+ }
19
+ ],
20
+ "appPublicEnv": {},
21
+ "expect": { "outcome": "reject", "code": "gadget_not_registered" }
22
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "gate-public-env-missing",
3
+ "description": "The contract references `useMapboxMap` under `@acme/mapbox`, and the app registers that exact `(package, export)` pair — registry membership passes — but the registered descriptor's `requires` lists the public env key `GGUI_PUBLIC_APP_MAPBOX_TOKEN` and `App.publicEnv` carries no keys at all. The render-time env gate (SPEC §7.7.3 — `assertPublicEnvSatisfied`) MUST reject with code `gadget_public_env_missing`: without the key, the wrapper's `getPublicEnv()` would throw at hook-mount inside the iframe, so the gate surfaces the misconfiguration as a recoverable author/operator-time error instead. Recovery: stamp the key on the app's public env, or drop the wrapper binding from the contract.",
4
+ "contract": {
5
+ "clientCapabilities": {
6
+ "gadgets": {
7
+ "@acme/mapbox": { "useMapboxMap": {} }
8
+ }
9
+ }
10
+ },
11
+ "appGadgets": [
12
+ {
13
+ "package": "@acme/mapbox",
14
+ "version": "1.0.0",
15
+ "exports": [{ "hook": "useMapboxMap" }],
16
+ "requires": ["GGUI_PUBLIC_APP_MAPBOX_TOKEN"]
17
+ }
18
+ ],
19
+ "appPublicEnv": {},
20
+ "expect": { "outcome": "reject", "code": "gadget_public_env_missing" }
21
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "gate-public-env-satisfied-accept",
3
+ "description": "The positive counterpart of `gate-public-env-missing`. The contract references `useMapboxMap` under `@acme/mapbox`; the registered descriptor requires `GGUI_PUBLIC_APP_MAPBOX_TOKEN`; and `App.publicEnv` carries that exact key. Every declared wrapper's `requires` is satisfied, so the composed gate MUST accept. Paired with the reject case, this also proves the gate actually reads `appPublicEnv` — an env-blind gate passes one of the pair but never both.",
4
+ "contract": {
5
+ "clientCapabilities": {
6
+ "gadgets": {
7
+ "@acme/mapbox": { "useMapboxMap": {} }
8
+ }
9
+ }
10
+ },
11
+ "appGadgets": [
12
+ {
13
+ "package": "@acme/mapbox",
14
+ "version": "1.0.0",
15
+ "exports": [{ "hook": "useMapboxMap" }],
16
+ "requires": ["GGUI_PUBLIC_APP_MAPBOX_TOKEN"]
17
+ }
18
+ ],
19
+ "appPublicEnv": { "GGUI_PUBLIC_APP_MAPBOX_TOKEN": "pk.conformance-fixture-value" },
20
+ "expect": { "outcome": "accept" }
21
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "gate-public-env-undeclared-wrapper-accept",
3
+ "description": "The env gate is scoped to wrappers the CONTRACT references, not the whole catalog. The contract declares only `useLeafletMap` under `@ggui-samples/leaflet` (registered, no `requires`). The app catalog ALSO registers `@acme/mapbox`, whose `requires` lists `GGUI_PUBLIC_APP_MAPBOX_TOKEN` — unsatisfied, since `App.publicEnv` is empty — but the contract never references that wrapper, so it cannot affect this render's iframe. SPEC §7.7.3 walks `requires` for every wrapper the contract references; registered-but-undeclared wrappers MUST NOT fail the push. The gate MUST accept. Guards against a gate that validates the operator's entire catalog instead of the declared subset.",
4
+ "contract": {
5
+ "clientCapabilities": {
6
+ "gadgets": {
7
+ "@ggui-samples/leaflet": { "useLeafletMap": {} }
8
+ }
9
+ }
10
+ },
11
+ "appGadgets": [
12
+ {
13
+ "package": "@ggui-samples/leaflet",
14
+ "version": "2.3.1",
15
+ "exports": [{ "hook": "useLeafletMap" }]
16
+ },
17
+ {
18
+ "package": "@acme/mapbox",
19
+ "version": "1.0.0",
20
+ "exports": [{ "hook": "useMapboxMap" }],
21
+ "requires": ["GGUI_PUBLIC_APP_MAPBOX_TOKEN"]
22
+ }
23
+ ],
24
+ "appPublicEnv": {},
25
+ "expect": { "outcome": "accept" }
26
+ }
@@ -21,5 +21,6 @@
21
21
  "exports": [{ "component": "RevenueChart" }, { "hook": "useChartTheme" }]
22
22
  }
23
23
  ],
24
+ "appPublicEnv": {},
24
25
  "expect": { "outcome": "accept" }
25
26
  }
@@ -23,5 +23,6 @@
23
23
  ]
24
24
  }
25
25
  ],
26
+ "appPublicEnv": {},
26
27
  "expect": { "outcome": "accept" }
27
28
  }
@@ -23,5 +23,6 @@
23
23
  ]
24
24
  }
25
25
  ],
26
+ "appPublicEnv": {},
26
27
  "expect": { "outcome": "reject", "code": "gadget_not_registered" }
27
28
  }
@@ -1,51 +1,72 @@
1
1
  /**
2
2
  * Registration-conformance catalog — accept / reject cases for the
3
- * gadget push-time registry gate (SPEC §7.7.2 — `assertGadgetsRegistered`).
3
+ * render-time gadget gate stack:
4
+ *
5
+ * - registry membership (SPEC §7.7.2 — `assertGadgetsRegistered`):
6
+ * every `(package, export)` the contract references resolves in
7
+ * `App.gadgets`, with the miss classified into a precise reject
8
+ * code (`gadget_not_registered` ▸ `gadget_package_mismatch`);
9
+ * - public-env satisfaction (SPEC §7.7.3 —
10
+ * `assertPublicEnvSatisfied`): every declared wrapper's
11
+ * `requires[]` key is present in `App.publicEnv`
12
+ * (`gadget_public_env_missing`). §7.7.3 pins the registry gate
13
+ * FIRST when both fail;
14
+ * - duplicate export names (SPEC §7.9 —
15
+ * `assertNoDuplicateGadgetHooks`): the same export name declared
16
+ * under two packages collides in the generated module scope
17
+ * (`duplicate_gadget_hook`). The catalog deliberately authors its
18
+ * duplicate cases so every pair resolves cleanly — this check's
19
+ * priority relative to the other two is NOT pinned.
4
20
  *
5
21
  * ## Why this is a pure-function catalog, not a behavioral fixture
6
22
  *
7
- * The push-time gadget gate answers a pure question: given a contract
8
- * and the app's registered `App.gadgets` catalog, does every
9
- * `(package, export)` the contract references resolve — and if not,
10
- * which precise reject code applies? There is no render, no
11
- * transport, no wire frame in that question — it is a deterministic
12
- * classification, exactly like the `clientCapabilities` schema check
13
- * in `../schema-conformance`.
23
+ * The gadget gate stack answers a pure question: given a contract,
24
+ * the app's registered `App.gadgets` catalog, and the app's
25
+ * `App.publicEnv` map, does the push commit — and if not, which
26
+ * precise reject code applies? There is no render, no transport, no
27
+ * wire frame in that question — it is a deterministic classification,
28
+ * exactly like the `clientCapabilities` schema check in
29
+ * `../schema-conformance`.
14
30
  *
15
31
  * Modeling it as a WebSocket behavioral fixture would mean inventing a
16
- * wire frame the real protocol never emits (the gate runs at MCP-push
32
+ * wire frame the real protocol never emits (the gates run at MCP-push
17
33
  * time, before any live channel exists) — the dishonest modeling the
18
- * kit's Path-A / Path-B partition exists to forbid. So the gate gets
19
- * the same treatment as the wire schema: a catalog of cases graded
20
- * against a caller-supplied gate function.
34
+ * kit's Path-A / Path-B partition exists to forbid. So the gate stack
35
+ * gets the same treatment as the wire schema: a catalog of cases
36
+ * graded against a caller-supplied gate function.
21
37
  *
22
38
  * ## Polyglot, decoupled
23
39
  *
24
40
  * Each case ships as raw JSON under `./cases/`. {@link runRegistrationConformance}
25
41
  * takes the gate as a callback — the kit never imports a concrete gate
26
- * implementation here, so adopters drive their OWN gate. The reference
27
- * binding (`./registration-conformance.test.ts`) wraps
28
- * `@ggui-ai/mcp-server-handlers`'s `assertGadgetsRegistered`.
42
+ * implementation, so adopters drive their OWN gate. The kit's
43
+ * meta-test (`./registration-conformance.test.ts`) grades a kit-local
44
+ * gate built from the SPEC, proving catalog coherence while keeping
45
+ * the vendor-neutral kit free of any server implementation; the
46
+ * drift-catch against a SHIPPING gate lives implementation-side (the
47
+ * first-party one is `assert-gadgets.conformance.test.ts` in
48
+ * `@ggui-ai/mcp-server-handlers`) so the dependency edge stays
49
+ * implementation → kit.
29
50
  *
30
51
  * The `DataContract` / `GadgetDescriptor` types ARE imported (type-only)
31
52
  * from `@ggui-ai/protocol` — unlike the behavioral fixture vocabulary
32
53
  * in `../types.ts`, these are the gate's actual input contract, not a
33
54
  * frozen authored union; the runner's `gate` signature MUST match the
34
- * real function for the reference binding to be cast-free.
55
+ * real function for an implementation binding to be cast-free.
35
56
  */
36
57
  import type { DataContract, GadgetDescriptor } from '@ggui-ai/protocol';
37
58
  /**
38
- * The precise reject codes the gadget gate classifies a miss into.
39
- * Mirrors `GadgetGateErrorCode`'s registry-gate arms in
40
- * `@ggui-ai/mcp-server-handlers`. Extensibly-closed `(string & {})`
41
- * tail so a later protocol revision's code rides through without a kit
42
- * bump — same discipline as `ContractErrorCode` in `../types.ts`.
59
+ * The precise reject codes the gadget gate stack classifies a failing
60
+ * push into — the SPEC §7.9 Plane-2 slugs for the four gadget gate
61
+ * rejections. Extensibly-closed `(string & {})` tail so a later
62
+ * protocol revision's code rides through without a kit bump — same
63
+ * discipline as `BootstrapFailureReason` in `../types.ts`.
43
64
  */
44
- export type GadgetGateRejectCode = 'gadget_not_registered' | 'gadget_package_mismatch' | (string & {});
65
+ export type GadgetGateRejectCode = 'gadget_not_registered' | 'gadget_package_mismatch' | 'gadget_public_env_missing' | 'duplicate_gadget_hook' | (string & {});
45
66
  /**
46
- * The outcome of running the gate against one `(contract, appGadgets)`
47
- * pair. A conformant gate either accepts the push or rejects it with
48
- * one classified code.
67
+ * The outcome of running the gate stack against one
68
+ * `(contract, appGadgets, appPublicEnv)` triple. A conformant gate
69
+ * either accepts the push or rejects it with one classified code.
49
70
  */
50
71
  export type GateOutcome = {
51
72
  readonly outcome: 'accept';
@@ -70,6 +91,12 @@ export interface RegistrationConformanceCase {
70
91
  readonly contract: DataContract;
71
92
  /** The app's registered gadget catalog the gate resolves against. */
72
93
  readonly appGadgets: readonly GadgetDescriptor[];
94
+ /**
95
+ * The app's operator-stamped public-env map the gate checks declared
96
+ * wrappers' `requires[]` against (SPEC §7.7.3). Always present on a
97
+ * case — `{}` models an app with no public env configured.
98
+ */
99
+ readonly appPublicEnv: Readonly<Record<string, string>>;
73
100
  /** The outcome a spec-conformant gate MUST produce. */
74
101
  readonly expect: GateOutcome;
75
102
  }
@@ -97,18 +124,22 @@ export interface RegistrationConformanceResult {
97
124
  /**
98
125
  * Grade a gadget registration gate against the catalog.
99
126
  *
100
- * `gate` MUST be a pure classification of `(contract, appGadgets)` —
101
- * return `{outcome:'accept'}` when every referenced `(package, export)`
102
- * resolves, or `{outcome:'reject', code}` with the precise reject code
103
- * otherwise. The kit deliberately does NOT import a concrete gate —
104
- * adopters pass their own (the reference binding wraps
105
- * `assertGadgetsRegistered`; see `./registration-conformance.test.ts`).
106
- * A conformant gate produces an empty `failed` array.
127
+ * `gate` MUST be a pure classification of
128
+ * `(contract, appGadgets, appPublicEnv)` — return `{outcome:'accept'}`
129
+ * when the push commits (every referenced `(package, export)`
130
+ * resolves, every declared wrapper's `requires[]` is satisfied, no
131
+ * export name repeats across packages), or `{outcome:'reject', code}`
132
+ * with the precise reject code otherwise. Implementations that compose
133
+ * separate checks wrap the composition. The kit deliberately does NOT
134
+ * import a concrete gate — adopters pass their own (the first-party
135
+ * drift-catch wraps `@ggui-ai/mcp-server-handlers`'s gate trio in its
136
+ * own package; see the module doc). A conformant gate produces an
137
+ * empty `failed` array.
107
138
  *
108
139
  * `gate` is invoked exactly once per case, in {@link gadgetRegistrationCases}
109
140
  * order; it MUST be pure and MUST NOT throw (a throwing gate is itself
110
141
  * non-conformant — wrap it so a classified rejection becomes a
111
142
  * returned `GateOutcome`).
112
143
  */
113
- export declare function runRegistrationConformance(gate: (contract: DataContract, appGadgets: readonly GadgetDescriptor[]) => GateOutcome): RegistrationConformanceResult;
144
+ export declare function runRegistrationConformance(gate: (contract: DataContract, appGadgets: readonly GadgetDescriptor[], appPublicEnv: Readonly<Record<string, string>>) => GateOutcome): RegistrationConformanceResult;
114
145
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registration-conformance/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAUxE;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B,uBAAuB,GACvB,yBAAyB,GACzB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,2BAA2B,EAQzE,CAAC;AAEF,iDAAiD;AACjD,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,6BAA6B;IAC5C,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,SAAS,+BAA+B,EAAE,CAAC;CAC7D;AAUD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,CACJ,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,gBAAgB,EAAE,KACpC,WAAW,GACf,6BAA6B,CAgB/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registration-conformance/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAgBxE;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B,uBAAuB,GACvB,yBAAyB,GACzB,2BAA2B,GAC3B,uBAAuB,GACvB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAExE;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,2BAA2B,EAczE,CAAC;AAEF,iDAAiD;AACjD,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,6BAA6B;IAC5C,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,SAAS,+BAA+B,EAAE,CAAC;CAC7D;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,CACJ,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,SAAS,gBAAgB,EAAE,EACvC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAC3C,WAAW,GACf,6BAA6B,CAoB/B"}
@@ -1,7 +1,13 @@
1
+ import gateDuplicateHook from './cases/gate-duplicate-hook.json' with { type: 'json' };
1
2
  import gateExportNotRegistered from './cases/gate-export-not-registered.json' with { type: 'json' };
3
+ import gateMultiPackageDistinctNamesAccept from './cases/gate-multi-package-distinct-names-accept.json' with { type: 'json' };
2
4
  import gateNoGadgetsAccept from './cases/gate-no-gadgets-accept.json' with { type: 'json' };
3
5
  import gatePackageMismatch from './cases/gate-package-mismatch.json' with { type: 'json' };
4
6
  import gatePriorityNotRegisteredOutranksMismatch from './cases/gate-priority-not-registered-outranks-mismatch.json' with { type: 'json' };
7
+ import gatePriorityRegistryOutranksPublicEnv from './cases/gate-priority-registry-outranks-public-env.json' with { type: 'json' };
8
+ import gatePublicEnvMissing from './cases/gate-public-env-missing.json' with { type: 'json' };
9
+ import gatePublicEnvSatisfiedAccept from './cases/gate-public-env-satisfied-accept.json' with { type: 'json' };
10
+ import gatePublicEnvUndeclaredWrapperAccept from './cases/gate-public-env-undeclared-wrapper-accept.json' with { type: 'json' };
5
11
  import gateRegisteredResolvesAccept from './cases/gate-registered-resolves-accept.json' with { type: 'json' };
6
12
  import gateStdlibHookAccept from './cases/gate-stdlib-hook-accept.json' with { type: 'json' };
7
13
  import gateTypoClassifiesAsNotRegistered from './cases/gate-typo-classifies-as-not-registered.json' with { type: 'json' };
@@ -15,9 +21,15 @@ export const gadgetRegistrationCases = [
15
21
  gatePackageMismatch,
16
22
  gatePriorityNotRegisteredOutranksMismatch,
17
23
  gateTypoClassifiesAsNotRegistered,
24
+ gatePublicEnvMissing,
25
+ gatePriorityRegistryOutranksPublicEnv,
26
+ gateDuplicateHook,
18
27
  gateStdlibHookAccept,
19
28
  gateRegisteredResolvesAccept,
20
29
  gateNoGadgetsAccept,
30
+ gatePublicEnvSatisfiedAccept,
31
+ gatePublicEnvUndeclaredWrapperAccept,
32
+ gateMultiPackageDistinctNamesAccept,
21
33
  ];
22
34
  function gateOutcomeEquals(a, b) {
23
35
  if (a.outcome !== b.outcome)
@@ -30,13 +42,17 @@ function gateOutcomeEquals(a, b) {
30
42
  /**
31
43
  * Grade a gadget registration gate against the catalog.
32
44
  *
33
- * `gate` MUST be a pure classification of `(contract, appGadgets)` —
34
- * return `{outcome:'accept'}` when every referenced `(package, export)`
35
- * resolves, or `{outcome:'reject', code}` with the precise reject code
36
- * otherwise. The kit deliberately does NOT import a concrete gate —
37
- * adopters pass their own (the reference binding wraps
38
- * `assertGadgetsRegistered`; see `./registration-conformance.test.ts`).
39
- * A conformant gate produces an empty `failed` array.
45
+ * `gate` MUST be a pure classification of
46
+ * `(contract, appGadgets, appPublicEnv)` — return `{outcome:'accept'}`
47
+ * when the push commits (every referenced `(package, export)`
48
+ * resolves, every declared wrapper's `requires[]` is satisfied, no
49
+ * export name repeats across packages), or `{outcome:'reject', code}`
50
+ * with the precise reject code otherwise. Implementations that compose
51
+ * separate checks wrap the composition. The kit deliberately does NOT
52
+ * import a concrete gate — adopters pass their own (the first-party
53
+ * drift-catch wraps `@ggui-ai/mcp-server-handlers`'s gate trio in its
54
+ * own package; see the module doc). A conformant gate produces an
55
+ * empty `failed` array.
40
56
  *
41
57
  * `gate` is invoked exactly once per case, in {@link gadgetRegistrationCases}
42
58
  * order; it MUST be pure and MUST NOT throw (a throwing gate is itself
@@ -47,7 +63,7 @@ export function runRegistrationConformance(gate) {
47
63
  const passed = [];
48
64
  const failed = [];
49
65
  for (const testCase of gadgetRegistrationCases) {
50
- const actual = gate(testCase.contract, testCase.appGadgets);
66
+ const actual = gate(testCase.contract, testCase.appGadgets, testCase.appPublicEnv);
51
67
  if (gateOutcomeEquals(actual, testCase.expect)) {
52
68
  passed.push(testCase.name);
53
69
  }
@@ -1,10 +1,15 @@
1
- import type { ConformanceHost } from './conformance-host.js';
2
- import type { AuthConfig, ContractErrorBehavior, StreamUpdateBehavior, VersionMismatchBehavior } from './types.js';
1
+ import type { HostContextObservedPayload } from '@ggui-ai/protocol';
2
+ import type { ConformanceHost, SetupStep as HostSetupStep } from './conformance-host.js';
3
+ import { type MatchResult } from './match-behavior.js';
4
+ import type { AuthConfig, SessionStateBehavior, StreamUpdateBehavior, VersionMismatchBehavior } from './types.js';
3
5
  export interface RunConformanceConfig {
4
6
  /**
5
- * Base URL of the implementation under test. The runner appends
6
- * `/ws` to reach the live-channel endpoint; provide `http://host:port`
7
- * or `https://…` and the runner derives `ws://` / `wss://`.
7
+ * URL of the implementation under test. `http://` / `https://`
8
+ * schemes derive `ws://` / `wss://`. A bare origin (no path, e.g.
9
+ * `http://localhost:3000`) gets the default live-channel path `/ws`
10
+ * appended; a URL that already carries a path (e.g.
11
+ * `ws://localhost:3000/ws`, or a non-default mount point) is used
12
+ * exactly as given — the runner never appends to an explicit path.
8
13
  */
9
14
  readonly serverUrl: string;
10
15
  /** Auth carried on the WS upgrade. See {@link AuthConfig}. */
@@ -54,5 +59,139 @@ export interface ConformanceReporter {
54
59
  onComplete?(result: ConformanceResult): void;
55
60
  }
56
61
  export declare function runConformance(config: RunConformanceConfig): Promise<ConformanceResult>;
57
- export type { ContractErrorBehavior, StreamUpdateBehavior, VersionMismatchBehavior };
62
+ /**
63
+ * Resolve the WS endpoint from `config.serverUrl`:
64
+ * - `http://` / `https://` schemes become `ws://` / `wss://`; a
65
+ * scheme-less value is assumed `ws://`.
66
+ * - A bare origin (no path) gets the default live-channel path
67
+ * `/ws` appended.
68
+ * - A URL that already carries a path is used exactly as given —
69
+ * the runner never appends to an explicit path, so
70
+ * `ws://host:3000/ws` (or a non-default mount point) works
71
+ * without double-appending.
72
+ *
73
+ * Exported for unit tests; not part of the package's public API.
74
+ */
75
+ export declare function deriveWsUrl(serverUrl: string): string;
76
+ /**
77
+ * Fixture-authored `host_context_observed` Client→Server frame — the
78
+ * wire shape from `@ggui-ai/protocol` (`transport/websocket`):
79
+ * `{type: 'host_context_observed', payload: {sessionId, hostContext}}`.
80
+ * The iframe-runtime emits it after `ui/initialize` resolves (and on
81
+ * every `host-context-changed` notification); the server's obligation
82
+ * is to persist `payload.hostContext` onto `GguiSession.hostContext`
83
+ * with no synchronous response — which is why fixtures authoring this
84
+ * envelope pair it with a `session-state` expectation, not a frame
85
+ * expectation.
86
+ */
87
+ export interface HostContextObservedInputEnvelope {
88
+ readonly type: 'host_context_observed';
89
+ readonly requestId?: string;
90
+ readonly payload: HostContextObservedPayload;
91
+ }
92
+ /**
93
+ * Classification of a fixture's `inputEnvelope` into the CLOSED
94
+ * dispatch vocabulary — exactly the C→S frame types the shipped
95
+ * fixture catalog authors for explicit post-subscribe dispatch.
96
+ *
97
+ * - `action` — the live-channel action dispatch shape, sent
98
+ * VERBATIM. Deliberately untyped beyond the discriminator: action
99
+ * fixtures may author adversarial payloads (undeclared action
100
+ * names, malformed bodies) precisely because the server's
101
+ * rejection path is what's under test — the kit MUST NOT
102
+ * pre-validate away the inputs the contract is graded on.
103
+ * - `host_context_observed` — the validated typed arm
104
+ * ({@link HostContextObservedInputEnvelope}). The kit authors this
105
+ * frame as a well-formed client, so a malformed one is a
106
+ * fixture-authoring error, not a server probe.
107
+ * - `none` — every other authored envelope (`render`, `handshake`,
108
+ * `props-update`) is driven by the subscribe itself or by a
109
+ * Path-B host harness; the explicit send is skipped.
110
+ */
111
+ export type InputEnvelopeDispatch = {
112
+ readonly kind: 'action';
113
+ readonly envelope: unknown;
114
+ } | {
115
+ readonly kind: 'host_context_observed';
116
+ readonly envelope: HostContextObservedInputEnvelope;
117
+ } | {
118
+ readonly kind: 'none';
119
+ };
120
+ /**
121
+ * Validating classifier for the fixture's `inputEnvelope`. The fixture
122
+ * JSON enters the type system through a compile-time cast, so —
123
+ * exactly like {@link parseSetupStep} — the dispatchable arms are
124
+ * re-validated structurally here, and a malformed
125
+ * `host_context_observed` frame throws a descriptive fixture-authoring
126
+ * error (never a skip, never a fail of the implementation under test).
127
+ *
128
+ * Exported for unit tests; not part of the package's public API.
129
+ */
130
+ export declare function parseInputEnvelope(fixtureName: string, envelope: unknown): InputEnvelopeDispatch;
131
+ /**
132
+ * Grade a `session-state` expectation — the input message left no wire
133
+ * trace, so the honest verdict is a post-observation-window read-back
134
+ * of the mutated GguiSession field via
135
+ * {@link ConformanceHost.readSessionField}, compared with the SAME
136
+ * exact {@link deepEqual} the frame matchers use.
137
+ *
138
+ * A missing host, a host without `readSessionField`, or a read that
139
+ * throws all yield `unmatchable-on-ws` — the runner records a SKIP
140
+ * with the reason. The kit refuses to grade a stateful obligation it
141
+ * has no introspection seam for (a host that cannot read state cannot
142
+ * grade it); it never converts that gap into a pass or a fail.
143
+ *
144
+ * Exported for unit tests; not part of the package's public API.
145
+ */
146
+ export declare function matchSessionState(behavior: SessionStateBehavior, sessionId: string, host: ConformanceHost | undefined): Promise<MatchResult>;
147
+ /**
148
+ * Resolved, runner-ready form of `SubscribeFrameShaping`: the
149
+ * `'current'` sentinel is already replaced by the kit's compiled
150
+ * `PROTOCOL_SCHEMA_VERSION`, so the subscribe-send site only ever
151
+ * sees a concrete declaration (or none).
152
+ */
153
+ export interface ResolvedSubscribeShaping {
154
+ readonly omitAppId: boolean;
155
+ readonly supportedVersions?: readonly string[];
156
+ }
157
+ /**
158
+ * Validating narrower for the fixture-authored `subscribe` knob
159
+ * (`SubscribeFrameShaping`, types.ts). Same trust-boundary posture as
160
+ * {@link parseSetupStep}: the fixture JSON enters the type system
161
+ * through a compile-time cast, so the shape is re-validated
162
+ * structurally here and any malformed or unknown shaping is a
163
+ * fixture-authoring error the runner throws on — never a skip, never
164
+ * a fail of the implementation under test.
165
+ *
166
+ * The vocabulary is CLOSED — exactly the shaping fields the shipped
167
+ * catalog authors (`omitAppId`, `supportedVersions`); an unknown key
168
+ * is rejected so a typo'd knob can never silently no-op into a
169
+ * vacuous grade. `supportedVersions: 'current'` resolves to
170
+ * `[PROTOCOL_SCHEMA_VERSION]` (the kit's compiled canonical), keeping
171
+ * fixtures evergreen across protocol version bumps.
172
+ *
173
+ * Exported for unit tests; not part of the package's public API.
174
+ */
175
+ export declare function parseSubscribeShaping(fixtureName: string, shaping: unknown): ResolvedSubscribeShaping;
176
+ /**
177
+ * Validating narrower from the fixture-JSON `SetupStep` (discriminated
178
+ * on `type`) to the host's runtime `SetupStep` (discriminated on
179
+ * `kind`). The fixture JSON enters the type system through a
180
+ * compile-time cast (tsc widens JSON-module string literals), so the
181
+ * static union cannot be trusted at runtime — every directive is
182
+ * re-validated structurally here.
183
+ *
184
+ * The setup vocabulary is CLOSED: an unknown or malformed directive is
185
+ * a fixture-authoring error, thrown with a descriptive message. It is
186
+ * never mapped to a skip or a fail — those verdicts describe the
187
+ * implementation under test, not the fixture catalog.
188
+ *
189
+ * The input is `unknown` by design — this function IS the trust
190
+ * boundary, so it never leans on the static union it produces
191
+ * evidence for.
192
+ *
193
+ * Exported for unit tests; not part of the package's public API.
194
+ */
195
+ export declare function parseSetupStep(fixtureName: string, step: unknown): HostSetupStep;
196
+ export type { StreamUpdateBehavior, VersionMismatchBehavior };
58
197
  //# sourceMappingURL=run-conformance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-conformance.d.ts","sourceRoot":"","sources":["../src/run-conformance.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EAErB,oBAAoB,EAGpB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,aAAa,CAAC,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClD,aAAa,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,UAAU,CAAC,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC9C;AAMD,wBAAsB,cAAc,CAClC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA6C5B;AAyPD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"run-conformance.d.ts","sourceRoot":"","sources":["../src/run-conformance.ts"],"names":[],"mappings":"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"}