@openwop/spec-artifacts 2.35.0 → 2.36.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 (101) hide show
  1. package/CORPUS-STAMP.json +103 -89
  2. package/api/openapi.yaml +325 -4
  3. package/api/seams-v2.yaml +342 -1
  4. package/api/v2/asyncapi.yaml +1 -1
  5. package/api/v2/openapi.yaml +564 -8
  6. package/package.json +1 -1
  7. package/schemas/a2a-task-state.schema.json +3 -3
  8. package/schemas/artifact-type-pack-manifest.schema.json +3 -3
  9. package/schemas/capabilities.schema.json +34 -1
  10. package/schemas/connection-pack-manifest.schema.json +14 -0
  11. package/schemas/debug-bundle.schema.json +20 -0
  12. package/schemas/dispatch-config.schema.json +1 -1
  13. package/schemas/localized-content-language-settings.schema.json +3 -3
  14. package/schemas/localized-content-page.schema.json +2 -2
  15. package/schemas/localized-content-section.schema.json +3 -3
  16. package/schemas/run-event-payloads.schema.json +4 -2
  17. package/schemas/suspend-request.schema.json +61 -4
  18. package/schemas/v2/a2a-task-state.schema.json +10 -9
  19. package/schemas/v2/agent-deployment-transition.schema.json +4 -4
  20. package/schemas/v2/agent-deployment.schema.json +7 -7
  21. package/schemas/v2/agent-eval-suite.schema.json +10 -10
  22. package/schemas/v2/agent-inventory-response.schema.json +8 -2
  23. package/schemas/v2/artifact-type-pack-manifest.schema.json +3 -3
  24. package/schemas/v2/artifact.schema.json +84 -0
  25. package/schemas/v2/capabilities.schema.json +82 -8
  26. package/schemas/v2/certification-bundle.schema.json +1 -1
  27. package/schemas/v2/channel-presence-payload.schema.json +3 -3
  28. package/schemas/v2/connection-pack-manifest.schema.json +14 -0
  29. package/schemas/v2/conversation-event.schema.json +9 -2
  30. package/schemas/v2/conversation-turn.schema.json +19 -12
  31. package/schemas/v2/dispatch-config.schema.json +1 -1
  32. package/schemas/v2/envelopes/ui.a2ui-surface.schema.json +920 -22
  33. package/schemas/v2/error-envelope.schema.json +11 -1
  34. package/schemas/v2/eval-summary.schema.json +1 -2
  35. package/schemas/v2/goal.schema.json +4 -4
  36. package/schemas/v2/localized-content-language-settings.schema.json +3 -3
  37. package/schemas/v2/localized-content-page.schema.json +2 -2
  38. package/schemas/v2/localized-content-section.schema.json +3 -3
  39. package/schemas/v2/node-pack-manifest.schema.json +105 -0
  40. package/schemas/v2/part.schema.json +81 -0
  41. package/schemas/v2/proposal.schema.json +6 -6
  42. package/schemas/v2/run-event-payloads.schema.json +5 -3
  43. package/schemas/v2/self-hosted-runner-dispatch-frame.schema.json +2 -2
  44. package/schemas/v2/self-hosted-runner-result-frame.schema.json +1 -1
  45. package/schemas/v2/suspend-request.schema.json +251 -6
  46. package/schemas/v2/tool-descriptor.schema.json +246 -2
  47. package/schemas/v2/trigger-event.schema.json +1 -2
  48. package/schemas/v2/trigger-subscription.schema.json +1 -2
  49. package/schemas/v2/webhook-verification.schema.json +22 -0
  50. package/schemas/v2/workflow-definition.schema.json +25 -25
  51. package/spec/v1/alias-detectors.json +13 -1
  52. package/spec/v1/core-standard-manifest.json +2 -2
  53. package/spec/v1/deprecations.json +45 -1
  54. package/spec/v1/deprecations.schema.json +119 -4
  55. package/spec/v1/gaps.json +1925 -4
  56. package/spec/v2/README.md +5 -2
  57. package/spec/v2/core/capabilities.md +13 -26
  58. package/spec/v2/core/conformance.md +5 -8
  59. package/spec/v2/core/connection-packs.md +1 -1
  60. package/spec/v2/core/conversation.md +1 -1
  61. package/spec/v2/core/errors.md +8 -3
  62. package/spec/v2/core/events.md +8 -20
  63. package/spec/v2/core/form-content-packs.md +2 -2
  64. package/spec/v2/core/headers.md +5 -4
  65. package/spec/v2/core/host-services.md +6 -2
  66. package/spec/v2/core/idempotency.md +1 -1
  67. package/spec/v2/core/identity.md +23 -12
  68. package/spec/v2/core/interop.md +34 -4
  69. package/spec/v2/core/interrupt.md +6 -3
  70. package/spec/v2/core/node-pack-runtimes.md +20 -0
  71. package/spec/v2/core/oauth.md +32 -0
  72. package/spec/v2/core/overview.md +19 -6
  73. package/spec/v2/core/packs.md +4 -6
  74. package/spec/v2/core/persistence.md +20 -55
  75. package/spec/v2/core/replay.md +5 -11
  76. package/spec/v2/core/runs.md +9 -8
  77. package/spec/v2/core/security-defaults.md +18 -20
  78. package/spec/v2/core/tool-catalog.md +22 -0
  79. package/spec/v2/core/versioning.md +10 -28
  80. package/spec/v2/core/webhooks.md +16 -4
  81. package/spec/v2/core/workflow-chain-packs.md +1 -1
  82. package/spec/v2/corrections.json +32 -0
  83. package/spec/v2/corrections.schema.json +49 -0
  84. package/spec/v2/declaration.json +18 -13
  85. package/spec/v2/declaration.schema.json +3 -1
  86. package/spec/v2/errors.json +46 -1
  87. package/spec/v2/ext/a2uiSurface/README.md +131 -17
  88. package/spec/v2/ext/dataIntegration/README.md +5 -0
  89. package/spec/v2/facets/a2a.schema.json +4 -0
  90. package/spec/v2/facets/auth.schema.json +24 -0
  91. package/spec/v2/facets/mcp.schema.json +4 -0
  92. package/spec/v2/facets/oauth.schema.json +70 -0
  93. package/spec/v2/facets/webhooks.schema.json +23 -2
  94. package/spec/v2/id-field-bindings.json +2 -0
  95. package/spec/v2/interop-map.json +639 -0
  96. package/spec/v2/interop-map.schema.json +458 -0
  97. package/spec/v2/migrations.json +7 -0
  98. package/spec/v2/migrations.schema.json +58 -0
  99. package/spec/v2/path-manifest.json +6 -1
  100. package/spec/v2/release.json +3 -3
  101. package/spec/v2/surface-baseline.json +7981 -0
@@ -1,7 +1,8 @@
1
1
  # `a2uiSurface` extension
2
2
 
3
- > **Status: Draft · v2 extension.** Discovery-only reservation; no portable
4
- > operations or payload contract is defined in the current v2 corpus.
3
+ > **Status: Draft · v2 extension.** Normative contract for the `ui.a2ui-surface`
4
+ > envelope kind at per-kind schema version 2 (RFC 0209), and the deprecated
5
+ > `deltaTransport` facet (RFC 0114 in v1).
5
6
 
6
7
  | Field | Value |
7
8
  | --- | --- |
@@ -10,24 +11,137 @@
10
11
  | **adoption:** | `none` |
11
12
  | **peer-dependency id** | `a2uiSurface` |
12
13
  | **advertised as** | `extensions.<org>.a2uiSurface` |
13
- | **owning RFC** | RFC 0114 |
14
- | **declared facets** | `deltaTransport` |
14
+ | **owning RFC** | RFC 0209 |
15
+ | **declared facets** | `deltaTransport` (deprecated) |
15
16
 
16
- ## Contract boundary
17
+ ## Versions
17
18
 
18
- A host MAY advertise this identifier under its registered organization namespace.
19
- The extension record is organization-defined, so clients MUST NOT infer portable
20
- operations, payloads, or authorization semantics from its presence. A pack may
21
- name `a2uiSurface` as a dependency only when the host and pack share
22
- an out-of-band definition of that dependency.
19
+ `ui.a2ui-surface` has two per-kind schema versions in v2, both in
20
+ [`schemas/v2/envelopes/ui.a2ui-surface.schema.json`](../../../../schemas/v2/envelopes/ui.a2ui-surface.schema.json):
23
21
 
24
- The v1 description,
25
- [`spec/v1/capabilities.md`](https://github.com/openwop/openwop/blob/main/spec/v1/capabilities.md)
26
- (`a2uiSurface`), is useful for migration but is not a
27
- standalone v2 interoperability contract. A future revision can replace this
28
- boundary with normative behavior, schemas, and a behavioral witness.
22
+ | Version | Branch | Shape |
23
+ | --- | --- | --- |
24
+ | `1`, `0` or absent | `$defs/payloadV1` | the RFC 0102 seven-component tree pinned by `catalogVersion: "0.9.1"`, unchanged from v1 |
25
+ | `2` | `$defs/payloadV2` | `{ reasoning?, version: "v0.9", catalogId, surfaceId, messages[1..64] }`: an ordered run of A2UI v0.9 server-to-client messages in the profile below |
26
+
27
+ An engine MUST validate an envelope against exactly one branch: the one for the
28
+ version that `core/events.md` §"The envelope-kind catalog" selects (the emitted
29
+ version, or the advertised one under `warn` below the floor). It MUST NOT
30
+ validate against the union: a version-2 envelope carrying a version-1 payload is
31
+ invalid, and so is the reverse. The root `anyOf` exists for tooling; a host that
32
+ asks a model to emit version 2 hands the provider `$defs/payloadV2` alone.
33
+
34
+ A host admits version 2 by advertising `schemaVersions.kinds["ui.a2ui-surface"]: 2`.
35
+ The catalog rules then apply unchanged, so a consumer that knows only version 1
36
+ refuses version 2 with `unknown_schema_version` and fails closed.
37
+
38
+ In a version-2 payload, `catalogId` is an enum of the host-pinned catalogs, today
39
+ exactly `https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json`. Every
40
+ message's `surfaceId` MUST equal the payload's `surfaceId`, and a
41
+ `createSurface.catalogId` MUST equal the payload's `catalogId`. The schema cannot
42
+ express either cross-field rule, so the engine checks both at admission and
43
+ refuses a violation with `envelope_invalid`.
44
+
45
+ ## The profile
46
+
47
+ Every message that validates against `payloadV2.messages[]` MUST also validate
48
+ against upstream A2UI v0.9 `server_to_client.json` with the basic catalog and
49
+ `common_types.json` bound. The profile only removes; it never adds a property
50
+ A2UI lacks. Conformance vendors the upstream files, pinned by SHA-256
51
+ (`conformance/fixtures/upstream/a2ui-v0.9/`).
52
+
53
+ | Message | Profile |
54
+ | --- | --- |
55
+ | `createSurface` | `surfaceId`, `catalogId`, optional `theme` limited to `primaryColor` and `agentDisplayName` |
56
+ | `updateComponents` | `surfaceId` and `components[1..512]` from the set below |
57
+ | `updateDataModel` | as upstream: `surfaceId`, optional `path` (JSON Pointer), optional `value` |
58
+ | `deleteSurface` | as upstream |
59
+
60
+ Components, each closed and discriminated by a single-string-enum `component`:
61
+ `Text`, `TextField`, `CheckBox`, `ChoicePicker`, `DateTimeInput`, `Button`,
62
+ `Column`, `Row`, `Card`, `Divider`. A dynamic value is a literal or a `{path}`
63
+ data binding. `Column` and `Row` take static `children` id lists only.
64
+
65
+ | Excluded | Why |
66
+ | --- | --- |
67
+ | `Button.action.functionCall` (including `openUrl`) | client-side execution; `a2ui-action-confinement` |
68
+ | `FunctionCall` values, except `checks[].condition` calling `required` | code execution on the renderer; `a2ui-surface-no-code-exec` |
69
+ | `TextField.variant: "obscured"` | a surface MUST NOT solicit a secret; `a2ui-surface-no-secret-input` |
70
+ | `Image`, `Video`, `AudioPlayer`, `createSurface.theme.iconUrl` | each fetches a URL; `a2ui-surface-no-network-egress` |
71
+ | `createSurface.sendDataModel` | collected data returns only through the action below |
72
+ | `Icon` | its vocabulary is renderer-defined; deferred |
73
+ | `List`, `Tabs`, `Modal`, `Slider`, data-model templates | outside the day-one profile |
74
+
75
+ ## Actions and collected data
76
+
77
+ A `Button.action` MUST be the A2UI server-event arm `{ event: { name, context? } }`
78
+ with `name` ∈ {`resume`, `exchange`}: an interrupt resume or a conversation
79
+ exchange. When a user fires one, the consumer resolves `event.context` against
80
+ the surface's data model and submits the result, as the interrupt `resumeValue`
81
+ for `resume` or as the exchanged turn's data for `exchange`. With no `context` it
82
+ submits the whole data model at `/`. It MUST NOT submit anywhere else.
83
+
84
+ A host MUST NOT emit a surface whose evident purpose is credential collection.
85
+ Collected values become a `resumeValue` in the event log, where SR-1 redaction is
86
+ a backstop, not a licence.
87
+
88
+ ## The fold
89
+
90
+ A surface is identified by `(runId, surfaceId)`. Its state is the fold, in event
91
+ `sequence` order, of the `messages` of every version-2 `ui.a2ui-surface` envelope
92
+ the run recorded with that `surfaceId`, under A2UI v0.9 semantics:
93
+ `updateComponents` upserts components by `id`, `updateDataModel` replaces or
94
+ removes the value at `path`, and `deleteSurface` ends the surface.
95
+
96
+ The host MUST refuse, rather than record, an envelope that would make the fold
97
+ invalid, with `envelope_invalid`:
98
+
99
+ - the first envelope for a `surfaceId` does not begin with `createSurface`;
100
+ - `createSurface` is sent for a live `surfaceId`;
101
+ - any message follows `deleteSurface` without a new `createSurface`.
102
+
103
+ A consumer MUST NOT render the surface, or enable any action on it, until the
104
+ fold holds exactly one component with `id: "root"`. `partial: true` keeps its
105
+ per-envelope meaning; a surface's actions stay disabled until the envelope that
106
+ last touched it has finalized.
107
+
108
+ ## Replay and fork
109
+
110
+ Recorded surface envelopes are returned as recorded; no surface is regenerated.
111
+ A reader MUST keep accepting version-1 envelopes on replay, fork and poll for the
112
+ life of the major, including on a host whose floor is now 2: recorded envelopes
113
+ are read, not re-admitted through the envelope-kind catalog. A fork at `fromSeq`
114
+ folds only the envelopes in `[0, fromSeq)`.
115
+
116
+ ## Trust
117
+
118
+ If any envelope in a surface's fold carries `meta.contentTrust: "untrusted"`, the
119
+ whole surface is untrusted and the `untrusted_content_blocks_approval` rule
120
+ applies to every action on it: an `approval` interrupt it is bound to MUST NOT
121
+ advance. A later trusted `updateComponents` does not launder an earlier untrusted
122
+ one, and one untrusted update taints a surface a trusted node created. The SR-1
123
+ harness walks every message.
124
+
125
+ ## `deltaTransport` (deprecated)
126
+
127
+ `schemas/v2/a2ui-surface-delta-frame.schema.json` and the `deltaTransport` facet
128
+ are deprecated for major 2 (`spec/v1/deprecations.json`,
129
+ `openwop.deprecation.v2-a2ui-delta-frame` and `-delta-transport-facet`). A v2 host
130
+ SHOULD NOT advertise the facet: incremental updates are version-2 envelopes
131
+ carrying `updateComponents` / `updateDataModel`, recorded and replayable by the
132
+ fold. The rows carry `removeIn: "3.0"` until RFC 0197 is `Accepted`; removal then
133
+ follows its `v2-minor` path. v1's RFC 0114 stands.
29
134
 
30
135
  ## Conformance
31
136
 
32
- The current `claims-check` witness validates only that the discovery claim is
33
- well formed. It does not demonstrate compatible runtime behavior.
137
+ - `conformance/src/coherence/a2ui-v09-profile.test.ts` (corpus gate, no host): the
138
+ profile ⊂ upstream check, each excluded affordance refused, the pinned catalog,
139
+ the unchanged version-1 branch and the `ui.*`/`media.*` kind carve-out.
140
+ - `conformance/src/scenarios/v2-a2ui-v09-surface.test.ts` (major 2, seams-gated on
141
+ `POST /conformance/seams/sample/a2ui/emit-surface` in `api/seams-v2.yaml`):
142
+ version selects branch, fold guarded, catalog equality, legacy readable and
143
+ sticky taint. A host without the seam records `inapplicable`.
144
+ - No render before `root` is a renderer guarantee the server-oriented suite cannot
145
+ observe; it is witnessed by a reference-app client probe (`tier: reference-impl`).
146
+
147
+ The `claims-check` witness above is the discovery claim of `extensions.<org>.a2uiSurface`.
@@ -27,6 +27,11 @@ The v1 description,
27
27
  standalone v2 interoperability contract. A future revision can replace this
28
28
  boundary with normative behavior, schemas, and a behavioral witness.
29
29
 
30
+ For MCP access, the v1 `ctx.dataIntegration.fetchMCP` operation is superseded
31
+ by `ctx.mcp` ([`host-services.md`](../../core/host-services.md) §`mcp`, RFC 0204),
32
+ which returns MCP results unaltered. Retiring `fetchMCP` from an organization's
33
+ `dataIntegration` record is that organization's decision.
34
+
30
35
  ## Conformance
31
36
 
32
37
  The current `claims-check` witness validates only that the discovery claim is
@@ -40,6 +40,10 @@
40
40
  },
41
41
  "durableTasks": {
42
42
  "type": "boolean"
43
+ },
44
+ "agentCards": {
45
+ "const": true,
46
+ "description": "RFC 0202. Present ⇒ each inventory entry with an `a2aTenant` is published as an A2A 1.0 AgentCard through GetExtendedAgentCard with tenant = a2aTenant (interop.md §Per-agent cards). Requires the a2a-1.0 profile and agents.manifestRuntime. Omit when not offered (RFC 0192)."
43
47
  }
44
48
  },
45
49
  "required": [
@@ -42,6 +42,7 @@
42
42
  "enum": [
43
43
  "next-request",
44
44
  "exp-and-recheck",
45
+ "exp-only",
45
46
  "crl",
46
47
  "ocsp",
47
48
  "short-lived",
@@ -74,6 +75,29 @@
74
75
  ]
75
76
  }
76
77
  }
78
+ },
79
+ "$comment": "RFC 0210 §C — `exp-only` MUST NOT be advertised on `api-key` or `session`: there the host issued the credential itself, so revocation is in its own hands. The antecedent is the NEW member only, so no document that validates today can be invalidated by it. The full lane -> rule binding is deliberately NOT here (it would retroactively invalidate a committed bundle); it lives in the suite, and scripts/check-lane-revocation-rules.mjs keeps the table, this enum and the suite map in lockstep.",
80
+ "if": {
81
+ "properties": {
82
+ "revocation": {
83
+ "const": "exp-only"
84
+ }
85
+ },
86
+ "required": [
87
+ "revocation"
88
+ ]
89
+ },
90
+ "then": {
91
+ "properties": {
92
+ "lane": {
93
+ "not": {
94
+ "enum": [
95
+ "api-key",
96
+ "session"
97
+ ]
98
+ }
99
+ }
100
+ }
77
101
  }
78
102
  }
79
103
  },
@@ -70,6 +70,10 @@
70
70
  "maximum": 16
71
71
  }
72
72
  }
73
+ },
74
+ "client": {
75
+ "const": true,
76
+ "description": "RFC 0204. Present ⇒ the host exposes ctx.mcp.callTool / listTools / readResource / serverHealth to pack code (host-services.md §mcp). Omit when not offered (RFC 0192)."
73
77
  }
74
78
  },
75
79
  "required": [
@@ -0,0 +1,70 @@
1
+ {
2
+ "$comment": "RFC 0199 §C.1/§E.1 — oauth gains the credentialInterrupt facet (presence semantics, RFC 0192) and providers[] gains issuer + pkce. Hand-decided: grants/providers are otherwise the v1 seed.",
3
+ "properties": {
4
+ "grants": {
5
+ "type": "array",
6
+ "items": {
7
+ "type": "string",
8
+ "enum": [
9
+ "authorization_code",
10
+ "client_credentials",
11
+ "refresh_token"
12
+ ]
13
+ },
14
+ "uniqueItems": true,
15
+ "description": "OAuth 2.0 grant types the host performs on a node's behalf (oauth.md §Token lifecycle)."
16
+ },
17
+ "providers": {
18
+ "type": "array",
19
+ "description": "Provider catalog the host can acquire tokens for. A connector node's `auth.provider` MUST match an `id` here.",
20
+ "items": {
21
+ "type": "object",
22
+ "required": [
23
+ "id"
24
+ ],
25
+ "properties": {
26
+ "id": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "description": "Stable provider id, e.g. `slack`, `google`."
30
+ },
31
+ "authUrl": {
32
+ "type": "string",
33
+ "format": "uri",
34
+ "description": "Authorization endpoint."
35
+ },
36
+ "tokenUrl": {
37
+ "type": "string",
38
+ "format": "uri",
39
+ "description": "Token endpoint."
40
+ },
41
+ "scopesSupported": {
42
+ "type": "array",
43
+ "items": {
44
+ "type": "string"
45
+ },
46
+ "description": "Scopes this provider exposes."
47
+ },
48
+ "issuer": {
49
+ "type": "string",
50
+ "format": "uri",
51
+ "description": "RFC 0199 §A.4. The provider's authorization-server issuer identifier (RFC 8414 / RFC 9207). Absent ⇒ the host uses a provider-unique redirect URI (RFC 9700 §4.4.2.2)."
52
+ },
53
+ "pkce": {
54
+ "type": "string",
55
+ "enum": [
56
+ "S256",
57
+ "unsupported"
58
+ ],
59
+ "description": "RFC 0199 §A.1. Absent or `S256` ⇒ the host sends PKCE S256. `unsupported` ⇒ the host sends no PKCE for this provider; such a provider cannot back an MCP reach."
60
+ }
61
+ },
62
+ "additionalProperties": false
63
+ }
64
+ },
65
+ "credentialInterrupt": {
66
+ "const": true,
67
+ "description": "RFC 0199 §C.1 (oauth.md §The credential interrupt). Present ⇒ the host suspends a node on a `credential` interrupt instead of failing it when no credential resolves or refresh fails terminally. Absent ⇒ it fails the node with `connector_auth_expired`."
68
+ }
69
+ }
70
+ }
@@ -4,12 +4,17 @@
4
4
  "signatureAlgorithms": {
5
5
  "type": "array",
6
6
  "minItems": 1,
7
+ "contains": {
8
+ "const": "v1"
9
+ },
7
10
  "items": {
8
11
  "type": "string",
9
12
  "enum": [
10
- "v1"
13
+ "v1",
14
+ "standard-webhooks-1"
11
15
  ]
12
- }
16
+ },
17
+ "description": "RFC 0201 \u00a7A.3 \u2014 `v1` MUST be listed (schema-enforced by `contains`); `standard-webhooks-1` names the Standard Webhooks 1.0.0 companion scheme a subscriber opts into per subscription at registerWebhook."
13
18
  },
14
19
  "retryPolicy": {
15
20
  "type": "object",
@@ -55,6 +60,22 @@
55
60
  "description": "Ceiling the host clamps `limit` to (RFC 0182 \u00a7A.3 page-ceiling idiom)."
56
61
  }
57
62
  }
63
+ },
64
+ "secretRotation": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": [
68
+ "overlapSeconds"
69
+ ],
70
+ "description": "RFC 0201 \u00a7E \u2014 zero-downtime rotation for subscriptions opted into `standard-webhooks-1`; advertised only by a host serving `rotateWebhookSecret` (`POST /webhooks/{webhookId}/rotate-secret`). A host that does not advertise it answers that route `404 not_found`.",
71
+ "properties": {
72
+ "overlapSeconds": {
73
+ "type": "integer",
74
+ "minimum": 60,
75
+ "maximum": 604800,
76
+ "description": "How long after a rotation `webhook-signature` carries an entry under the previous secret beside the new one; `previousSecretExpiresAt = rotatedAt + overlapSeconds`."
77
+ }
78
+ }
58
79
  }
59
80
  },
60
81
  "required": [
@@ -59,6 +59,7 @@
59
59
  "artifactId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
60
60
  "auditCorrelationId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
61
61
  "callId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
62
+ "catalogId": "an A2UI v0.9 catalog URI (RFC 0209 §A.2), pinned by enum in ui.a2ui-surface $defs/catalogId — not an openwop id",
62
63
  "causationHostId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
63
64
  "changeId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
64
65
  "changelogId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
@@ -99,6 +100,7 @@
99
100
  "speakerId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
100
101
  "stepId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
101
102
  "suiteId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
103
+ "surfaceId": "an A2UI v0.9 surface id, scoped to (runId, surfaceId) by RFC 0209 §C.9; grammar in ui.a2ui-surface $defs/surfaceId — not an openwop id",
102
104
  "taskId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
103
105
  "toolId": "no openwop id kind governs this surface; the grammar is the owning schema's own",
104
106
  "workerId": "no openwop id kind governs this surface; the grammar is the owning schema's own"