@openwop/openwop-conformance 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +156 -1
- package/README.md +3 -2
- package/api/asyncapi.yaml +8 -0
- package/api/openapi.yaml +371 -1
- package/api/redocly.yaml +15 -0
- package/coverage.md +26 -5
- package/fixtures/conformance-agent-reasoning-streaming.json +37 -0
- package/fixtures/conformance-dispatch-cancellable-child.json +27 -0
- package/fixtures/conformance-dispatch-deterministic-fail-child.json +30 -0
- package/fixtures/conformance-dispatch-input-mapping-no-default.json +49 -0
- package/fixtures/conformance-dispatch-per-worker-override.json +59 -0
- package/fixtures/conformance-envelope-nl-to-format-engaged.json +41 -0
- package/fixtures/conformance-envelope-recovery-applied.json +39 -0
- package/fixtures/conformance-envelope-refusal.json +38 -0
- package/fixtures/conformance-envelope-retry-attempted.json +39 -0
- package/fixtures/conformance-envelope-retry-exhausted.json +38 -0
- package/fixtures/conformance-envelope-truncated.json +39 -0
- package/fixtures/conformance-envelope-truncation-cap-exhaustion.json +39 -0
- package/fixtures/conformance-model-capability-insufficient.json +25 -0
- package/fixtures/conformance-multi-agent-confidence-escalation.json +49 -0
- package/fixtures/conformance-multi-agent-handoff-child.json +27 -0
- package/fixtures/conformance-multi-agent-handoff.json +49 -0
- package/fixtures/conformance-prompt-all-four-kinds.json +39 -0
- package/fixtures/conformance-prompt-end-to-end.json +33 -0
- package/fixtures/conformance-subworkflow-input-mapping-no-default.json +33 -0
- package/fixtures/conformance-subworkflow-mid-run-mutation-child.json +31 -0
- package/fixtures/conformance-subworkflow-mid-run-mutation.json +33 -0
- package/fixtures/openwop-smoke-cost-emit.json +37 -0
- package/fixtures/prompt-templates/conformance-prompt-few-shot-2.json +14 -0
- package/fixtures/prompt-templates/conformance-prompt-few-shot.json +14 -0
- package/fixtures/prompt-templates/conformance-prompt-schema-hint.json +14 -0
- package/fixtures/prompt-templates/conformance-prompt-secret-redaction.json +23 -0
- package/fixtures/prompt-templates/conformance-prompt-trust-marker.json +23 -0
- package/fixtures/prompt-templates/conformance-prompt-writer-system.json +15 -0
- package/fixtures/prompt-templates/conformance-prompt-writer-user.json +15 -0
- package/fixtures.md +45 -0
- package/package.json +1 -1
- package/schemas/README.md +5 -0
- package/schemas/agent-manifest.schema.json +16 -0
- package/schemas/capabilities.schema.json +390 -0
- package/schemas/core-conformance-mock-agent-config.schema.json +5 -0
- package/schemas/envelopes/clarification.request.schema.json +9 -0
- package/schemas/envelopes/error.schema.json +4 -0
- package/schemas/envelopes/schema.request.schema.json +4 -0
- package/schemas/envelopes/schema.response.schema.json +1 -1
- package/schemas/node-pack-manifest.schema.json +28 -0
- package/schemas/orchestrator-decision.schema.json +12 -0
- package/schemas/prompt-kind.schema.json +8 -0
- package/schemas/prompt-pack-manifest.schema.json +80 -0
- package/schemas/prompt-ref.schema.json +40 -0
- package/schemas/prompt-template.schema.json +149 -0
- package/schemas/registry-version-manifest.schema.json +5 -0
- package/schemas/run-ancestry-response.schema.json +54 -0
- package/schemas/run-event-payloads.schema.json +513 -11
- package/schemas/run-event.schema.json +17 -1
- package/schemas/run-snapshot.schema.json +3 -2
- package/schemas/workflow-definition.schema.json +19 -1
- package/src/lib/driver.ts +15 -0
- package/src/lib/env.ts +51 -0
- package/src/lib/event-log-query.ts +62 -0
- package/src/lib/fixtures.ts +38 -1
- package/src/lib/host-toggle.ts +54 -0
- package/src/lib/llm-cache-key-recipe.ts +68 -0
- package/src/lib/multi-agent-capabilities.ts +10 -0
- package/src/lib/otel-scrape.ts +59 -0
- package/src/scenarios/agentReasoningStreaming.test.ts +193 -0
- package/src/scenarios/aiEnvelope.capBreached.test.ts +97 -9
- package/src/scenarios/aiEnvelope.contractRefusal.test.ts +224 -15
- package/src/scenarios/aiEnvelope.correlationReplay.test.ts +257 -25
- package/src/scenarios/aiEnvelope.redaction.test.ts +210 -29
- package/src/scenarios/aiEnvelope.schemaDrift.test.ts +163 -24
- package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +262 -12
- package/src/scenarios/aiEnvelope.universalKinds.test.ts +107 -16
- package/src/scenarios/blob-presign-expiry.test.ts +42 -9
- package/src/scenarios/blob-roundtrip.test.ts +0 -0
- package/src/scenarios/cache-ttl-expiry.test.ts +34 -8
- package/src/scenarios/cost-attribution.test.ts +124 -11
- package/src/scenarios/cross-engine-append-ordering.test.ts +99 -0
- package/src/scenarios/cross-host-ancestry-endpoint.test.ts +136 -0
- package/src/scenarios/cross-host-causation-shape.test.ts +117 -0
- package/src/scenarios/cross-host-traceparent-propagation.test.ts +60 -0
- package/src/scenarios/dispatch-cross-worker-handoff.test.ts +34 -3
- package/src/scenarios/dispatch-input-mapping.test.ts +75 -6
- package/src/scenarios/dispatch-output-mapping.test.ts +96 -6
- package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +223 -0
- package/src/scenarios/envelope-nl-to-format-engaged.test.ts +152 -0
- package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +343 -0
- package/src/scenarios/envelope-reasoning-shape.test.ts +190 -0
- package/src/scenarios/envelope-recovery-applied.test.ts +229 -0
- package/src/scenarios/envelope-refusal-shape.test.ts +289 -0
- package/src/scenarios/envelope-retry-attempted.test.ts +258 -0
- package/src/scenarios/envelope-retry-exhausted.test.ts +168 -0
- package/src/scenarios/envelope-tier-one-subset-static.test.ts +229 -0
- package/src/scenarios/envelope-truncated.test.ts +136 -0
- package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +144 -0
- package/src/scenarios/envelope-variant-discriminator-static.test.ts +152 -0
- package/src/scenarios/fixtures-gating.test.ts +139 -1
- package/src/scenarios/fixtures-valid.test.ts +123 -15
- package/src/scenarios/kv-ttl-expiry.test.ts +40 -9
- package/src/scenarios/model-capability-insufficient.test.ts +221 -0
- package/src/scenarios/model-capability-substituted.test.ts +203 -0
- package/src/scenarios/multi-agent-confidence-escalation.test.ts +164 -0
- package/src/scenarios/multi-agent-handoff-state-machine.test.ts +167 -0
- package/src/scenarios/multi-agent-memory-lifecycle.test.ts +124 -0
- package/src/scenarios/multi-region-idempotency.test.ts +58 -0
- package/src/scenarios/node-module-required-capabilities-shape.test.ts +185 -0
- package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +19 -0
- package/src/scenarios/pack-registry-publish.test.ts +231 -51
- package/src/scenarios/prompt-all-four-kinds-events.test.ts +198 -0
- package/src/scenarios/prompt-composed-secret-redaction.test.ts +178 -0
- package/src/scenarios/prompt-composed-trust-marker.test.ts +165 -0
- package/src/scenarios/prompt-end-to-end-events.test.ts +202 -0
- package/src/scenarios/prompt-list-and-fetch.test.ts +207 -0
- package/src/scenarios/prompt-mutable-lifecycle.test.ts +216 -0
- package/src/scenarios/prompt-pack-install.test.ts +187 -0
- package/src/scenarios/prompt-render-deterministic.test.ts +240 -0
- package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +140 -0
- package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +172 -0
- package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +144 -0
- package/src/scenarios/prompt-template-shape.test.ts +359 -0
- package/src/scenarios/provider-usage.test.ts +185 -0
- package/src/scenarios/queue-ack-nack-dlq.test.ts +64 -10
- package/src/scenarios/queue-publish-consume-roundtrip.test.ts +50 -10
- package/src/scenarios/replay-divergence-at-refusal.test.ts +134 -0
- package/src/scenarios/replay-llm-cache-key-portable.test.ts +197 -0
- package/src/scenarios/replay-llm-cache-key.test.ts +127 -25
- package/src/scenarios/replay-observable-sequence-determinism.test.ts +80 -0
- package/src/scenarios/sandbox-capability-gate-respected.test.ts +31 -0
- package/src/scenarios/sandbox-memory-cap.test.ts +61 -0
- package/src/scenarios/sandbox-no-cross-pack-mutation.test.ts +35 -0
- package/src/scenarios/sandbox-no-host-env-leak.test.ts +38 -0
- package/src/scenarios/sandbox-no-host-fs-escape.test.ts +91 -0
- package/src/scenarios/sandbox-no-host-process-escape.test.ts +30 -0
- package/src/scenarios/sandbox-no-network-escape.test.ts +49 -0
- package/src/scenarios/sandbox-timeout-cap.test.ts +61 -0
- package/src/scenarios/search-bm25-roundtrip.test.ts +54 -9
- package/src/scenarios/spec-corpus-validity.test.ts +34 -6
- package/src/scenarios/sql-transaction-atomicity.test.ts +37 -8
- package/src/scenarios/stream-subscribe-from-beginning.test.ts +46 -9
- package/src/scenarios/subworkflow-input-mapping.test.ts +146 -10
- package/src/scenarios/table-cursor-pagination.test.ts +47 -9
- package/src/scenarios/table-schema-enforcement.test.ts +46 -9
- package/src/scenarios/vector-knn-roundtrip.test.ts +50 -10
- package/src/scenarios/workflow-chain-host-expansion.test.ts +202 -0
|
@@ -66,6 +66,170 @@
|
|
|
66
66
|
},
|
|
67
67
|
"additionalProperties": false
|
|
68
68
|
},
|
|
69
|
+
"envelopes": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"description": "Envelope LLM-contract advertisement container introduced by the RFC 0030–0033 envelope-hardening track. Each sub-block is independently opt-in; hosts that adopt a subset advertise only the sub-blocks they implement. `additionalProperties: true` reserved for future RFCs that extend the track; host-private extensions go under `x-host-<host>-<key>` per `host-extensions.md` §\"Canonical-prefix table\".",
|
|
72
|
+
"additionalProperties": true,
|
|
73
|
+
"properties": {
|
|
74
|
+
"reasoning": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"description": "RFC 0030 §A + §C. Host's envelope payload schemas support the OPTIONAL `reasoning` field on kinds where multi-step reasoning materially improves output quality; the host's system-prompt-injection helper instructs the model to populate it. Absent block = no advertisement (the field MAY still appear on envelope schemas; this advertisement signals the host's prompt-injection posture).",
|
|
77
|
+
"additionalProperties": false,
|
|
78
|
+
"required": ["supported"],
|
|
79
|
+
"properties": {
|
|
80
|
+
"supported": {
|
|
81
|
+
"type": "boolean",
|
|
82
|
+
"description": "Host's envelope payload schemas carry `reasoning` (OPTIONAL) on kinds where reasoning materially improves output quality, per RFC 0030 §A. Hosts SHOULD prompt the model to populate the field; hosts MUST NOT reject envelopes where `reasoning` is absent (the field is OPTIONAL by spec); hosts SHALL NOT route on `reasoning` contents."
|
|
83
|
+
},
|
|
84
|
+
"promptDirective": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"enum": ["mandatory", "advisory", "off"],
|
|
87
|
+
"description": "Strength of the host's system-prompt instruction to populate `reasoning`. `mandatory`: the directive is firmly worded (the host instructs the model very forcefully to emit `reasoning`). `advisory` (default when absent): the directive is suggestive. `off`: the host emits no directive — applications that want `reasoning` populated must inject the instruction themselves. Note: `mandatory` is a prompt-injection posture, NOT a wire-level refusal contract — hosts MUST NOT reject envelopes where `reasoning` is absent regardless of this value."
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"tierOneSubsetCompliance": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"enum": ["strict", "warn", "off"],
|
|
94
|
+
"description": "RFC 0030 §B + §C. Host's self-attested compliance posture for the Tier-1 cross-vendor structured-output subset documented in `spec/v1/structured-output-subset.md`. `strict`: every host-served envelope schema passes the static subset-compliance check (object-root, `additionalProperties: false` everywhere, every property in `required`, no `oneOf`/`allOf`/`not`/`prefixItems`/`propertyNames`, no string format/pattern/length constraints, no number bounds, no array bounds, ≤5 nesting depth, ≤100 property count). `warn`: host serves non-compliant schemas but logs the violations. `off` (default when absent): no self-attestation. The conformance-suite static-subset scenario gates on this flag."
|
|
95
|
+
},
|
|
96
|
+
"reliability": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"additionalProperties": false,
|
|
99
|
+
"required": ["supported"],
|
|
100
|
+
"description": "RFC 0032 §C. Host emits the envelope-reliability event family on documented adverse paths. Hosts opt into the family via `supported: true` AND explicitly list the events they emit via `events[]`. Hosts that advertise `supported: true` MUST include at least `envelope.retry.exhausted` and `envelope.refusal` in `events[]` (the two MUST-tier events). The other four (`envelope.retry.attempted`, `envelope.truncated`, `envelope.nlToFormat.engaged`, `envelope.recovery.applied`) are SHOULD/MAY-tier per RFC 0032 §B and may be omitted.",
|
|
101
|
+
"properties": {
|
|
102
|
+
"supported": {
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"description": "Host emits the RFC 0032 envelope-reliability event family on the documented adverse paths. When `false` or absent, conformance scenarios for the family soft-skip."
|
|
105
|
+
},
|
|
106
|
+
"events": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"items": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"enum": [
|
|
111
|
+
"envelope.retry.attempted",
|
|
112
|
+
"envelope.retry.exhausted",
|
|
113
|
+
"envelope.refusal",
|
|
114
|
+
"envelope.truncated",
|
|
115
|
+
"envelope.nlToFormat.engaged",
|
|
116
|
+
"envelope.recovery.applied"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"uniqueItems": true,
|
|
120
|
+
"description": "Subset of the six reliability events the host actually emits. Hosts that advertise `supported: true` MUST include `envelope.retry.exhausted` and `envelope.refusal`. Conformance scenarios soft-skip for events absent from this list (the event-emission assertion is skipped; other host behavior assertions remain in force)."
|
|
121
|
+
},
|
|
122
|
+
"maxRetryAttempts": {
|
|
123
|
+
"type": "integer",
|
|
124
|
+
"minimum": 1,
|
|
125
|
+
"maximum": 16,
|
|
126
|
+
"description": "Host's retry budget per envelope emission. Conformance scenarios use this to construct fixtures that exercise the retry-exhausted path. Independent of `capabilities.limits.schemaRounds` (which is the engine-side per-emission cap) — `maxRetryAttempts` reports the host's actual configured value, not the spec's upper bound."
|
|
127
|
+
},
|
|
128
|
+
"completion": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"required": ["distinguishesTruncation"],
|
|
132
|
+
"description": "RFC 0033 §E. Host's self-attested envelope-completion contract posture — does the host distinguish truncation from schema-violation in its retry routing per RFC 0033 §A + §B + §C?",
|
|
133
|
+
"properties": {
|
|
134
|
+
"distinguishesTruncation": {
|
|
135
|
+
"type": "boolean",
|
|
136
|
+
"description": "Host implements RFC 0033's truncation-vs-schema-violation retry-routing distinction: truncation → increased output budget (NO corrective fragment); schema-violation → corrective system fragment (NO budget increase). When `false` or absent, the host conflates the two paths (legacy behavior); RFC 0033 conformance scenarios soft-skip."
|
|
137
|
+
},
|
|
138
|
+
"truncationBudgetMultiplier": {
|
|
139
|
+
"type": "number",
|
|
140
|
+
"minimum": 1,
|
|
141
|
+
"maximum": 8,
|
|
142
|
+
"description": "Host's per-attempt output-budget multiplier on truncation retries. Informational; clients MAY surface this in cost-estimation UIs. Defaults to 2 when absent and `distinguishesTruncation: true`. Spec recommendation is 2× per RFC 0033 §B."
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"prompts": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"description": "RFC 0027 + RFC 0028 prompt-template support advertisement. The `supported` flag gates **node-execution resolution** of PromptRef values per RFC 0027 (Phase A); the separate `endpointsSupported` flag gates the **REST surface** at `/v1/prompts*` per RFC 0028 (Phase B). The two axes are independent — a host MAY implement Phase A composition without exposing the REST surface, and vice versa. Absent block = no support; consumers passing PromptRef values to such a host MUST tolerate the keys being treated as opaque strings.",
|
|
153
|
+
"required": ["supported"],
|
|
154
|
+
"properties": {
|
|
155
|
+
"supported": {
|
|
156
|
+
"type": "boolean",
|
|
157
|
+
"description": "RFC 0027 Phase A. When `true`, the host resolves PromptRef values in `WorkflowNode.config.{systemPromptRef, userPromptRef, additionalPromptRefs}` at node-execution time AND emits `prompt.composed` run events per spec/v1/prompts.md §\"Composition + observability\". Does NOT imply the `/v1/prompts*` REST surface is available — see `endpointsSupported` for that. False or absent = the PromptRef keys on `WorkflowNode.config` are treated as opaque strings and never composed."
|
|
158
|
+
},
|
|
159
|
+
"endpointsSupported": {
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"description": "RFC 0028 §A. When `true`, the host serves the `/v1/prompts*` REST surface — at minimum the read endpoints (`listPromptTemplates`, `getPromptTemplate`, `renderPromptTemplate`). The mutating endpoints additionally require `mutableLibrary: true`; the pack-install path additionally requires `packsSupported: true`. False or absent = every `/v1/prompts*` request returns `501 capability_not_provided`. Independent of `supported` — a host MAY advertise `supported: true, endpointsSupported: false` (composition without library REST) or `supported: false, endpointsSupported: true` (library REST against an external resolver, e.g., a façade host)."
|
|
162
|
+
},
|
|
163
|
+
"templateKinds": {
|
|
164
|
+
"type": "array",
|
|
165
|
+
"items": { "$ref": "./prompt-kind.schema.json" },
|
|
166
|
+
"uniqueItems": true,
|
|
167
|
+
"description": "Subset of PromptKind values the host accepts. Defaults to all four (`system`, `user`, `few-shot`, `schema-hint`) when omitted. The $ref resolves to the shared `prompt-kind.schema.json` `$def` per RFC 0027 §A — uses a relative URI so redocly's lint walker resolves it against the local file rather than fetching the openwop.dev URL."
|
|
168
|
+
},
|
|
169
|
+
"variableSources": {
|
|
170
|
+
"type": "array",
|
|
171
|
+
"items": { "type": "string", "enum": ["input", "variable", "secret", "context"] },
|
|
172
|
+
"uniqueItems": true,
|
|
173
|
+
"description": "Subset of PromptVariable.source values the host supports. `secret` SHOULD only appear when `capabilities.secrets.supported` is also true."
|
|
174
|
+
},
|
|
175
|
+
"maxTemplateBytes": {
|
|
176
|
+
"type": "integer",
|
|
177
|
+
"minimum": 1,
|
|
178
|
+
"maximum": 65536,
|
|
179
|
+
"description": "Host limit on PromptTemplate.text length. MUST NOT exceed the schema cap (65536). When advertised, the host MUST reject larger bodies on install + on `POST /v1/prompts` (RFC 0028)."
|
|
180
|
+
},
|
|
181
|
+
"observability": {
|
|
182
|
+
"type": "string",
|
|
183
|
+
"enum": ["off", "hashed", "full"],
|
|
184
|
+
"description": "How `prompt.composed` events expose resolved bodies. `off`: event not emitted. `hashed`: payload carries only sha256 + per-variable-binding hashes (no plaintext). `full`: payload carries the composed body with secret-sourced values redacted to `[REDACTED:<secretId>]` markers and untrusted segments wrapped in `<UNTRUSTED>` markers. Default when absent: `hashed`."
|
|
185
|
+
},
|
|
186
|
+
"packsSupported": {
|
|
187
|
+
"type": "boolean",
|
|
188
|
+
"description": "RFC 0028 §C. When `true`, the host installs `kind: \"prompt\"` registry packs and exposes their templates at `GET /v1/prompts` with `meta.source: \"pack\"` + `meta.packName` + `meta.packVersion`. When `false` or absent, packs are not loaded; only host built-ins and (when `mutableLibrary: true`) user-created templates are visible."
|
|
189
|
+
},
|
|
190
|
+
"mutableLibrary": {
|
|
191
|
+
"type": "boolean",
|
|
192
|
+
"description": "RFC 0028 §C. When `true`, the host honors the mutating endpoints `POST /v1/prompts`, `PUT /v1/prompts/{templateId}`, `DELETE /v1/prompts/{templateId}`. When `false` or absent, those endpoints return 501. Pack-sourced and host-built-in templates remain read-only even under `mutableLibrary: true` — deletion of those returns 403 per RFC 0028 §A."
|
|
193
|
+
},
|
|
194
|
+
"library": {
|
|
195
|
+
"type": "object",
|
|
196
|
+
"additionalProperties": false,
|
|
197
|
+
"description": "RFC 0028 §C. Per-library configuration knobs that influence how clients call the prompt surface.",
|
|
198
|
+
"properties": {
|
|
199
|
+
"id": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"description": "Host's library identifier exposed at `GET /v1/prompts` (filterable via the structured `PromptRef.libraryId` field). Single-library hosts MAY omit this."
|
|
202
|
+
},
|
|
203
|
+
"renderEndpoint": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"format": "uri-reference",
|
|
206
|
+
"description": "Absolute or relative URI of the `:render` endpoint. Defaults to `/v1/prompts:render`. Useful for hosts mounting the surface under a prefix."
|
|
207
|
+
},
|
|
208
|
+
"maxRenderRequestBytes": {
|
|
209
|
+
"type": "integer",
|
|
210
|
+
"minimum": 1,
|
|
211
|
+
"description": "Hard cap on `POST /v1/prompts:render` request body size."
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"defaults": {
|
|
216
|
+
"type": "object",
|
|
217
|
+
"additionalProperties": false,
|
|
218
|
+
"description": "RFC 0029 §B. Per-kind host-default PromptRefs that apply at resolution chain layer 4 (`host-defaults`) per `spec/v1/prompts.md` §\"Resolution chain (normative)\". Advertised so clients can preview the full chain at edit time without dispatching a node. Hosts MAY ship per-kind defaults; the openwop spec ships none.",
|
|
219
|
+
"properties": {
|
|
220
|
+
"system": { "$ref": "./prompt-ref.schema.json" },
|
|
221
|
+
"user": { "$ref": "./prompt-ref.schema.json" },
|
|
222
|
+
"few-shot": { "$ref": "./prompt-ref.schema.json" },
|
|
223
|
+
"schema-hint": { "$ref": "./prompt-ref.schema.json" }
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"agentBindings": {
|
|
227
|
+
"type": "boolean",
|
|
228
|
+
"description": "RFC 0029 §B. When `true`, the host honors `AgentManifest.promptOverrides[kind]` and `AgentManifest.promptLibraryRef` at resolution chain layer 2 (`agent-overrides` / `agent-library-default`) per `spec/v1/prompts.md` §\"Resolution chain (normative)\". When `false` or absent, layer 2 is skipped — the host applies only layers 1, 3, 4. Conformance scenarios for agent-binding resolution are gated on this flag."
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"additionalProperties": false
|
|
232
|
+
},
|
|
69
233
|
"extensions": {
|
|
70
234
|
"type": "object",
|
|
71
235
|
"description": "Optional per-canvas-type or per-workflow extensions (additional envelope types, override limits)."
|
|
@@ -170,6 +334,21 @@
|
|
|
170
334
|
}
|
|
171
335
|
},
|
|
172
336
|
"additionalProperties": true
|
|
337
|
+
},
|
|
338
|
+
"testSeams": {
|
|
339
|
+
"type": "object",
|
|
340
|
+
"additionalProperties": false,
|
|
341
|
+
"description": "RFC 0034 — Conformance-only test seams under the host-extension namespace. Hosts that opt in expose introspection endpoints so cross-host conformance scenarios can verify BYOK canaries do not leak into OTel span attributes or debug-bundle exports. Production hosts SHOULD return 404 or 403 from these seams unless an env-gate (e.g., `OPENWOP_TEST_OTEL_SCRAPE=true`) is set.",
|
|
342
|
+
"properties": {
|
|
343
|
+
"otelScrape": {
|
|
344
|
+
"type": "boolean",
|
|
345
|
+
"description": "Host exposes `GET /v1/host/sample/test/otel/spans?runId=<id>` returning `{ spans: Array<{ name, attributes, events }> }` scoped to the run. Conformance verifies span attributes don't carry BYOK canaries. When advertised true, the host MUST serve a 200 response with the documented shape."
|
|
346
|
+
},
|
|
347
|
+
"debugBundleExport": {
|
|
348
|
+
"type": "boolean",
|
|
349
|
+
"description": "Host exposes `POST /v1/host/sample/test/debug-bundle/export` returning the same payload shape as `GET /v1/runs/{runId}/debug-bundle` per `spec/v1/debug-bundle.md`. Conformance verifies the serialized bundle doesn't carry BYOK canaries. When advertised true, the host MUST serve a 200 response with the documented shape."
|
|
350
|
+
}
|
|
351
|
+
}
|
|
173
352
|
}
|
|
174
353
|
},
|
|
175
354
|
"additionalProperties": true
|
|
@@ -210,6 +389,122 @@
|
|
|
210
389
|
"uniqueItems": true,
|
|
211
390
|
"description": "Optional v1 host-advertised opaque capability ids that NodeModules may declare in `NodeModule.requires`. Naming convention: dotted, domain-scoped (`chat.sendPrompt`, `canvas.write`, `secrets.byok`). Provider value shapes are documented per-capability alongside consumers, NOT in the protocol package — the protocol owns the *check*, not domain provider contracts. A client that submits a workflow whose nodes declare a `requires` entry SHOULD first verify the host advertises that capability; a host that lacks a capability MUST refuse to dispatch nodes that declare it, terminating the run with `RunSnapshot.error.code = 'capability_not_provided'`. See `capabilities.md` §\"Runtime capabilities\"."
|
|
212
391
|
},
|
|
392
|
+
"multiAgent": {
|
|
393
|
+
"type": "object",
|
|
394
|
+
"description": "RFC 0037 — Multi-agent execution model + handoff state machine. Hosts that advertise implement the supervisor→dispatch→harvest loop + the 4-state handoff state machine + the `core.workflowChain.event` emission contract per spec/v1/multi-agent-execution.md. Absent block = host implements RFCs 0006/0007/0022 individually with implementation flexibility on integration semantics; conformance scenarios gating on this flag soft-skip on absence.",
|
|
395
|
+
"additionalProperties": false,
|
|
396
|
+
"properties": {
|
|
397
|
+
"executionModel": {
|
|
398
|
+
"type": "object",
|
|
399
|
+
"additionalProperties": false,
|
|
400
|
+
"required": ["supported", "version"],
|
|
401
|
+
"properties": {
|
|
402
|
+
"supported": {
|
|
403
|
+
"type": "boolean",
|
|
404
|
+
"description": "Host implements the execution loop + handoff state machine per spec/v1/multi-agent-execution.md §\"Execution loop\" + §\"Handoff state machine\". When true, the host MUST emit `core.workflowChain.event` records on every handoff transition per the §\"Transition events\" table."
|
|
405
|
+
},
|
|
406
|
+
"version": {
|
|
407
|
+
"type": "integer",
|
|
408
|
+
"minimum": 1,
|
|
409
|
+
"maximum": 4,
|
|
410
|
+
"description": "Profile version. 1 = Phase 1 (execution-loop framework + planner→worker handoff). 2 = Phase 2 (confidence-floor escalation + agent-memory lifecycle, RFC 0039). 3 = Phase 3 (cross-host causation, follow-up RFC). 4 = Phase 4 (replay determinism under nondeterministic models, follow-up RFC). A host advertising `version: N` MUST implement all phases 1..N additively."
|
|
411
|
+
},
|
|
412
|
+
"confidenceEscalationFloor": {
|
|
413
|
+
"type": "number",
|
|
414
|
+
"minimum": 0.5,
|
|
415
|
+
"maximum": 1.0,
|
|
416
|
+
"description": "RFC 0039 §A. Operator-declared confidence floor at or above the spec floor of 0.5; when an OrchestratorDecision carries `confidence` below this floor, the host MUST escalate via a `clarify` or `escalate` interrupt instead of executing the decision. Absent: the spec floor 0.5 applies. Values < 0.5 are non-conformant; values > 1.0 are nonsense. Applies only when `version >= 2`."
|
|
417
|
+
},
|
|
418
|
+
"crossChildMemoryConcurrency": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"enum": ["strict", "advisory"],
|
|
421
|
+
"description": "RFC 0039 §B. Cross-child memory-write concurrency posture when version >= 2. `strict` (default when absent): the host serializes concurrent writes from sibling dispatched children to the parent's shared memory scope. `advisory`: the host opts out of the serialization MUST and documents last-write-wins semantics out-of-band. Hosts that choose advisory SHOULD also advertise their resolution rule under `crossChildMemoryConcurrencyResolution` (reserved field; follow-up clarification)."
|
|
422
|
+
},
|
|
423
|
+
"crossHostCausation": {
|
|
424
|
+
"type": "object",
|
|
425
|
+
"description": "RFC 0040 §D — Phase 3 cross-host causation linking. When advertised, the host honors the cross-host `causationId` extension (a `causationHostId` field on event payloads pointing at the originating host), W3C `traceparent` propagation across MCP + A2A composition boundaries, and (when `ancestryEndpointSupported: true`) the `GET /v1/runs/{runId}/ancestry` cross-host parent-chain endpoint. Hosts advertising `version: 3` MUST advertise this sub-block with `supported: true` and a stable `hostId`.",
|
|
426
|
+
"additionalProperties": false,
|
|
427
|
+
"required": ["supported"],
|
|
428
|
+
"properties": {
|
|
429
|
+
"supported": {
|
|
430
|
+
"type": "boolean",
|
|
431
|
+
"description": "Host implements RFC 0040 Phase 3 cross-host causation contracts."
|
|
432
|
+
},
|
|
433
|
+
"hostId": {
|
|
434
|
+
"type": "string",
|
|
435
|
+
"minLength": 1,
|
|
436
|
+
"description": "Stable identifier for this host instance, used as the `causationHostId` value on cross-host events. SHOULD be a URL or DNS-style identifier (e.g., `myndhyve.ai/workflow-runtime`); the protocol does not normate a stricter format."
|
|
437
|
+
},
|
|
438
|
+
"ancestryEndpointSupported": {
|
|
439
|
+
"type": "boolean",
|
|
440
|
+
"description": "Host serves `GET /v1/runs/{runId}/ancestry` returning the cross-host parent chain per RFC 0040 §C. Optional even when crossHostCausation.supported is true — hosts that emit `causationHostId` but don't expose the ancestry-walking endpoint still satisfy the per-event chaining contract; this flag advertises the additional endpoint."
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
"replayDeterminism": {
|
|
445
|
+
"type": "object",
|
|
446
|
+
"description": "RFC 0041 §D — Phase 4 replay determinism. When advertised, the host honors the LLM cache-key recipe in `replay.md` §\"LLM cache-key recipe\" as NORMATIVE (graduated from informative for version >= 4), emits `replay.divergedAtRefusal` events + fails with `replay_diverged_at_refusal` on refusal-divergence (RFC 0041 §B), and guarantees observable-output-sequence determinism per RFC 0041 §C. Hosts advertising `version: 4` MUST advertise this sub-block with `supported: true`.",
|
|
447
|
+
"additionalProperties": false,
|
|
448
|
+
"required": ["supported"],
|
|
449
|
+
"properties": {
|
|
450
|
+
"supported": {
|
|
451
|
+
"type": "boolean",
|
|
452
|
+
"description": "Host implements RFC 0041 Phase 4 replay-determinism contracts."
|
|
453
|
+
},
|
|
454
|
+
"llmCacheKeyRecipe": {
|
|
455
|
+
"type": "string",
|
|
456
|
+
"anyOf": [
|
|
457
|
+
{ "const": "spec-rfc-0041" },
|
|
458
|
+
{ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$" }
|
|
459
|
+
],
|
|
460
|
+
"description": "The LLM cache-key recipe the host honors. `spec-rfc-0041` = the canonical recipe in `replay.md` §\"LLM cache-key recipe\" §A + §B + §C. Vendor-specific recipes use the canonical host-extension namespace string matching `^x-host-<host>-<recipe-name>$` per `spec/v1/host-extensions.md` §\"Canonical prefixes\"; the matching algorithm MUST be documented at the host's discovery doc."
|
|
461
|
+
},
|
|
462
|
+
"refusalDivergenceEmission": {
|
|
463
|
+
"type": "boolean",
|
|
464
|
+
"description": "Host emits `replay.divergedAtRefusal` events + fails replay with `error.code: replay_diverged_at_refusal` per RFC 0041 §B. Hosts advertising `version: 4` MUST set this to `true`."
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
"modelCapabilities": {
|
|
473
|
+
"type": "object",
|
|
474
|
+
"description": "RFC 0031. Host implements model-capability gating + (optional) substitution per `NodeModule.requiredModelCapabilities` + `NodeModule.fallbackModel`. Distinct from `runtimeCapabilities` which gates on HOST capabilities — `modelCapabilities` gates on MODEL capabilities (structured-output support, discriminator-enum support, long-context, native reasoning, function-calling). Absent block = no advertisement; NodeModules' `requiredModelCapabilities` are treated as opaque metadata and dispatch proceeds without checks.",
|
|
475
|
+
"additionalProperties": false,
|
|
476
|
+
"required": ["supported"],
|
|
477
|
+
"properties": {
|
|
478
|
+
"supported": {
|
|
479
|
+
"type": "boolean",
|
|
480
|
+
"description": "Host honors `NodeModule.requiredModelCapabilities` and emits `model.capability.substituted` / `model.capability.insufficient` events per RFC 0031 §B + §D. When `false` or absent, the fields are treated as opaque metadata and dispatch proceeds without capability checks."
|
|
481
|
+
},
|
|
482
|
+
"advertised": {
|
|
483
|
+
"type": "array",
|
|
484
|
+
"items": {
|
|
485
|
+
"type": "string",
|
|
486
|
+
"pattern": "^([a-z][a-z0-9-]*|x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*)$"
|
|
487
|
+
},
|
|
488
|
+
"uniqueItems": true,
|
|
489
|
+
"description": "Capability identifiers the host's active model advertises. Clients MAY introspect this at install time to determine whether their NodeModules' `requiredModelCapabilities` are satisfiable without fallback. Spec-reserved identifiers per RFC 0031 §C: `structured-output`, `discriminator-enum`, `long-context`, `reasoning` (model-native thinking-tokens), `function-calling`. Host-private extensions MUST prefix with `x-host-<host>-`."
|
|
490
|
+
},
|
|
491
|
+
"substitutionSupported": {
|
|
492
|
+
"type": "boolean",
|
|
493
|
+
"description": "Host honors `NodeModule.fallbackModel` substitution per RFC 0031 §B step 3. When `false` or absent, hosts MUST refuse to dispatch (step 4) on any unmet capability — they MUST NOT attempt fallback even when the field is declared on the NodeModule. Recursive fallback is NOT permitted (RFC 0031 §\"Unresolved questions\" #3)."
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
"providerUsage": {
|
|
498
|
+
"type": "object",
|
|
499
|
+
"description": "RFC 0026. Hosts that emit `provider.usage` events after every LLM provider invocation per RFC 0026 §B. The event carries per-call token counts in the durable event log; cost rollup remains in `RunSnapshot.metrics.openwopCost`. Old hosts ignore.",
|
|
500
|
+
"properties": {
|
|
501
|
+
"supported": { "type": "boolean", "description": "Host emits one `provider.usage` event per LLM provider call." },
|
|
502
|
+
"costEstimates": { "type": "boolean", "description": "When true, the host includes `costEstimateUsd` on `provider.usage` events using its internal rate table. When false/absent, only token counts are emitted." },
|
|
503
|
+
"currency": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "Default ISO 4217 currency for `costEstimateUsd` values. When absent, USD is assumed." }
|
|
504
|
+
},
|
|
505
|
+
"required": ["supported"],
|
|
506
|
+
"additionalProperties": false
|
|
507
|
+
},
|
|
213
508
|
"aiProviders": {
|
|
214
509
|
"type": "object",
|
|
215
510
|
"description": "Optional v1 companion to `secrets`. Advertises which AI providers the host's AI-proxy can route to and which permit BYOK.",
|
|
@@ -357,6 +652,11 @@
|
|
|
357
652
|
"type": "integer",
|
|
358
653
|
"minimum": 0,
|
|
359
654
|
"description": "Effective cap on reasoning trace length when verbosity is `summary`. Default 512 tokens."
|
|
655
|
+
},
|
|
656
|
+
"streaming": {
|
|
657
|
+
"type": "boolean",
|
|
658
|
+
"default": false,
|
|
659
|
+
"description": "RFC 0024. When `true`, the host MAY emit `agent.reasoning.delta` events while a reasoning block is still open, in addition to the final `agent.reasoned`. Hosts that omit / `false` this flag emit only the final `agent.reasoned`. Consumers MUST tolerate both modes."
|
|
360
660
|
}
|
|
361
661
|
},
|
|
362
662
|
"additionalProperties": false
|
|
@@ -632,6 +932,96 @@
|
|
|
632
932
|
},
|
|
633
933
|
"additionalProperties": false
|
|
634
934
|
},
|
|
935
|
+
"sandbox": {
|
|
936
|
+
"type": "object",
|
|
937
|
+
"description": "RFC 0035 — Sandbox execution contract for pack-loaded typeIds. Hosts that advertise execute pack-loaded code inside an isolation boundary meeting the 8 failure-mode invariants in spec/v1/host-capabilities.md §'Sandbox execution contract'. Absent block = host does NOT sandbox pack-loaded code and MUST refuse to load any pack whose manifest declares `peerDependencies.host.sandbox: required`.",
|
|
938
|
+
"additionalProperties": false,
|
|
939
|
+
"required": ["supported", "isolationModel"],
|
|
940
|
+
"properties": {
|
|
941
|
+
"supported": {
|
|
942
|
+
"type": "boolean",
|
|
943
|
+
"description": "Host enforces the 8 sandbox failure-mode invariants per spec/v1/host-capabilities.md §'Sandbox execution contract'. When false, host MUST refuse to load packs declaring required sandbox isolation."
|
|
944
|
+
},
|
|
945
|
+
"isolationModel": {
|
|
946
|
+
"type": "string",
|
|
947
|
+
"anyOf": [
|
|
948
|
+
{ "enum": ["wasm", "process", "container", "vm"] },
|
|
949
|
+
{ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$" }
|
|
950
|
+
],
|
|
951
|
+
"description": "Categorical isolation model. `wasm` = WebAssembly sandbox with explicit host imports (e.g., Wasmtime, Wasmer). `process` = OS process boundary with restricted syscalls (e.g., gVisor, seccomp, Landlock). `container` = container runtime boundary (e.g., Firecracker microVM). `vm` = full VM. Vendor-specific isolation models advertise `^x-host-<host>-<key>$` per spec/v1/host-extensions.md §'Canonical prefixes'; documentation lives at the host's discovery doc."
|
|
952
|
+
},
|
|
953
|
+
"allowedHostCalls": {
|
|
954
|
+
"type": "array",
|
|
955
|
+
"items": { "type": "string" },
|
|
956
|
+
"description": "Whitelist of host-call surfaces sandboxed code MAY invoke. Identifiers from the spec-reserved `host.*` capability set or `^x-host-<host>-<key>$` extension namespace. Empty array = pure compute only (no host I/O). Conformance verifies the sandbox refuses unlisted calls (`sandbox_capability_denied`)."
|
|
957
|
+
},
|
|
958
|
+
"memoryLimitBytes": {
|
|
959
|
+
"type": "integer",
|
|
960
|
+
"minimum": 1048576,
|
|
961
|
+
"description": "Per-invocation memory cap (≥ 1 MiB). Host MUST enforce; exceeding fails the node with `sandbox_memory_exceeded`."
|
|
962
|
+
},
|
|
963
|
+
"wallClockLimitMs": {
|
|
964
|
+
"type": "integer",
|
|
965
|
+
"minimum": 100,
|
|
966
|
+
"description": "Per-invocation wall-clock cap (≥ 100 ms). Host MUST enforce; exceeding fails the node with `sandbox_timeout`."
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
"idempotency": {
|
|
971
|
+
"type": "object",
|
|
972
|
+
"description": "RFC 0036 — Multi-region idempotency contract. Optional v1 advertisement. The existing `crossRegion: 'single-region'|'best-effort'|'strict'` categorical claim lives under `capabilities.idempotency.crossRegion` per spec/v1/idempotency.md §'Multi-region idempotency (annex)'. The `multiRegion` sub-block here gives a granular advertisement that hosts SHOULD pair with the categorical `crossRegion` claim.",
|
|
973
|
+
"additionalProperties": true,
|
|
974
|
+
"properties": {
|
|
975
|
+
"multiRegion": {
|
|
976
|
+
"type": "object",
|
|
977
|
+
"additionalProperties": false,
|
|
978
|
+
"required": ["supported"],
|
|
979
|
+
"properties": {
|
|
980
|
+
"supported": {
|
|
981
|
+
"type": "boolean",
|
|
982
|
+
"description": "Host implements cross-region idempotency reconciliation per spec/v1/idempotency.md §'Multi-region reconciliation'. When `true`, an Idempotency-Key write succeeding in region A is read-visible in region B within `replicationLagBoundMs + safetyMargin`."
|
|
983
|
+
},
|
|
984
|
+
"replicationLagBoundMs": {
|
|
985
|
+
"type": "integer",
|
|
986
|
+
"minimum": 0,
|
|
987
|
+
"maximum": 60000,
|
|
988
|
+
"description": "Conservative upper bound on cross-region replication lag (≤ 60s ceiling chosen to keep operator advertisement honest; production cross-region deployments typically run < 10s). Conformance asserts read-visibility after the bound."
|
|
989
|
+
},
|
|
990
|
+
"partitionRecoveryStrategy": {
|
|
991
|
+
"type": "string",
|
|
992
|
+
"anyOf": [
|
|
993
|
+
{ "enum": ["last-writer-wins", "first-writer-wins"] },
|
|
994
|
+
{ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$" }
|
|
995
|
+
],
|
|
996
|
+
"description": "Deterministic resolution rule for conflicting idempotency-key records when a partition healed. `last-writer-wins` / `first-writer-wins` are spec-reserved categorical rules; vendor strategies use `^x-host-<host>-<key>$`. Conformance asserts deterministic resolution actually applies; it does NOT prescribe which strategy a host picks."
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
},
|
|
1002
|
+
"eventLog": {
|
|
1003
|
+
"type": "object",
|
|
1004
|
+
"description": "RFC 0036 — Event-log multi-engine advertisement. Optional v1.",
|
|
1005
|
+
"additionalProperties": false,
|
|
1006
|
+
"properties": {
|
|
1007
|
+
"crossEngineOrdering": {
|
|
1008
|
+
"type": "object",
|
|
1009
|
+
"additionalProperties": false,
|
|
1010
|
+
"required": ["supported"],
|
|
1011
|
+
"properties": {
|
|
1012
|
+
"supported": {
|
|
1013
|
+
"type": "boolean",
|
|
1014
|
+
"description": "Host implements append-ordering guarantees across multiple engine instances writing to the same run's event log. When `true`, two engines appending concurrently converge on a total order any reader observes consistently."
|
|
1015
|
+
},
|
|
1016
|
+
"orderingModel": {
|
|
1017
|
+
"type": "string",
|
|
1018
|
+
"enum": ["lamport", "vector-clock", "global-sequencer"],
|
|
1019
|
+
"description": "Mechanism the host uses to derive the total order. `lamport` = Lamport timestamps on each append. `vector-clock` = per-engine vector counters merged at read. `global-sequencer` = single sequencer assigns monotonic seq numbers (the Postgres reference host's posture)."
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
635
1025
|
"compliance": {
|
|
636
1026
|
"type": "object",
|
|
637
1027
|
"description": "Privacy / compliance behavior advertised to clients (closes O5). Lets consumers know what masking mode is in effect so a `\"[REDACTED]\"` value in event log payloads is recognizable as a server-side mask vs an upstream null.",
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"type": "integer",
|
|
32
32
|
"minimum": 0,
|
|
33
33
|
"description": "Optional reasoning-token count for observability/cost attribution."
|
|
34
|
+
},
|
|
35
|
+
"streamChunks": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": { "type": "string" },
|
|
38
|
+
"description": "RFC 0024. When present, the host MUST emit one `agent.reasoning.delta` event per array entry (in order; `sequence` starts at 0 and increments by 1), THEN emit the closing `agent.reasoned` event whose `reasoning` field equals the concatenation of all `streamChunks`. When absent, only the closing `agent.reasoned` event fires (the pre-RFC-0024 behavior). Gated at conformance test time on `capabilities.agents.reasoning.streaming: true`."
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
}
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["questions"],
|
|
8
8
|
"properties": {
|
|
9
|
+
"reasoning": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "OPTIONAL chain-of-thought field per RFC 0030 §A. Hosts SHOULD instruct the model to populate this with its analytical process before emitting the structured fields when reasoning materially improves output quality. The field is informational only — hosts SHALL NOT route on its contents. Hosts MUST NOT reject envelopes where `reasoning` is absent. Subject to the same SR-1 redaction harness as other envelope payload fields per `ai-envelope.md` §\"Redaction (SR-1 carry-forward)\" and the `envelope-reasoning-secret-redaction` SECURITY invariant."
|
|
12
|
+
},
|
|
9
13
|
"questions": {
|
|
10
14
|
"type": "array",
|
|
11
15
|
"minItems": 1,
|
|
@@ -28,6 +32,11 @@
|
|
|
28
32
|
"schema": {
|
|
29
33
|
"description": "Optional JSON Schema constraining the answer shape (choices, free-text length, etc.). When present, the host's resolve endpoint SHOULD validate the answer against this schema before returning it to the engine.",
|
|
30
34
|
"type": "object"
|
|
35
|
+
},
|
|
36
|
+
"context": {
|
|
37
|
+
"description": "Optional open-shape metadata bag the LLM MAY use to surface per-question UI hints, trace pointers, or related context. Host-defined. The engine treats this as opaque; SR-1 redaction (`ai-envelope.md` §\"Redaction (SR-1 carry-forward)\") walks every payload field recursively, so any BYOK material that ends up here is scrubbed before persistence.",
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": true
|
|
31
40
|
}
|
|
32
41
|
},
|
|
33
42
|
"additionalProperties": false
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["code", "message"],
|
|
8
8
|
"properties": {
|
|
9
|
+
"reasoning": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "OPTIONAL chain-of-thought field per RFC 0030 §A — useful when the model is explaining why it could not produce the requested envelope (the analytical process behind a `validation_failed` or `tool_call_refused` decision). Informational only; hosts SHALL NOT route on contents. Hosts MUST NOT reject envelopes where `reasoning` is absent. Subject to SR-1 redaction per `ai-envelope.md` §\"Redaction\" and the `envelope-reasoning-secret-redaction` invariant."
|
|
12
|
+
},
|
|
9
13
|
"code": {
|
|
10
14
|
"type": "string",
|
|
11
15
|
"minLength": 1,
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["envelopeType"],
|
|
8
8
|
"properties": {
|
|
9
|
+
"reasoning": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "OPTIONAL chain-of-thought field per RFC 0030 §A — useful when the model wants to explain why it's asking for the schema (e.g., uncertainty about a specific kind's shape). Informational only; hosts SHALL NOT route on contents. Hosts MUST NOT reject envelopes where `reasoning` is absent. Subject to SR-1 redaction per `ai-envelope.md` §\"Redaction\" and the `envelope-reasoning-secret-redaction` invariant."
|
|
12
|
+
},
|
|
9
13
|
"envelopeType": {
|
|
10
14
|
"type": "string",
|
|
11
15
|
"minLength": 1,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "string",
|
|
11
11
|
"minLength": 1,
|
|
12
12
|
"maxLength": 256,
|
|
13
|
-
"description": "Envelope kind whose schema delivery the LLM is acknowledging. SHOULD match the `envelopeType` from the preceding `schema.request`. Engines MAY refuse mismatches with `
|
|
13
|
+
"description": "Envelope kind whose schema delivery the LLM is acknowledging. SHOULD match the `envelopeType` from the preceding `schema.request`. Engines MAY refuse mismatches with `envelope_invalid` but are not required to (the LLM's acknowledgement is advisory)."
|
|
14
14
|
},
|
|
15
15
|
"ack": {
|
|
16
16
|
"type": "boolean",
|
|
@@ -160,6 +160,34 @@
|
|
|
160
160
|
"type": "array",
|
|
161
161
|
"items": { "$ref": "#/$defs/SecretRequirement" },
|
|
162
162
|
"description": "Secrets the node needs to execute. Resolved by the host's secret-resolution adapter at dispatch time. Hosts that don't advertise `Capabilities.secrets.supported` MUST refuse to dispatch a node with non-empty `requiresSecrets` and return `credential_unavailable`."
|
|
163
|
+
},
|
|
164
|
+
"requiredModelCapabilities": {
|
|
165
|
+
"type": "array",
|
|
166
|
+
"items": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"pattern": "^([a-z][a-z0-9-]*|x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*)$"
|
|
169
|
+
},
|
|
170
|
+
"uniqueItems": true,
|
|
171
|
+
"maxItems": 32,
|
|
172
|
+
"description": "RFC 0031 §B. Model capabilities this NodeModule requires the active model to advertise in `capabilities.modelCapabilities.advertised[]`. Distinct from `requires`, which gates on HOST capabilities (`capabilities.runtimeCapabilities[]`) — this field gates on MODEL capabilities. Spec-reserved identifiers: `structured-output`, `discriminator-enum`, `long-context`, `reasoning` (model-native thinking-tokens), `function-calling`. Host-private extensions MUST prefix with `x-host-<host>-` per `host-extensions.md` §\"Canonical-prefix table\". Empty array (or absent field) means no model-capability requirements. When the active model does not satisfy the declared set, the host MUST follow the dispatch flow in RFC 0031 §B: substitute to `fallbackModel` (emit `model.capability.substituted`) or refuse (emit `model.capability.insufficient` + terminate with `capability_not_provided`)."
|
|
173
|
+
},
|
|
174
|
+
"fallbackModel": {
|
|
175
|
+
"type": "object",
|
|
176
|
+
"additionalProperties": false,
|
|
177
|
+
"required": ["provider", "model"],
|
|
178
|
+
"description": "RFC 0031 §B. Substitute model coordinates the host MAY use if the active model lacks the declared `requiredModelCapabilities`. When the host substitutes, it MUST emit `model.capability.substituted` per RFC 0031 §D. Absent means no substitution permitted; the host MUST refuse to dispatch with `capability_not_provided` when capabilities are unmet. The fallback is single-shot — if the fallback itself fails capability checks or authentication, the host emits `model.capability.insufficient` with `fallbackAttempted: true` and refuses (no recursive fallback chains per RFC 0031 §\"Unresolved questions\" #3).",
|
|
179
|
+
"properties": {
|
|
180
|
+
"provider": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
183
|
+
"description": "Provider id per `capabilities.aiProviders.supported` (e.g., `anthropic`, `openai`, `gemini`). MUST be in the host's `capabilities.aiProviders.supported[]` for the substitution to fire; otherwise the host emits `model.capability.insufficient` with `fallbackAttempted: true`."
|
|
184
|
+
},
|
|
185
|
+
"model": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"minLength": 1,
|
|
188
|
+
"description": "Provider-stamped model id (e.g., `claude-opus-4-7`, `gpt-5`, `gemini-2.5-pro`)."
|
|
189
|
+
}
|
|
190
|
+
}
|
|
163
191
|
}
|
|
164
192
|
},
|
|
165
193
|
"additionalProperties": false
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
"maxLength": 256
|
|
23
23
|
},
|
|
24
24
|
"description": "Ordered list of worker node-ids OR agent-ids to dispatch. Hosts that interpret entries as node-ids dispatch in DAG order; hosts that interpret as agent-ids resolve to nodes via the run's static DAG."
|
|
25
|
+
},
|
|
26
|
+
"confidence": {
|
|
27
|
+
"type": "number",
|
|
28
|
+
"minimum": 0,
|
|
29
|
+
"maximum": 1,
|
|
30
|
+
"description": "RFC 0039 §A — supervisor's stated confidence in this decision, in [0, 1]. Optional; absent means 'no opinion stated' (NOT low confidence). Hosts advertising `capabilities.multiAgent.executionModel.version >= 2` MUST honor a confidence floor (spec floor 0.5; operator-stricter via `confidenceEscalationFloor`): a decision with `confidence` below the floor MUST escalate via clarify-or-escalate interrupt instead of executing. Pre-Phase-2 hosts ignore the field per forward-compat."
|
|
25
31
|
}
|
|
26
32
|
},
|
|
27
33
|
"additionalProperties": false
|
|
@@ -52,6 +58,12 @@
|
|
|
52
58
|
"type": "string",
|
|
53
59
|
"description": "Optional free-form rationale captured for audit/debug. Common values: `'goal-reached'`, `'max-iterations'`, `'unrecoverable-error'`. Spec does NOT close this enum.",
|
|
54
60
|
"minLength": 1
|
|
61
|
+
},
|
|
62
|
+
"confidence": {
|
|
63
|
+
"type": "number",
|
|
64
|
+
"minimum": 0,
|
|
65
|
+
"maximum": 1,
|
|
66
|
+
"description": "RFC 0039 §A — supervisor's stated confidence in this termination decision, in [0, 1]. Optional; absent means 'no opinion stated' (NOT low confidence). Hosts advertising `capabilities.multiAgent.executionModel.version >= 2` MUST honor a confidence floor as documented on NextWorkerDecision.confidence above; the same MUST applies to TerminateDecision because a confidently-wrong terminate is the same class of failure as a confidently-wrong dispatch."
|
|
55
67
|
}
|
|
56
68
|
},
|
|
57
69
|
"additionalProperties": false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/prompt-kind.schema.json",
|
|
4
|
+
"title": "PromptKind",
|
|
5
|
+
"description": "Role a PromptTemplate plays when composed into an LLM call. Shared $def referenced by every schema that names a prompt kind. Adding a kind here is the single edit needed to introduce one across the corpus. See spec/v1/prompts.md §\"PromptKind\" for the canonical semantics of each value, and RFC 0027 for the rationale behind the four-value choice (vs. an open-ended string).\n\nKind semantics:\n- system: behavior + output discipline; composed as the LLM's system message.\n- user: per-call task prompt; composed as the LLM's user message; the surface variable substitution targets.\n- few-shot: example bodies prepended to the user message OR injected as alternating user/assistant turns per host policy.\n- schema-hint: structured-output schema description injected into the system or user message at compose time.",
|
|
6
|
+
"type": "string",
|
|
7
|
+
"enum": ["system", "user", "few-shot", "schema-hint"]
|
|
8
|
+
}
|