@openwop/spec-artifacts 2.35.1 → 2.36.1
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/CORPUS-STAMP.json +103 -89
- package/api/openapi.yaml +325 -4
- package/api/seams-v2.yaml +342 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +564 -8
- package/package.json +1 -1
- package/schemas/a2a-task-state.schema.json +3 -3
- package/schemas/artifact-type-pack-manifest.schema.json +3 -3
- package/schemas/capabilities.schema.json +34 -1
- package/schemas/connection-pack-manifest.schema.json +14 -0
- package/schemas/debug-bundle.schema.json +20 -0
- package/schemas/dispatch-config.schema.json +1 -1
- package/schemas/localized-content-language-settings.schema.json +3 -3
- package/schemas/localized-content-page.schema.json +2 -2
- package/schemas/localized-content-section.schema.json +3 -3
- package/schemas/run-event-payloads.schema.json +4 -2
- package/schemas/suspend-request.schema.json +61 -4
- package/schemas/v2/a2a-task-state.schema.json +10 -9
- package/schemas/v2/agent-deployment-transition.schema.json +4 -4
- package/schemas/v2/agent-deployment.schema.json +7 -7
- package/schemas/v2/agent-eval-suite.schema.json +10 -10
- package/schemas/v2/agent-inventory-response.schema.json +8 -2
- package/schemas/v2/artifact-type-pack-manifest.schema.json +3 -3
- package/schemas/v2/artifact.schema.json +84 -0
- package/schemas/v2/capabilities.schema.json +82 -8
- package/schemas/v2/certification-bundle.schema.json +1 -1
- package/schemas/v2/channel-presence-payload.schema.json +3 -3
- package/schemas/v2/connection-pack-manifest.schema.json +14 -0
- package/schemas/v2/conversation-event.schema.json +9 -2
- package/schemas/v2/conversation-turn.schema.json +19 -12
- package/schemas/v2/dispatch-config.schema.json +1 -1
- package/schemas/v2/envelopes/ui.a2ui-surface.schema.json +920 -22
- package/schemas/v2/error-envelope.schema.json +11 -1
- package/schemas/v2/eval-summary.schema.json +1 -2
- package/schemas/v2/goal.schema.json +4 -4
- package/schemas/v2/localized-content-language-settings.schema.json +3 -3
- package/schemas/v2/localized-content-page.schema.json +2 -2
- package/schemas/v2/localized-content-section.schema.json +3 -3
- package/schemas/v2/node-pack-manifest.schema.json +105 -0
- package/schemas/v2/part.schema.json +81 -0
- package/schemas/v2/proposal.schema.json +6 -6
- package/schemas/v2/run-event-payloads.schema.json +5 -3
- package/schemas/v2/self-hosted-runner-dispatch-frame.schema.json +2 -2
- package/schemas/v2/self-hosted-runner-result-frame.schema.json +1 -1
- package/schemas/v2/suspend-request.schema.json +251 -6
- package/schemas/v2/tool-descriptor.schema.json +246 -2
- package/schemas/v2/trigger-event.schema.json +1 -2
- package/schemas/v2/trigger-subscription.schema.json +1 -2
- package/schemas/v2/webhook-verification.schema.json +22 -0
- package/schemas/v2/workflow-definition.schema.json +25 -25
- package/spec/v1/alias-detectors.json +13 -1
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/deprecations.json +45 -1
- package/spec/v1/deprecations.schema.json +119 -4
- package/spec/v1/gaps.json +1925 -4
- package/spec/v2/README.md +5 -2
- package/spec/v2/core/capabilities.md +13 -26
- package/spec/v2/core/conformance.md +5 -8
- package/spec/v2/core/connection-packs.md +1 -1
- package/spec/v2/core/conversation.md +1 -1
- package/spec/v2/core/errors.md +8 -3
- package/spec/v2/core/events.md +8 -20
- package/spec/v2/core/form-content-packs.md +2 -2
- package/spec/v2/core/headers.md +5 -4
- package/spec/v2/core/host-services.md +6 -2
- package/spec/v2/core/idempotency.md +1 -1
- package/spec/v2/core/identity.md +23 -12
- package/spec/v2/core/interop.md +34 -4
- package/spec/v2/core/interrupt.md +6 -3
- package/spec/v2/core/node-pack-runtimes.md +20 -0
- package/spec/v2/core/oauth.md +32 -0
- package/spec/v2/core/overview.md +19 -6
- package/spec/v2/core/packs.md +4 -6
- package/spec/v2/core/persistence.md +20 -55
- package/spec/v2/core/replay.md +5 -11
- package/spec/v2/core/runs.md +9 -8
- package/spec/v2/core/security-defaults.md +18 -20
- package/spec/v2/core/tool-catalog.md +22 -0
- package/spec/v2/core/versioning.md +10 -28
- package/spec/v2/core/webhooks.md +16 -4
- package/spec/v2/core/workflow-chain-packs.md +1 -1
- package/spec/v2/corrections.json +32 -0
- package/spec/v2/corrections.schema.json +49 -0
- package/spec/v2/declaration.json +18 -13
- package/spec/v2/declaration.schema.json +3 -1
- package/spec/v2/errors.json +46 -1
- package/spec/v2/ext/a2uiSurface/README.md +131 -17
- package/spec/v2/ext/dataIntegration/README.md +5 -0
- package/spec/v2/facets/a2a.schema.json +4 -0
- package/spec/v2/facets/auth.schema.json +24 -0
- package/spec/v2/facets/mcp.schema.json +4 -0
- package/spec/v2/facets/oauth.schema.json +70 -0
- package/spec/v2/facets/webhooks.schema.json +23 -2
- package/spec/v2/id-field-bindings.json +2 -0
- package/spec/v2/interop-map.json +639 -0
- package/spec/v2/interop-map.schema.json +458 -0
- package/spec/v2/migrations.json +7 -0
- package/spec/v2/migrations.schema.json +58 -0
- package/spec/v2/path-manifest.json +6 -1
- package/spec/v2/release.json +3 -3
- package/spec/v2/surface-baseline.json +7981 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://openwop.dev/spec/v2/agent-eval-suite.schema.json",
|
|
4
4
|
"title": "AgentEvalSuite",
|
|
5
|
-
"description": "RFC 0081
|
|
5
|
+
"description": "RFC 0081 §A. A portable, host-agnostic evaluation suite for a manifest agent (RFC 0003/0070): the tasks, the expected outputs or rubrics, the deterministic tool/memory fixtures, the allowed model classes, and the pass/fail thresholds that answer \"is this agent good enough to deploy?\". Distributed inside a pack tarball and referenced by URI exactly like `systemPromptRef` / `handoff.*SchemaRef` (RFC 0003 §C/§D) — NOT embedded in `AgentManifest`. A host advertising `capabilities.agents.evalSuite.supported: true` executes a suite as an eval run (a `mode: \"eval\"` projection over `POST /runs`, RFC 0081 §B) and terminates with an `eval-summary.schema.json` scorecard. The suite carries NO secret material and NO host-internal identifiers (it is authored offline and shipped in a signed pack).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": [
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"version": {
|
|
21
21
|
"type": "string",
|
|
22
22
|
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
23
|
-
"description": "SemVer of the suite. A suite version is pinned on an eval run (carried on `eval.started.suiteVersion` and `eval-summary.suiteVersion`) so a regression comparison (
|
|
23
|
+
"description": "SemVer of the suite. A suite version is pinned on an eval run (carried on `eval.started.suiteVersion` and `eval-summary.suiteVersion`) so a regression comparison (§D `regression` mode) is between like versions."
|
|
24
24
|
},
|
|
25
25
|
"targetAgentId": {
|
|
26
26
|
"$ref": "ids.schema.json#/$defs/agentId",
|
|
27
|
-
"description": "MAY. The `AgentManifest.id` this suite is authored for. Absent
|
|
27
|
+
"description": "MAY. The `AgentManifest.id` this suite is authored for. Absent ⇒ the suite is agent-agnostic and MAY be pointed at any `agentId` at run time (the run request carries the `agentId`). When present, a host SHOULD reject an eval run whose target `agentId` differs, unless the caller explicitly overrides."
|
|
28
28
|
},
|
|
29
29
|
"modes": {
|
|
30
30
|
"type": "array",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"live-shadow"
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
|
-
"description": "The eval modes this suite exercises (RFC 0081
|
|
43
|
+
"description": "The eval modes this suite exercises (RFC 0081 §D closed vocabulary). `golden`: exact / contains / json-match against each task's `expected`. `rubric`: a host-chosen judge scores against weighted criteria (nondeterministic — a recorded-fact score). `adversarial`: tasks probe for unsafe / jailbreak behavior; `safetyFindings` is the primary output. `regression`: re-run against a new agent/model/prompt version and diff scores vs a `baselineRunId` (composes RFC 0054 `:diff`). `live-shadow`: run against LIVE tools/memory instead of `fixtures` — the only mode that bypasses fixture injection; explicitly nondeterministic. A run MUST request only modes the suite declares here AND the host advertises (`capabilities.agents.evalSuite.modes`); an unadvertised mode is rejected at run-create with `400 validation_error`."
|
|
44
44
|
},
|
|
45
45
|
"allowedModels": {
|
|
46
46
|
"type": "array",
|
|
@@ -56,18 +56,18 @@
|
|
|
56
56
|
"general"
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
|
-
"description": "MAY. The `AgentManifest.modelClass` values (RFC 0002) the suite is valid for. Absent
|
|
59
|
+
"description": "MAY. The `AgentManifest.modelClass` values (RFC 0002) the suite is valid for. Absent ⇒ valid for any class. A host SHOULD record the `evaluatedModelClass` on the summary so a score is interpreted against the model it was produced with."
|
|
60
60
|
},
|
|
61
61
|
"thresholds": {
|
|
62
62
|
"type": "object",
|
|
63
63
|
"additionalProperties": false,
|
|
64
|
-
"description": "MAY. The pass/fail bar for the suite. A task or the aggregate `passed` flag is computed against these. Absent
|
|
64
|
+
"description": "MAY. The pass/fail bar for the suite. A task or the aggregate `passed` flag is computed against these. Absent ⇒ the host's default bar (the summary still carries raw scores).",
|
|
65
65
|
"properties": {
|
|
66
66
|
"passScore": {
|
|
67
67
|
"type": "number",
|
|
68
68
|
"minimum": 0,
|
|
69
69
|
"maximum": 1,
|
|
70
|
-
"description": "The minimum aggregate score (0.0
|
|
70
|
+
"description": "The minimum aggregate score (0.0–1.0) for `EvalSummary.passed: true`."
|
|
71
71
|
},
|
|
72
72
|
"maxCostUsd": {
|
|
73
73
|
"type": "number",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"description": "Suite-unique task identifier (kebab-case). Carried verbatim on `eval.scored.taskId` and the per-task summary entry."
|
|
101
101
|
},
|
|
102
102
|
"input": {
|
|
103
|
-
"description": "The run input for the task, validated against the agent's input schema by the host. An opaque object/value
|
|
103
|
+
"description": "The run input for the task, validated against the agent's input schema by the host. An opaque object/value — content is task-defined."
|
|
104
104
|
},
|
|
105
105
|
"expected": {
|
|
106
106
|
"type": "object",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"rubric": {
|
|
145
145
|
"type": "array",
|
|
146
146
|
"minItems": 1,
|
|
147
|
-
"description": "Present when `kind: \"rubric\"`. Weighted criteria a judge scores the output against; the task score is the weighted sum of met criteria, normalized to 0.0
|
|
147
|
+
"description": "Present when `kind: \"rubric\"`. Weighted criteria a judge scores the output against; the task score is the weighted sum of met criteria, normalized to 0.0–1.0. Judge selection + scoring is host-internal (nondeterministic — the score is a recorded fact).",
|
|
148
148
|
"items": {
|
|
149
149
|
"type": "object",
|
|
150
150
|
"additionalProperties": false,
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
"fixtures": {
|
|
173
173
|
"type": "object",
|
|
174
174
|
"additionalProperties": false,
|
|
175
|
-
"description": "MAY. Deterministic substitutes for live tool/memory I/O so a `golden`/`regression` eval is reproducible. When present, the eval host MUST inject `toolResponses` in place of live tool calls and seed `memorySeed` before the invocation. The `live-shadow` mode is the explicit exception
|
|
175
|
+
"description": "MAY. Deterministic substitutes for live tool/memory I/O so a `golden`/`regression` eval is reproducible. When present, the eval host MUST inject `toolResponses` in place of live tool calls and seed `memorySeed` before the invocation. The `live-shadow` mode is the explicit exception — it ignores `fixtures` and runs against live tools/memory.",
|
|
176
176
|
"properties": {
|
|
177
177
|
"toolResponses": {
|
|
178
178
|
"type": "array",
|
|
@@ -164,9 +164,15 @@
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
+
},
|
|
168
|
+
"a2aTenant": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"minLength": 1,
|
|
171
|
+
"maxLength": 128,
|
|
172
|
+
"pattern": "^[A-Za-z0-9._~-]+$",
|
|
173
|
+
"description": "RFC 0202. Opaque A2A routing value for this agent: the `tenant` of its AgentInterface entries and of GetExtendedAgentCard. Stable for the agent and host version; encodes no tenant, workspace or principal. Present only when the host advertises a2a.agentCards and routes at least one workflow to the agent. Path-segment-safe because the A2A HTTP+JSON binding carries it as `/{tenant}/…`."
|
|
167
174
|
}
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
|
-
}
|
|
171
|
-
"x-openwop-seeded-from": "v1"
|
|
177
|
+
}
|
|
172
178
|
}
|
|
@@ -146,11 +146,11 @@
|
|
|
146
146
|
"items": {
|
|
147
147
|
"type": "string",
|
|
148
148
|
"minLength": 1,
|
|
149
|
-
"maxLength":
|
|
150
|
-
"pattern": "^([a-z][a-z0-9]*|vendor\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*|x-[a-z][a-z0-9-]
|
|
149
|
+
"maxLength": 255,
|
|
150
|
+
"pattern": "^([a-z][a-z0-9]*|vendor\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*|x-[a-z][a-z0-9-]*|[a-z0-9][a-z0-9!#$&^_.+-]{0,126}/[a-z0-9][a-z0-9!#$&^_.+-]{0,126})$"
|
|
151
151
|
},
|
|
152
152
|
"uniqueItems": true,
|
|
153
|
-
"description": "Export-format identifiers (hints) a renderer MAY offer. Spec-reserved core identifiers carry interoperable meaning (the lowercase file-extension / common name): `pdf`, `pptx`, `docx`, `xlsx`, `md`, `html`, `txt`, `csv`, `json`, `png`, `svg`, `jpeg`, `step`, `stl`, `dxf`. Domain-specific formats outside the core set MUST be `vendor.<org>.<format>`- or `x-<format>`-prefixed (mirrors the `requiredModelCapabilities` reserved-core + extension idiom). Advisory: this spec assigns no byte-level production semantics to any identifier \u2014 it standardizes the identifier so two hosts agree what `pptx` names, not how the bytes are produced."
|
|
153
|
+
"description": "Export-format identifiers (hints) a renderer MAY offer. Spec-reserved core identifiers carry interoperable meaning (the lowercase file-extension / common name): `pdf`, `pptx`, `docx`, `xlsx`, `md`, `html`, `txt`, `csv`, `json`, `png`, `svg`, `jpeg`, `step`, `stl`, `dxf`. Domain-specific formats outside the core set MUST be `vendor.<org>.<format>`- or `x-<format>`-prefixed (mirrors the `requiredModelCapabilities` reserved-core + extension idiom). An entry MAY instead be a lowercase RFC 6838 media type (`type/subtype`, no parameters; RFC 0205 §C); each reserved alias names exactly one media type per artifact-type-packs.md §\"Export-format aliases\", and a consumer MUST treat the two spellings as one format. Advisory: this spec assigns no byte-level production semantics to any identifier \u2014 it standardizes the identifier so two hosts agree what `pptx` names, not how the bytes are produced."
|
|
154
154
|
},
|
|
155
155
|
"syncOn": {
|
|
156
156
|
"type": "string",
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/artifact.schema.json",
|
|
4
|
+
"title": "Artifact",
|
|
5
|
+
"description": "RFC 0205 §A/§D. An A2A v1.0.1 `Artifact`, transcribed from `specification/a2a.proto` `message Artifact` at tag v1.0.1 (camelCase per A2A spec §5.5). The body of `getArtifact` when it is served as `application/a2a+json` (spec/v2/core/runs.md); `artifactId` equals the path segment. The same shape a2a-integration.md D.3 projects over A2A, so one decoder reads both.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"artifactId",
|
|
10
|
+
"parts"
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"artifactId": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"description": "a2a.proto: \"Unique identifier (e.g. UUID) for the artifact. It must be unique within a task.\" On `getArtifact` it MUST equal the `{artifactId}` path segment."
|
|
17
|
+
},
|
|
18
|
+
"name": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "a2a.proto: \"A human readable name for the artifact.\""
|
|
21
|
+
},
|
|
22
|
+
"description": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "a2a.proto: \"Optional. A human readable description of the artifact.\""
|
|
25
|
+
},
|
|
26
|
+
"parts": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"items": {
|
|
30
|
+
"$ref": "part.schema.json"
|
|
31
|
+
},
|
|
32
|
+
"description": "a2a.proto: \"The content of the artifact. Must contain at least one part.\" A registered artifact's JSON payload is a `data` Part with `mediaType: application/json`."
|
|
33
|
+
},
|
|
34
|
+
"metadata": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"description": "a2a.proto: \"Optional. Metadata included with the artifact.\" OpenWOP identity for a registered type SHOULD be carried as `metadata.openwop.artifactTypeId` and `metadata.openwop.schemaVersion` (RFC 0205 §A.2).",
|
|
37
|
+
"properties": {
|
|
38
|
+
"openwop": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"properties": {
|
|
41
|
+
"artifactTypeId": {
|
|
42
|
+
"$ref": "ids.schema.json#/$defs/typeId",
|
|
43
|
+
"description": "The registered artifact type (`artifact.created.artifactType`), bound to the `typeId` kind (identity.md §5)."
|
|
44
|
+
},
|
|
45
|
+
"schemaVersion": {
|
|
46
|
+
"type": "integer",
|
|
47
|
+
"minimum": 0
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"additionalProperties": {}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"additionalProperties": {}
|
|
54
|
+
},
|
|
55
|
+
"extensions": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"items": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"format": "uri"
|
|
60
|
+
},
|
|
61
|
+
"description": "a2a.proto: \"The URIs of extensions that are present or contributed to this Artifact.\""
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"examples": [
|
|
65
|
+
{
|
|
66
|
+
"artifactId": "art-1",
|
|
67
|
+
"name": "Launch brief",
|
|
68
|
+
"parts": [
|
|
69
|
+
{
|
|
70
|
+
"data": {
|
|
71
|
+
"title": "Q3 launch"
|
|
72
|
+
},
|
|
73
|
+
"mediaType": "application/json"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"metadata": {
|
|
77
|
+
"openwop": {
|
|
78
|
+
"artifactTypeId": "vendor.acme.brief",
|
|
79
|
+
"schemaVersion": 1
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"implementation": {
|
|
41
41
|
"type": "object",
|
|
42
|
-
"
|
|
42
|
+
"additionalProperties": false,
|
|
43
|
+
"description": "RFC 0208 §G — self-reported server identity; informational (capabilities.md §3.1): a client SHOULD NOT change behaviour because of it or authorize from it.",
|
|
43
44
|
"properties": {
|
|
44
45
|
"name": {
|
|
45
46
|
"type": "string"
|
|
@@ -49,10 +50,13 @@
|
|
|
49
50
|
},
|
|
50
51
|
"vendor": {
|
|
51
52
|
"type": "string"
|
|
53
|
+
},
|
|
54
|
+
"url": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"format": "uri",
|
|
57
|
+
"description": "The operator's site — A2A AgentProvider.url, MCP Implementation.websiteUrl. Informational."
|
|
52
58
|
}
|
|
53
|
-
}
|
|
54
|
-
"additionalProperties": false,
|
|
55
|
-
"x-openwop-seeded-from": "v1"
|
|
59
|
+
}
|
|
56
60
|
},
|
|
57
61
|
"engineVersion": {
|
|
58
62
|
"type": "integer",
|
|
@@ -2071,7 +2075,7 @@
|
|
|
2071
2075
|
]
|
|
2072
2076
|
},
|
|
2073
2077
|
"uniqueItems": true,
|
|
2074
|
-
"description": "OAuth 2.0 grant types the host performs on a node's behalf."
|
|
2078
|
+
"description": "OAuth 2.0 grant types the host performs on a node's behalf (oauth.md §Token lifecycle)."
|
|
2075
2079
|
},
|
|
2076
2080
|
"providers": {
|
|
2077
2081
|
"type": "array",
|
|
@@ -2103,10 +2107,27 @@
|
|
|
2103
2107
|
"type": "string"
|
|
2104
2108
|
},
|
|
2105
2109
|
"description": "Scopes this provider exposes."
|
|
2110
|
+
},
|
|
2111
|
+
"issuer": {
|
|
2112
|
+
"type": "string",
|
|
2113
|
+
"format": "uri",
|
|
2114
|
+
"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)."
|
|
2115
|
+
},
|
|
2116
|
+
"pkce": {
|
|
2117
|
+
"type": "string",
|
|
2118
|
+
"enum": [
|
|
2119
|
+
"S256",
|
|
2120
|
+
"unsupported"
|
|
2121
|
+
],
|
|
2122
|
+
"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."
|
|
2106
2123
|
}
|
|
2107
2124
|
},
|
|
2108
2125
|
"additionalProperties": false
|
|
2109
2126
|
}
|
|
2127
|
+
},
|
|
2128
|
+
"credentialInterrupt": {
|
|
2129
|
+
"const": true,
|
|
2130
|
+
"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`."
|
|
2110
2131
|
}
|
|
2111
2132
|
},
|
|
2112
2133
|
"allOf": [
|
|
@@ -2145,7 +2166,7 @@
|
|
|
2145
2166
|
}
|
|
2146
2167
|
],
|
|
2147
2168
|
"description": "core/capabilities.md#oauth — witness: witnessable-gated; maturity experimental/none; RFC 0047",
|
|
2148
|
-
"x-openwop-
|
|
2169
|
+
"x-openwop-facets-from": "spec/v2/facets/oauth.schema.json"
|
|
2149
2170
|
},
|
|
2150
2171
|
"authorization": {
|
|
2151
2172
|
"type": "object",
|
|
@@ -5280,12 +5301,17 @@
|
|
|
5280
5301
|
"signatureAlgorithms": {
|
|
5281
5302
|
"type": "array",
|
|
5282
5303
|
"minItems": 1,
|
|
5304
|
+
"contains": {
|
|
5305
|
+
"const": "v1"
|
|
5306
|
+
},
|
|
5283
5307
|
"items": {
|
|
5284
5308
|
"type": "string",
|
|
5285
5309
|
"enum": [
|
|
5286
|
-
"v1"
|
|
5310
|
+
"v1",
|
|
5311
|
+
"standard-webhooks-1"
|
|
5287
5312
|
]
|
|
5288
|
-
}
|
|
5313
|
+
},
|
|
5314
|
+
"description": "RFC 0201 §A.3 — `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."
|
|
5289
5315
|
},
|
|
5290
5316
|
"retryPolicy": {
|
|
5291
5317
|
"type": "object",
|
|
@@ -5331,6 +5357,22 @@
|
|
|
5331
5357
|
"description": "Ceiling the host clamps `limit` to (RFC 0182 §A.3 page-ceiling idiom)."
|
|
5332
5358
|
}
|
|
5333
5359
|
}
|
|
5360
|
+
},
|
|
5361
|
+
"secretRotation": {
|
|
5362
|
+
"type": "object",
|
|
5363
|
+
"additionalProperties": false,
|
|
5364
|
+
"required": [
|
|
5365
|
+
"overlapSeconds"
|
|
5366
|
+
],
|
|
5367
|
+
"description": "RFC 0201 §E — 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`.",
|
|
5368
|
+
"properties": {
|
|
5369
|
+
"overlapSeconds": {
|
|
5370
|
+
"type": "integer",
|
|
5371
|
+
"minimum": 60,
|
|
5372
|
+
"maximum": 604800,
|
|
5373
|
+
"description": "How long after a rotation `webhook-signature` carries an entry under the previous secret beside the new one; `previousSecretExpiresAt = rotatedAt + overlapSeconds`."
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5334
5376
|
}
|
|
5335
5377
|
},
|
|
5336
5378
|
"allOf": [
|
|
@@ -5621,6 +5663,10 @@
|
|
|
5621
5663
|
},
|
|
5622
5664
|
"durableTasks": {
|
|
5623
5665
|
"type": "boolean"
|
|
5666
|
+
},
|
|
5667
|
+
"agentCards": {
|
|
5668
|
+
"const": true,
|
|
5669
|
+
"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)."
|
|
5624
5670
|
}
|
|
5625
5671
|
},
|
|
5626
5672
|
"allOf": [
|
|
@@ -6902,6 +6948,10 @@
|
|
|
6902
6948
|
"maximum": 16
|
|
6903
6949
|
}
|
|
6904
6950
|
}
|
|
6951
|
+
},
|
|
6952
|
+
"client": {
|
|
6953
|
+
"const": true,
|
|
6954
|
+
"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)."
|
|
6905
6955
|
}
|
|
6906
6956
|
},
|
|
6907
6957
|
"allOf": [
|
|
@@ -7523,6 +7573,7 @@
|
|
|
7523
7573
|
"enum": [
|
|
7524
7574
|
"next-request",
|
|
7525
7575
|
"exp-and-recheck",
|
|
7576
|
+
"exp-only",
|
|
7526
7577
|
"crl",
|
|
7527
7578
|
"ocsp",
|
|
7528
7579
|
"short-lived",
|
|
@@ -7555,6 +7606,29 @@
|
|
|
7555
7606
|
]
|
|
7556
7607
|
}
|
|
7557
7608
|
}
|
|
7609
|
+
},
|
|
7610
|
+
"$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.",
|
|
7611
|
+
"if": {
|
|
7612
|
+
"properties": {
|
|
7613
|
+
"revocation": {
|
|
7614
|
+
"const": "exp-only"
|
|
7615
|
+
}
|
|
7616
|
+
},
|
|
7617
|
+
"required": [
|
|
7618
|
+
"revocation"
|
|
7619
|
+
]
|
|
7620
|
+
},
|
|
7621
|
+
"then": {
|
|
7622
|
+
"properties": {
|
|
7623
|
+
"lane": {
|
|
7624
|
+
"not": {
|
|
7625
|
+
"enum": [
|
|
7626
|
+
"api-key",
|
|
7627
|
+
"session"
|
|
7628
|
+
]
|
|
7629
|
+
}
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7558
7632
|
}
|
|
7559
7633
|
}
|
|
7560
7634
|
},
|
|
@@ -259,7 +259,7 @@
|
|
|
259
259
|
"properties": {
|
|
260
260
|
"id": {
|
|
261
261
|
"type": "string",
|
|
262
|
-
"pattern": "^openwop\\.(?!it\\.(?:artifact-schema-compile-bounded|artifact-type-legacy-ids|capability-example-root-layout|certification-floor-enforcement|chain-subchain-unsupported-refused|compensation-profile|core-manifest-and-extension-registry|discovery-canonical-family-no-shadow|edge-condition-truthy-falsy|effect-identity-composition|effect-identity-cross-scope|error-envelope-canonical-shape|event-codemap-complete|form-content-packs|multi-region-effect-vocabulary|normative-example-extraction|openapi-asyncapi-sdk-parity|pack-manifest-extensions|protocol-version-grammar|registry-declarative-kinds|rfc-0147-self-audit|rfc-lifecycle-coherence|semantic-digest-v2|spec-corpus-validity|spec-section-citations|tool-result-trust-monotone|v2-alias-covers-reword|v2-bundle-signature-attributable|v2-corpus-tag-pinned|v2-declaration-parity|v2-envelope-catalog|v2-eos-clock|v2-error-registry-prose-parity|v2-event-naming-rule|v2-events-channel-parity|v2-externally-gated-never-stable|v2-facet-advertisement|v2-front-door-counts|v2-id-kinds-bound|v2-normative-home-gate|v2-one-signing-scheme|v2-path-parity|v2-release-identity|v2-req-only-assertions|v2-retention-floors|v2-seams-not-in-canonical|v2-security-defaults-table|v2-spec-artifacts-digest|v2-threat-model-template|v2-umbrella-alias-covered|v2-umbrella-child-parts|v2-umbrella-codemod-at-active|v2-umbrella-codemod-legs|v2-umbrella-migration-deprecation|v2-witness-required|versioned-composition-profiles|workflow-chain-internal-flag|workload-identity-profile)\\.)(requirement|it|scenario|floor|profile|family)\\.[a-z0-9]",
|
|
262
|
+
"pattern": "^openwop\\.(?!it\\.(?:a2a-parts-schemas|a2ui-v09-profile|artifact-schema-compile-bounded|artifact-type-legacy-ids|bundle-maturity-gate|capability-example-root-layout|certification-floor-enforcement|chain-subchain-unsupported-refused|compensation-profile|core-manifest-and-extension-registry|discovery-canonical-family-no-shadow|edge-condition-truthy-falsy|effect-identity-composition|effect-identity-cross-scope|error-envelope-canonical-shape|event-codemap-complete|form-content-packs|locale-key-grammar|multi-region-effect-vocabulary|node-pack-mcp-server-record|normative-example-extraction|openapi-asyncapi-sdk-parity|openapi-security-declared|pack-manifest-extensions|protocol-version-grammar|registry-declarative-kinds|removal-dates-minor|rfc-0147-self-audit|rfc-lifecycle-coherence|semantic-digest-v2|spec-corpus-validity|spec-section-citations|tool-descriptor-annotations|tool-result-trust-monotone|v2-alias-covers-reword|v2-bundle-signature-attributable|v2-corpus-tag-pinned|v2-declaration-parity|v2-envelope-catalog|v2-eos-clock|v2-error-registry-prose-parity|v2-event-naming-rule|v2-events-channel-parity|v2-externally-gated-never-stable|v2-facet-advertisement|v2-front-door-counts|v2-id-kinds-bound|v2-interop-map-coherent|v2-lane-exp-only-schema|v2-normative-home-gate|v2-one-signing-scheme|v2-path-parity|v2-release-identity|v2-req-only-assertions|v2-retention-floors|v2-retirement-gate|v2-seams-not-in-canonical|v2-security-defaults-table|v2-spec-artifacts-digest|v2-surface-monotone-gate|v2-threat-model-template|v2-umbrella-alias-covered|v2-umbrella-child-parts|v2-umbrella-codemod-at-active|v2-umbrella-codemod-legs|v2-umbrella-migration-deprecation|v2-witness-required|versioned-composition-profiles|workflow-chain-internal-flag|workload-identity-profile)\\.)(requirement|it|scenario|floor|profile|family)\\.[a-z0-9]",
|
|
263
263
|
"description": "RFC 0168 §A.1 — `openwop.<area>.<slug>`. The suite mints six areas: `requirement` (an explicit `req()` id), `it` (a per-test id from the scenario file and title), `scenario` and `floor` (per-file rows), `profile` (a claimed-profile row) and `family` (a capability gate). The lookahead refuses every id minted from a corpus-coherence file: those run in the spec repo’s CI and MUST NOT appear in a host bundle (conformance.md §\"Two products, two ledgers\"; RFC 0168 §D.1). `scripts/check-req-only.mjs` fails when the list drifts from `conformance/src/coherence/`."
|
|
264
264
|
},
|
|
265
265
|
"scenario": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://openwop.dev/spec/v2/channel-presence-payload.schema.json",
|
|
4
4
|
"title": "ChannelPresencePayload",
|
|
5
|
-
"description": "Payload of the OPTIONAL `channel.presence` RunEvent (RFC 0110). EPHEMERAL live presence for a `type:'channel'` conversation
|
|
5
|
+
"description": "Payload of the OPTIONAL `channel.presence` RunEvent (RFC 0110). EPHEMERAL live presence for a `type:'channel'` conversation — who is currently present + (optionally) who is typing. A host MUST NOT persist this event to the replayable event log / transcript, and it MUST NOT affect replay or `:fork` determinism (presence is live state, the load-bearing distinction from the persisted `conversation.exchanged` turn — see replay.md). Membership-gated: every ref MUST be a current channel participant and the event MUST NOT be delivered to a non-member (the same DEFAULT-DENY visibility as the channel's messages; cross-tenant delivery is forbidden, CTI-1). NON-PII: subject refs are the opaque RFC 0041 vocabulary only — no IP/location/device. A host MAY emit; if it advertises `channelPresence.supported` it MUST. Gated on `channelPresence.supported` (capabilities.schema.json). See RFC 0110.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": [
|
|
8
8
|
"conversationId",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"present": {
|
|
20
20
|
"type": "array",
|
|
21
|
-
"description": "Subject refs (RFC 0041 vocabulary `user:<id>` / `agent:<id>`
|
|
21
|
+
"description": "Subject refs (RFC 0041 vocabulary `user:<id>` / `agent:<id>` — opaque, non-PII) of members CURRENTLY present in the channel. MUST be a subset of the channel's current participants; a non-member MUST NOT appear.",
|
|
22
22
|
"items": {
|
|
23
23
|
"type": "string",
|
|
24
24
|
"minLength": 1,
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
]
|
|
54
54
|
}
|
|
55
55
|
],
|
|
56
|
-
"$comment": "RFC 0110 NEGATIVE (not validatable as an examples[] entry, which must be VALID): a payload carrying any field beyond conversationId/present/typing (e.g. `ip`, `location`) MUST FAIL validation via `additionalProperties: false`
|
|
56
|
+
"$comment": "RFC 0110 NEGATIVE (not validatable as an examples[] entry, which must be VALID): a payload carrying any field beyond conversationId/present/typing (e.g. `ip`, `location`) MUST FAIL validation via `additionalProperties: false` — the no-PII guard; see conformance/src/scenarios/channel-presence-shape.test.ts.",
|
|
57
57
|
"x-openwop-seeded-from": "v1"
|
|
58
58
|
}
|
|
@@ -218,6 +218,20 @@
|
|
|
218
218
|
"instanceUrlTemplate": {
|
|
219
219
|
"type": "string",
|
|
220
220
|
"description": "For per-account-host providers (Snowflake/NetSuite/ServiceNow): a template the host fills per connection, e.g. `https://{account}.snowflakecomputing.com`. Its presence signals the provider cannot use a single global OAuth app."
|
|
221
|
+
},
|
|
222
|
+
"issuer": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"format": "uri",
|
|
225
|
+
"pattern": "^https://",
|
|
226
|
+
"description": "RFC 0199 §A.4/§B.3. The authorization server's issuer identifier. Fixed and manifest-declared, like `endpoints`. OPTIONAL in the schema; a host MUST NOT authorize a `reach.mcp` + `oauth2` provider whose manifest omits it (refused `connection_auth_metadata_mismatch` before any authorization URL is issued)."
|
|
227
|
+
},
|
|
228
|
+
"pkce": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"enum": [
|
|
231
|
+
"S256",
|
|
232
|
+
"unsupported"
|
|
233
|
+
],
|
|
234
|
+
"description": "RFC 0199 §A.1. Absent or `S256` ⇒ the host sends PKCE S256. `unsupported` ⇒ no PKCE; a host MUST NOT authorize such a provider when it is reached as an MCP server (§B.2)."
|
|
221
235
|
}
|
|
222
236
|
}
|
|
223
237
|
},
|
|
@@ -72,6 +72,14 @@
|
|
|
72
72
|
"null"
|
|
73
73
|
]
|
|
74
74
|
},
|
|
75
|
+
"parts": {
|
|
76
|
+
"type": "array",
|
|
77
|
+
"minItems": 1,
|
|
78
|
+
"items": {
|
|
79
|
+
"$ref": "part.schema.json"
|
|
80
|
+
},
|
|
81
|
+
"description": "RFC 0205 §B. OPTIONAL. The turn's content as A2A `Part`s (A2A v1.0.1 `Message.parts`). PRESENCE IS THE DISCRIMINATOR: a turn carrying `parts` is A2A-shaped and projects to an A2A `Message` via `messageId`, `role` (user→ROLE_USER, agent→ROLE_AGENT) and `parts`. A producer SHOULD emit it and keep `content` displayable to readers that predate it. A turn without `parts` stays valid on emission, read, replay and fork for the life of the major. Kept in sync with `conversation-event.schema.json#/$defs/ConversationTurn/properties/parts`."
|
|
82
|
+
},
|
|
75
83
|
"ts": {
|
|
76
84
|
"type": "integer",
|
|
77
85
|
"minimum": 0
|
|
@@ -254,6 +262,5 @@
|
|
|
254
262
|
},
|
|
255
263
|
"additionalProperties": false
|
|
256
264
|
}
|
|
257
|
-
}
|
|
258
|
-
"x-openwop-seeded-from": "v1"
|
|
265
|
+
}
|
|
259
266
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://openwop.dev/spec/v2/conversation-turn.schema.json",
|
|
4
4
|
"title": "ConversationTurn",
|
|
5
|
-
"description": "One turn in a multi-turn conversation. Structural superset of `ConversationMessage` (RFC 0002
|
|
5
|
+
"description": "One turn in a multi-turn conversation. Structural superset of `ConversationMessage` (RFC 0002 §G — append-only, idempotent on `messageId`, replay-deterministic). Adds `role`, optional `agent` reference, and `turnIndex` discriminators. Folds through the existing `applyMessage` reducer unchanged. See RFC 0005 §C.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": [
|
|
8
8
|
"messageId",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"from": {
|
|
23
23
|
"type": "string",
|
|
24
|
-
"description": "Sender identity. Either an agent ID (RFC 0002
|
|
24
|
+
"description": "Sender identity. Either an agent ID (RFC 0002 §A1) or the literal `'user'` for human-originated turns.",
|
|
25
25
|
"minLength": 1,
|
|
26
26
|
"maxLength": 256
|
|
27
27
|
},
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"groupId": {
|
|
34
34
|
"type": "string",
|
|
35
|
-
"description": "Optional shared-agent group ID. When set, the turn is scoped to the `shared:<groupId>` agent context per RFC 0002
|
|
35
|
+
"description": "Optional shared-agent group ID. When set, the turn is scoped to the `shared:<groupId>` agent context per RFC 0002 §A8.",
|
|
36
36
|
"maxLength": 256
|
|
37
37
|
},
|
|
38
38
|
"content": {
|
|
@@ -46,6 +46,14 @@
|
|
|
46
46
|
"null"
|
|
47
47
|
]
|
|
48
48
|
},
|
|
49
|
+
"parts": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"minItems": 1,
|
|
52
|
+
"items": {
|
|
53
|
+
"$ref": "part.schema.json"
|
|
54
|
+
},
|
|
55
|
+
"description": "RFC 0205 §B. OPTIONAL. The turn's content as A2A `Part`s (A2A v1.0.1 `Message.parts`). PRESENCE IS THE DISCRIMINATOR: a turn carrying `parts` is A2A-shaped and projects to an A2A `Message` via `messageId`, `role` (user→ROLE_USER, agent→ROLE_AGENT) and `parts`. A producer SHOULD emit it and keep `content` displayable to readers that predate it. A turn without `parts` stays valid on emission, read, replay and fork for the life of the major. Kept in sync with `conversation-event.schema.json#/$defs/ConversationTurn/properties/parts`."
|
|
56
|
+
},
|
|
49
57
|
"ts": {
|
|
50
58
|
"type": "integer",
|
|
51
59
|
"minimum": 0,
|
|
@@ -58,11 +66,11 @@
|
|
|
58
66
|
"agent",
|
|
59
67
|
"system"
|
|
60
68
|
],
|
|
61
|
-
"description": "Discriminator distinguishing human-originated turns (`'user'`), AI-agent-originated turns (`'agent'`), and host-emitted procedural turns (`'system'`
|
|
69
|
+
"description": "Discriminator distinguishing human-originated turns (`'user'`), AI-agent-originated turns (`'agent'`), and host-emitted procedural turns (`'system'` — e.g., `'conversation timed out'`)."
|
|
62
70
|
},
|
|
63
71
|
"agent": {
|
|
64
72
|
"type": "object",
|
|
65
|
-
"description": "Optional agent reference (RFC 0002
|
|
73
|
+
"description": "Optional agent reference (RFC 0002 §A1 `AgentRef`) for `role: 'agent'` turns. The same shape RFC 0002 reserves on `RunSnapshot.agent` and `node.started.payload.agent` — propagated through inheritance.",
|
|
66
74
|
"properties": {
|
|
67
75
|
"agentId": {
|
|
68
76
|
"$ref": "ids.schema.json#/$defs/agentId"
|
|
@@ -74,15 +82,15 @@
|
|
|
74
82
|
"shared",
|
|
75
83
|
"shared:%shared%"
|
|
76
84
|
],
|
|
77
|
-
"description": "Per RFC 0002
|
|
85
|
+
"description": "Per RFC 0002 §A8 — `shared:<groupId>` requires a `groupId` field on the message."
|
|
78
86
|
},
|
|
79
87
|
"memoryRef": {
|
|
80
88
|
"type": "string",
|
|
81
|
-
"description": "Opaque memory reference per RFC 0002
|
|
89
|
+
"description": "Opaque memory reference per RFC 0002 §A + RFC 0004 §A. Resolves to `MemoryEntry[]` via host `MemoryAdapter` for cross-run conversation continuity."
|
|
82
90
|
},
|
|
83
91
|
"model": {
|
|
84
92
|
"type": "object",
|
|
85
|
-
"description": "RFC 0109
|
|
93
|
+
"description": "RFC 0109 — OPTIONAL provenance: which model produced this `role: 'agent'` turn. NON-SECRET, NON-PII: provider + model identifiers ONLY (`additionalProperties: false` forbids any credential/endpoint/prompt leaking in — the SR-1 secret-redaction guard). Stamped at emit; read VERBATIM on `:fork` (never re-resolved). A host that stamps it MUST advertise `conversationTurnModelProvenance.supported: true`. Absent ⇒ no advertisement; clients MUST tolerate its absence.",
|
|
86
94
|
"additionalProperties": false,
|
|
87
95
|
"required": [
|
|
88
96
|
"provider",
|
|
@@ -115,12 +123,12 @@
|
|
|
115
123
|
"type": "string",
|
|
116
124
|
"minLength": 1,
|
|
117
125
|
"maxLength": 256,
|
|
118
|
-
"description": "RFC 0101. Stable speaker identity of this turn
|
|
126
|
+
"description": "RFC 0101. Stable speaker identity of this turn — the roster INSTANCE id of the agent that produced it (the `host:<id>` AgentRef agentId per `agent-roster-entry.schema.json` §A / RFC 0086), NOT the manifest/class `AgentRef.agentId`. REQUIRED when `role: 'agent'` (the conditional below) so that 'turn N was spoken by agent X' is an observable, replay-stable, cross-host-projectable fact in a multi-party transcript. When a `participants` roster is declared on `conversation.opened` (RFC 0101), `speakerId` MUST be a member of that roster; a turn whose `speakerId` is not a participant MUST be rejected (host-enforced, capability-gated on `multiPartyConversation.supported`). For `role: 'user'` / `role: 'system'` turns the field is OPTIONAL and carries no normative meaning. Additive-safe: pre-RFC-0101 `role: 'agent'` turns that omit it are accepted by hosts that do NOT advertise `multiPartyConversation`."
|
|
119
127
|
}
|
|
120
128
|
},
|
|
121
129
|
"allOf": [
|
|
122
130
|
{
|
|
123
|
-
"$comment": "RFC 0101
|
|
131
|
+
"$comment": "RFC 0101 — agent turns MUST carry speaker attribution. Conditional (not unconditional `required`) so the field is only mandatory for `role: 'agent'`; `user`/`system` turns and pre-RFC-0101 producers on non-multi-party hosts are unaffected. Capability-gated: hosts enforce this only when advertising `multiPartyConversation.supported` (capabilities.schema.json).",
|
|
124
132
|
"if": {
|
|
125
133
|
"properties": {
|
|
126
134
|
"role": {
|
|
@@ -158,6 +166,5 @@
|
|
|
158
166
|
}
|
|
159
167
|
],
|
|
160
168
|
"$comment": "RFC 0101 NEGATIVE (covered by the `allOf`/`if` conditional + conversation scenarios, NOT validatable as an `examples[]` entry which must be VALID): a `{ role: 'agent', ... }` turn that OMITS `speakerId` MUST FAIL validation; see conformance/src/scenarios/multi-party-conversation-shape.test.ts.",
|
|
161
|
-
"additionalProperties": false
|
|
162
|
-
"x-openwop-seeded-from": "v1"
|
|
169
|
+
"additionalProperties": false
|
|
163
170
|
}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"child-run"
|
|
23
23
|
],
|
|
24
24
|
"default": "child-run",
|
|
25
|
-
"description": "How `kind: 'next-worker'` is dispatched. v1.x normates only `'child-run'` — each `nextWorkerIds[i]` resolves to a workflow id and is dispatched as a child run via the existing `core.subWorkflow` machinery. Same-run DAG navigation is OUT OF SCOPE for v1.x (deferred to RFC 0013 / v1.3+).
|
|
25
|
+
"description": "How `kind: 'next-worker'` is dispatched. v1.x normates only `'child-run'` — each `nextWorkerIds[i]` resolves to a workflow id and is dispatched as a child run via the existing `core.subWorkflow` machinery. Same-run DAG navigation is OUT OF SCOPE for v1.x (deferred to RFC 0013 / v1.3+). The enum is closed: any other value, including a `vendor.<host>.<model>` name, fails validation against this schema, so a host cannot add a dispatch model without an additive schema change. Conformance scenarios validate `'child-run'` only."
|
|
26
26
|
},
|
|
27
27
|
"fanOutPolicy": {
|
|
28
28
|
"type": "string",
|