@openwop/openwop-conformance 2.46.36 → 2.46.38
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 +10 -0
- package/README.md +2 -2
- package/coverage.md +1 -1
- package/dist/spec-artifacts.lock.json +2 -2
- package/fixtures/conformance-clarification.json +1 -1
- package/fixtures.md +1 -1
- package/package.json +2 -2
- package/requirements.json +52 -7
- package/scenario-majors.json +5 -2
- package/schemas/CORPUS-STAMP.json +15 -15
- package/src/scenarios/v2-clarification-resume-answers.test.ts +66 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [2.46.38] — 2026-10-31 — Last AI Envelope names out of v2 descriptions
|
|
2
|
+
|
|
3
|
+
- **No suite change.** The cycle carries description-only edits to six v2 schemas and facets, which change the packed `@openwop/spec-artifacts`.
|
|
4
|
+
|
|
5
|
+
## [2.46.37] — 2026-10-31 — One clarification resume value
|
|
6
|
+
|
|
7
|
+
- **New scenario `v2-clarification-resume-answers`.** Gated on `conformance-clarification`: the array `{ answers: [{ id: "q1", answer: "blue" }] }` resolves the clarification with a 2xx and the run completes. Before this, only the form row resolved a plain clarification shape at major 2.
|
|
8
|
+
- **Fixture text.** `fixtures.md` §conformance-clarification and the fixture's description name the array, not the keyed `{answers: {q1}}`.
|
|
9
|
+
- **Coherence.** `v2-retirement-gate` covers the published steward-deletion census: the scan may fall below it, never rise above it, and a new row must match.
|
|
10
|
+
|
|
1
11
|
## [2.46.36] — 2026-10-31 — The AI Envelope is deleted from v2
|
|
2
12
|
|
|
3
13
|
- **Envelope scenarios removed (RFC 0255).** Ten major-2 envelope and A2UI files are deleted, and their ids carry tombstones naming `openwop.correction.v2.5`. `v2-structured-output-advertisement` and `v2-limits-clarification-rounds-advertisement` replace the advertisement files they re-point, with alias rows. Major-1 scenarios are unchanged.
|
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ Each scenario file records its disposition and assertion count in `<report-dir>/
|
|
|
137
137
|
|
|
138
138
|
## What's Covered
|
|
139
139
|
|
|
140
|
-
The current suite has
|
|
140
|
+
The current suite has 664 scenario files under `src/scenarios/`. By target major ([`scenario-majors.json`](./scenario-majors.json)): 224 files run against a v2 host and 455 against a v1 host; 15 of them run at both.
|
|
141
141
|
|
|
142
142
|
The v2 scenarios (`src/scenarios/v2-*.test.ts`) cover, by area:
|
|
143
143
|
|
|
@@ -166,7 +166,7 @@ Three kinds of scenario share the tree:
|
|
|
166
166
|
- **Host** checks drive a live host over HTTP.
|
|
167
167
|
- **Gated** checks run only when the host advertises the family, profile or fixture they need, and otherwise record `inapplicable` or `blocked` with a reason. `--require-behavior` turns an advertised-but-unwitnessable behaviour into a failure.
|
|
168
168
|
|
|
169
|
-
Current source tree:
|
|
169
|
+
Current source tree: 664 scenario files. [`coverage.md`](./coverage.md) maps each spec document and every OpenAPI operation to its scenarios. [`CHANGELOG.md`](./CHANGELOG.md) records when each scenario landed.
|
|
170
170
|
|
|
171
171
|
## How the 2.x suite is built
|
|
172
172
|
|
package/coverage.md
CHANGED
|
@@ -31,7 +31,7 @@ Each scenario that targets major 2 is listed once, under the [`spec/v2/core/`](.
|
|
|
31
31
|
| [`idempotency.md`](../spec/v2/core/idempotency.md) | `v2-durability-recovery.test.ts`, `v2-idempotency-in-flight.test.ts`, `v2-idempotency-key-grammar.test.ts` |
|
|
32
32
|
| [`identity.md`](../spec/v2/core/identity.md) | `auth-challenge-no-oracle.test.ts`, `v2-assurance-downgrade-audited.test.ts`, `v2-auth-challenge.test.ts`, `v2-authorization-advertisement.test.ts`, `v2-bound-id-kinds.test.ts`, `v2-bound-id-path-projection.test.ts`, `v2-id-grammar.test.ts`, `v2-interrupt-token-scheme.test.ts`, `v2-lane-exp-only-bound.test.ts`, `v2-lane-issuer-advertised.test.ts`, `v2-oidc-id-token-audience.test.ts`, `v2-owner-subject-required.test.ts`, `v2-protected-resource-metadata.test.ts`, `v2-revocation-honored.test.ts`, `v2-subject-link-record.test.ts` |
|
|
33
33
|
| [`interop.md`](../spec/v2/core/interop.md) | `otel-mcp-semconv-projection.test.ts`, `v2-a2a-agent-cards.test.ts`, `v2-a2a-client-error-details.test.ts`, `v2-a2a-operation-map.test.ts`, `v2-a2a-push-delivery.test.ts`, `v2-interop-trace-context.test.ts`, `v2-legacy-profiles-absent.test.ts`, `v2-mcp-mount-map.test.ts`, `v2-mcp-tasks.test.ts`, `v2-minimum-version-refused.test.ts`, `v2-mrtr-rounds-ceiling.test.ts`, `v2-negotiation-authenticated.test.ts`, `v2-negotiation-decided-emitted.test.ts`, `v2-negotiation-decided-inbound.test.ts`, `v2-no-transport-advertisement.test.ts`, `v2-refresh-sla.test.ts` |
|
|
34
|
-
| [`interrupt.md`](../spec/v2/core/interrupt.md) | `v2-approval-reject-disposition.test.ts`, `v2-approver-enforced.test.ts`, `v2-callback-url-guarded.test.ts` |
|
|
34
|
+
| [`interrupt.md`](../spec/v2/core/interrupt.md) | `v2-approval-reject-disposition.test.ts`, `v2-approver-enforced.test.ts`, `v2-callback-url-guarded.test.ts`, `v2-clarification-resume-answers.test.ts` |
|
|
35
35
|
| [`node-pack-runtimes.md`](../spec/v2/core/node-pack-runtimes.md) | `v2-node-pack-runtimes-advertisement.test.ts`, `v2-wasm-memory-cap.test.ts`, `v2-wasm-abi-reject.test.ts` |
|
|
36
36
|
| [`oauth.md`](../spec/v2/core/oauth.md) | `v2-credential-interrupt.test.ts`, `v2-credentials-advertisement.test.ts`, `v2-oauth-client-pkce-state-iss.test.ts`, `v2-oauth-mcp-reach-discovery.test.ts` |
|
|
37
37
|
| [`packs.md`](../spec/v2/core/packs.md) | `v2-manifest-ceiling-refused.test.ts`, `v2-manifest-hatch-carried.test.ts`, `v2-peer-dependency-declared.test.ts`, `v2-registry-lifecycle.test.ts`, `v2-ui-plugin-boundary.test.ts`, `v2-ui-plugins-advertisement.test.ts` |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "conformance-clarification",
|
|
3
3
|
"name": "Conformance: Clarification",
|
|
4
4
|
"version": "1.0",
|
|
5
|
-
"description": "Suspends on a clarification interrupt with one fixed question. Resume
|
|
5
|
+
"description": "Suspends on a clarification interrupt with one fixed question. Resume value: {answers: [{id: 'q1', answer: string}]} (interrupt.md §Re-entry and resume values).",
|
|
6
6
|
"nodes": [
|
|
7
7
|
{
|
|
8
8
|
"id": "ask",
|
package/fixtures.md
CHANGED
|
@@ -324,7 +324,7 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
|
|
|
324
324
|
- **Behavior**:
|
|
325
325
|
1. Run starts and reaches a `clarificationGate` node.
|
|
326
326
|
2. Server emits `clarification.requested` carrying `questions: [{id: "q1", question: "What is your favorite color?"}]`.
|
|
327
|
-
3. After client POSTs `{answers: {q1: "blue"}}`, server emits `clarification.resolved`.
|
|
327
|
+
3. After client POSTs `{answers: [{id: "q1", answer: "blue"}]}`, server emits `clarification.resolved`.
|
|
328
328
|
4. Run reaches `completed`.
|
|
329
329
|
- **Terminal status (after resolve)**: `completed`.
|
|
330
330
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "2.46.
|
|
3
|
+
"version": "2.46.38",
|
|
4
4
|
"description": "Black-box conformance suite for OpenWOP hosts (v2 current; v1 scenarios retained for the frozen v1 tree).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"@openwop/spec-artifacts": "file:../spec-artifacts"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@openwop/spec-artifacts": "2.46.
|
|
59
|
+
"@openwop/spec-artifacts": "2.46.38"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/requirements.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"$comment": "GENERATED by conformance/scripts/generate-requirement-registry.mjs — do not edit. One record per it()/test() in src/scenarios. Ids: openwop.it.<file-stem>.<title-slug>[~n] (src/lib/requirement-ids.ts). A record with id null has an interpolated title; its run-time row is keyed by the rendered title and maps here by file+line only. Renamed ids need a row in requirement-aliases.json.",
|
|
3
3
|
"generatedFrom": "src/scenarios/*.test.ts",
|
|
4
4
|
"counts": {
|
|
5
|
-
"files":
|
|
6
|
-
"tests":
|
|
7
|
-
"withStableId":
|
|
5
|
+
"files": 747,
|
|
6
|
+
"tests": 2855,
|
|
7
|
+
"withStableId": 2855,
|
|
8
8
|
"interpolatedTitles": 0,
|
|
9
|
-
"explicitIds":
|
|
9
|
+
"explicitIds": 2725
|
|
10
10
|
},
|
|
11
11
|
"records": [
|
|
12
12
|
{
|
|
@@ -29213,6 +29213,28 @@
|
|
|
29213
29213
|
}
|
|
29214
29214
|
]
|
|
29215
29215
|
},
|
|
29216
|
+
{
|
|
29217
|
+
"id": "openwop.it.v2-clarification-resume-answers.a-clarification-resolves-with-answers-id-answer-and-the-run-completes",
|
|
29218
|
+
"file": "v2-clarification-resume-answers.test.ts",
|
|
29219
|
+
"line": 51,
|
|
29220
|
+
"title": "a clarification resolves with { answers: [{ id, answer }] } and the run completes",
|
|
29221
|
+
"explicitId": "openwop.requirement.interrupt.clarification-resume-answers",
|
|
29222
|
+
"citations": [
|
|
29223
|
+
{
|
|
29224
|
+
"section": "spec/v2/core/interrupt.md §Re-entry and resume values",
|
|
29225
|
+
"requirement": null,
|
|
29226
|
+
"interpolated": true
|
|
29227
|
+
},
|
|
29228
|
+
{
|
|
29229
|
+
"section": "spec/v2/core/interrupt.md §Re-entry and resume values",
|
|
29230
|
+
"requirement": "the resolve MUST be a 2xx"
|
|
29231
|
+
},
|
|
29232
|
+
{
|
|
29233
|
+
"section": "spec/v2/core/interrupt.md §Re-entry and resume values",
|
|
29234
|
+
"requirement": "the resolved run MUST complete"
|
|
29235
|
+
}
|
|
29236
|
+
]
|
|
29237
|
+
},
|
|
29216
29238
|
{
|
|
29217
29239
|
"id": "openwop.it.v2-client-version-header.a-client-at-the-floor-is-not-below-it-equal-on-major-minor-the-patch-never-decid",
|
|
29218
29240
|
"file": "v2-client-version-header.test.ts",
|
|
@@ -48822,13 +48844,36 @@
|
|
|
48822
48844
|
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48823
48845
|
"requirement": null,
|
|
48824
48846
|
"interpolated": true
|
|
48847
|
+
},
|
|
48848
|
+
{
|
|
48849
|
+
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48850
|
+
"requirement": null,
|
|
48851
|
+
"interpolated": true
|
|
48852
|
+
},
|
|
48853
|
+
{
|
|
48854
|
+
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48855
|
+
"requirement": "the report must still show typed and scanned side by side"
|
|
48856
|
+
},
|
|
48857
|
+
{
|
|
48858
|
+
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48859
|
+
"requirement": null,
|
|
48860
|
+
"interpolated": true
|
|
48861
|
+
},
|
|
48862
|
+
{
|
|
48863
|
+
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48864
|
+
"requirement": null,
|
|
48865
|
+
"interpolated": true
|
|
48866
|
+
},
|
|
48867
|
+
{
|
|
48868
|
+
"section": "COMPATIBILITY.md §3a (RFC 0255 §D)",
|
|
48869
|
+
"requirement": "the refusal must say the scan may not rise above the census"
|
|
48825
48870
|
}
|
|
48826
48871
|
]
|
|
48827
48872
|
},
|
|
48828
48873
|
{
|
|
48829
48874
|
"id": "openwop.it.v2-retirement-gate.a-new-row-is-refused-while-the-interop-matrix-names-an-independent-host",
|
|
48830
48875
|
"file": "v2-retirement-gate.test.ts",
|
|
48831
|
-
"line":
|
|
48876
|
+
"line": 272,
|
|
48832
48877
|
"title": "a new row is REFUSED while the INTEROP-MATRIX names an independent host",
|
|
48833
48878
|
"explicitId": "openwop.requirement.0255.steward-deletion-licence",
|
|
48834
48879
|
"citations": [
|
|
@@ -48846,7 +48891,7 @@
|
|
|
48846
48891
|
{
|
|
48847
48892
|
"id": "openwop.it.v2-retirement-gate.a-new-row-is-refused-while-a-committed-bundle-comes-from-an-origin-nobody-lists",
|
|
48848
48893
|
"file": "v2-retirement-gate.test.ts",
|
|
48849
|
-
"line":
|
|
48894
|
+
"line": 279,
|
|
48850
48895
|
"title": "a new row is REFUSED while a committed bundle comes from an origin nobody lists",
|
|
48851
48896
|
"explicitId": "openwop.requirement.0255.steward-deletion-licence",
|
|
48852
48897
|
"citations": [
|
|
@@ -48864,7 +48909,7 @@
|
|
|
48864
48909
|
{
|
|
48865
48910
|
"id": "openwop.it.v2-retirement-gate.a-row-removing-a-reader-for-persisted-data-is-refused-and-so-is-one-naming-no-rf",
|
|
48866
48911
|
"file": "v2-retirement-gate.test.ts",
|
|
48867
|
-
"line":
|
|
48912
|
+
"line": 286,
|
|
48868
48913
|
"title": "a row removing a reader for persisted data is REFUSED, and so is one naming no RFC",
|
|
48869
48914
|
"explicitId": "openwop.requirement.0255.steward-deletion-licence",
|
|
48870
48915
|
"citations": [
|
package/scenario-majors.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "GENERATED by conformance/scripts/generate-scenario-majors.mjs (RFC 0168 §D.3). Do not edit; add a file to BOTH_MAJORS in the generator to target both majors.",
|
|
3
3
|
"counts": {
|
|
4
|
-
"files":
|
|
4
|
+
"files": 664,
|
|
5
5
|
"v1": 455,
|
|
6
|
-
"v2":
|
|
6
|
+
"v2": 224
|
|
7
7
|
},
|
|
8
8
|
"majors": {
|
|
9
9
|
"a2a-1-0-agent-card.test.ts": [
|
|
@@ -1374,6 +1374,9 @@
|
|
|
1374
1374
|
"v2-channel-presence-delivery.test.ts": [
|
|
1375
1375
|
2
|
|
1376
1376
|
],
|
|
1377
|
+
"v2-clarification-resume-answers.test.ts": [
|
|
1378
|
+
2
|
|
1379
|
+
],
|
|
1377
1380
|
"v2-client-version-header.test.ts": [
|
|
1378
1381
|
2
|
|
1379
1382
|
],
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "Provenance of @openwop/spec-artifacts (RFC 0168 §D.2). files: SHA-256 per file; the conformance suite compares the installed peer against dist/spec-artifacts.lock.json at start.",
|
|
3
3
|
"package": "@openwop/spec-artifacts",
|
|
4
|
-
"version": "2.46.
|
|
5
|
-
"corpusTag": "v2.46.
|
|
4
|
+
"version": "2.46.38",
|
|
5
|
+
"corpusTag": "v2.46.38",
|
|
6
6
|
"files": {
|
|
7
7
|
"api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
|
|
8
8
|
"api/asyncapi.yaml": "d5ecb9ee6114582be3b1f662c84bfac9ae96dae7bacb853e461168f70a8e1c7d",
|
|
9
9
|
"api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
|
|
10
10
|
"api/openapi.yaml": "ac6de5303872664b78ff419c035915593e01599e02835e777a0123de1baeb398",
|
|
11
11
|
"api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
|
|
12
|
-
"api/seams-v2.yaml": "
|
|
13
|
-
"api/v2/asyncapi.yaml": "
|
|
14
|
-
"api/v2/openapi.yaml": "
|
|
12
|
+
"api/seams-v2.yaml": "27a3edfe025994989a2296f3d5d4a0c52d8e1ce924a8f450a0dddc5ad736d8ff",
|
|
13
|
+
"api/v2/asyncapi.yaml": "9f06497fcd4d96f96aacb59d43e88f6f1126c5f52846c9d3d0704bce458de6ae",
|
|
14
|
+
"api/v2/openapi.yaml": "46bbe19ff9bc87b9c3155dc6fd49a9af6bb8a154edf40df9edb6aeaf26f7b770",
|
|
15
15
|
"api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
|
|
16
16
|
"schemas/README.md": "276fc1d51eb08e14e9127b9fd27761d7046ee33c12000f3a64a801322db8bf58",
|
|
17
17
|
"schemas/a2a-task-state.schema.json": "75d5049dea8bd873ff0e7546f1c60c8d36c219bec7084264360be54a8be30ae1",
|
|
@@ -115,11 +115,11 @@
|
|
|
115
115
|
"schemas/v2/artifact.schema.json": "85b9dc284d39b99d2a66fa8cbf47f2dd3d8526d3bd6cc411ad315b372de38975",
|
|
116
116
|
"schemas/v2/audit-verify-result.schema.json": "14af8e9283510f0a40e48a2059c929ee44e0fc9fa3cc66a95bfbe90b17c48297",
|
|
117
117
|
"schemas/v2/budget-policy.schema.json": "1de68095db0beb5c7a4be629de26e79f62ebbe748a88d46f36e768edfd1f0d68",
|
|
118
|
-
"schemas/v2/capabilities.schema.json": "
|
|
118
|
+
"schemas/v2/capabilities.schema.json": "4ec06ca94cc9314aa2331916738c12f329bd28c7efb7d3ddfde75b2055bbb05c",
|
|
119
119
|
"schemas/v2/certification-bundle.schema.json": "29d2ff33d8256d8729cd4914e2ecff5ff07afc310264e2db483a9c0ae13df2a6",
|
|
120
120
|
"schemas/v2/channel-presence-payload.schema.json": "fc03df0c20cc12a25f7ee6a47503a4c5931d79fe3d5ff24815e8fd7c1bcb9a87",
|
|
121
121
|
"schemas/v2/channel-written-payload.schema.json": "ccecff3c71a3275ad8db035ac0e04db25e6f8d23cf091ddbcd5a60d1be1cbb6b",
|
|
122
|
-
"schemas/v2/chat-card-pack-manifest.schema.json": "
|
|
122
|
+
"schemas/v2/chat-card-pack-manifest.schema.json": "9cf235f5d0fe662f34f7e72bfbf2a82e0743046059a9d5af7aec948e228fdb0e",
|
|
123
123
|
"schemas/v2/compact-tool-descriptor.schema.json": "b5c418d72082d5b713bf318212a83397e5be98e56d25ca056302b41b8dd8273b",
|
|
124
124
|
"schemas/v2/compensation-policy.schema.json": "b3c1142637f5bf980f2b0bb67adb47e8cb7abb99a0405a4b6816ccf5d9c089d6",
|
|
125
125
|
"schemas/v2/compensation-projection.schema.json": "f46977c7076347b5473faa8c4bbe73d8321c33b33c98fff2f26ee7cbada4ed98",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"schemas/v2/orchestrator-decision.schema.json": "503b9b28109d875ec7a1acccb45447312a6b1c7d5f4175a9f43c8338d37bd1b1",
|
|
156
156
|
"schemas/v2/org-chart-responsibility-view.schema.json": "8a2565e4cdc6737a3946a70799f93642808b92f9c8d56dcdff3a0782053b89a1",
|
|
157
157
|
"schemas/v2/pack-lockfile.schema.json": "2685417702c105146b780cd99154296a46578fbb10d81c8c713348ee26fea898",
|
|
158
|
-
"schemas/v2/part.schema.json": "
|
|
158
|
+
"schemas/v2/part.schema.json": "c160cb50a80c0efcaa1f5959f8c57ee045e180f86c72d36b017f8eb1ba257e0d",
|
|
159
159
|
"schemas/v2/prompt-kind.schema.json": "67251c937a5a91fb97c0422050e808dc0c162a9b8561366814cf87b0a7f62e00",
|
|
160
160
|
"schemas/v2/prompt-pack-manifest.schema.json": "752407469475396ad250085437a6cc6bd56a017ac6d3e52196aecc65dda4e51a",
|
|
161
161
|
"schemas/v2/prompt-ref.schema.json": "8288495bf353fbc158cef6525d16dd1dcd9373941d15ec072044f05d143355d0",
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"schemas/v2/residency.schema.json": "3fd23c9732beb140504e81560fc426eb6764d547e56da5fb92c5a5c7bf04db3a",
|
|
170
170
|
"schemas/v2/run-ancestry-response.schema.json": "334c17f2062dea62726ca1d07b8be3f169cdc422af843c1def5fb317039814c9",
|
|
171
171
|
"schemas/v2/run-diff-response.schema.json": "8bdb2045c274580038bd74781f7d062f5049839797c164a89de4ed89edc53a74",
|
|
172
|
-
"schemas/v2/run-event-payloads.schema.json": "
|
|
172
|
+
"schemas/v2/run-event-payloads.schema.json": "9d69dc614ff93294d4a0174e144346c0d846dfb4b2863b27a39058dadc3cdf1c",
|
|
173
173
|
"schemas/v2/run-event.schema.json": "2f0d7416bd376c56affe97b6b2b49981532e8e9ff45c0a162cf806c78b3e7fb7",
|
|
174
174
|
"schemas/v2/run-list-response.schema.json": "c2dbc34768dcf64528914a213aa3cb55952e8e3e90a64b04a9423b2a19749d38",
|
|
175
175
|
"schemas/v2/run-options.schema.json": "f0e9f494d80086c2ed2cf9fe87df54e5b4e66601699c4a1089f4edbc7ba58867",
|
|
@@ -203,7 +203,7 @@
|
|
|
203
203
|
"schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
|
|
204
204
|
"spec/v1/alias-detectors.json": "202a443678e592a515e33aad7f6ab679a07d8408809f2d4b0f59d156c84ffc65",
|
|
205
205
|
"spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
|
|
206
|
-
"spec/v1/core-standard-manifest.json": "
|
|
206
|
+
"spec/v1/core-standard-manifest.json": "3fcea0739a3d914b30dcbc2f001c25d3fee12aea5402369522bad7bfc5c8b691",
|
|
207
207
|
"spec/v1/deprecations.json": "901fdab0a7212627f1838cbb06ae7b7204f0dff528299e56d3d938deecea27c1",
|
|
208
208
|
"spec/v1/deprecations.schema.json": "3e393c405d2a41b467d8c5e3c468549078df1ce6a6d2588fc488097b95d9b55b",
|
|
209
209
|
"spec/v1/end-of-support.json": "35f0bf3b70fe78b16e2a2fd81a153fc27e703f6c16376c6fe7cdf1f4f2c4e6d4",
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
"spec/v2/core/idempotency.md": "adbd317a6ebb57c2759c076297b31f67def9e391576bccd0bbea787b13e85872",
|
|
233
233
|
"spec/v2/core/identity.md": "3447f4bec0e4780a3b32b0039d9a0ae1d85de5a71166a4d7e2d3d68b09d55129",
|
|
234
234
|
"spec/v2/core/interop.md": "78d7944c8955412a570f14b84bf74ed4e0ef5dec6680e1cb538c3329a4aa778b",
|
|
235
|
-
"spec/v2/core/interrupt.md": "
|
|
235
|
+
"spec/v2/core/interrupt.md": "3f003b6825ec394ebff1605471fddeabe19aa2c7c370332fb4defd443645f526",
|
|
236
236
|
"spec/v2/core/node-pack-runtimes.md": "0a269d2b36477870d45bdd2e7e34fea9dfd428e2e59e6cc7cbc0c67f3147a9ee",
|
|
237
237
|
"spec/v2/core/oauth.md": "9bdbdc85ad2ff4c1f578730edba3a79a6ce111f0335f90feb06863c8e823a23f",
|
|
238
238
|
"spec/v2/core/overview.md": "593c2ac434952f08c6f552e1b77780541906fe5ffdeb911133f6402075e65e72",
|
|
@@ -276,7 +276,7 @@
|
|
|
276
276
|
"spec/v2/ext/webResearch/README.md": "2771686719161b811c2a50361815a334c58f09e442528fb8e23e4fcdcd42d630",
|
|
277
277
|
"spec/v2/facets/a2a.schema.json": "b68bf5e29e455e46c2ad7cfcccf5963730ec2310ff9db81884550d8df30fd6ef",
|
|
278
278
|
"spec/v2/facets/agents.schema.json": "cc9abae19f500b8a2c6f2b3494284f6f9bb782cde7eec13e4f2f5363a1b44ad5",
|
|
279
|
-
"spec/v2/facets/aiProviders.schema.json": "
|
|
279
|
+
"spec/v2/facets/aiProviders.schema.json": "cb2638174c233835203408f78a18da72a9e7aaa240a29220fc709dd43c6930c4",
|
|
280
280
|
"spec/v2/facets/auditLogIntegrity.schema.json": "9a7f81320c8f940c6f4129bc7dd895a4063231c5458a717a08c2cbf9bb886c46",
|
|
281
281
|
"spec/v2/facets/auth.schema.json": "7d98bc81a0f7d307460d039eebfebd21388091bfe1d538762583940f94c0bd2a",
|
|
282
282
|
"spec/v2/facets/connections.schema.json": "f998bb206a5814183bb4720cc34fa43b7ab64d61e39a79437b009c589ce8b78e",
|
|
@@ -305,9 +305,9 @@
|
|
|
305
305
|
"spec/v2/path-manifest.json": "20f598f56df460ad3ed50aba3d6bc2933ea16a3c96ce125da1c5dd6989d4155c",
|
|
306
306
|
"spec/v2/peer-dependency-aliases.json": "cbf62f551f9295b0ac7ba6cc0466abb153563354a57b0622f3ec6e6689cba47e",
|
|
307
307
|
"spec/v2/profiles.json": "b382b261c7844798575f7c1b37c934f0da19846016a2337d883d4f5ef6e05479",
|
|
308
|
-
"spec/v2/release.json": "
|
|
308
|
+
"spec/v2/release.json": "7e083fce19c55779cca6f89f30a511127519b4da544c488b83075ba23fc58e18",
|
|
309
309
|
"spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
|
|
310
|
-
"spec/v2/surface-baseline.json": "
|
|
310
|
+
"spec/v2/surface-baseline.json": "bf4bfd1310b78e3307534a0867f7601c39fc988d1659979753188f35fd627f62"
|
|
311
311
|
},
|
|
312
|
-
"corpusCommit": "
|
|
312
|
+
"corpusCommit": "8dd71a2ff82f90e1369b8aac9132d1bd1b9d27c6"
|
|
313
313
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `spec/v2/core/interrupt.md` §"Re-entry and resume values" — a host MUST accept
|
|
3
|
+
* `{ answers: [{ id, answer }] }`, each `id` a `questions[].id`, as a
|
|
4
|
+
* `clarification` resume value, with or without a form (suite 2.46.37, target
|
|
5
|
+
* major 2; one run created).
|
|
6
|
+
*
|
|
7
|
+
* Until 2.46.37 `fixtures.md` taught `{answers: {q1: "blue"}}` for
|
|
8
|
+
* `conformance-clarification`, and only the form row (`v2-interrupt-form-rules`)
|
|
9
|
+
* resolved a clarification with the array at major 2. A host can take the keyed
|
|
10
|
+
* object from the fixture text and refuse the array, as the v2 reference host
|
|
11
|
+
* did until openwop-examples#179.
|
|
12
|
+
*
|
|
13
|
+
* Leg: `conformance-clarification` suspends `waiting-input` with question `q1`;
|
|
14
|
+
* `{ answers: [{ id: "q1", answer: "blue" }] }` resolves it with a 2xx; the run
|
|
15
|
+
* completes. A host not advertising the fixture records the leg `inapplicable`.
|
|
16
|
+
*
|
|
17
|
+
* @see spec/v2/core/interrupt.md §Re-entry and resume values
|
|
18
|
+
* @see conformance/fixtures.md §conformance-clarification
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { describe, it, expect } from 'vitest';
|
|
22
|
+
import { driver, type OpenWOPResponse } from '../lib/driver.js';
|
|
23
|
+
import { v2Discovery } from '../lib/v2.js';
|
|
24
|
+
import { isFixtureAdvertised } from '../lib/fixtures.js';
|
|
25
|
+
import { readErrorCode } from '../lib/error-envelope.js';
|
|
26
|
+
import { softSkip } from '../lib/soft-skip.js';
|
|
27
|
+
import { req } from '../lib/requirement-ids.js';
|
|
28
|
+
|
|
29
|
+
const DOC = 'spec/v2/core/interrupt.md §Re-entry and resume values';
|
|
30
|
+
const ID = 'openwop.requirement.interrupt.clarification-resume-answers';
|
|
31
|
+
const FIXTURE = 'conformance-clarification';
|
|
32
|
+
const NODE = 'ask';
|
|
33
|
+
const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
|
|
34
|
+
|
|
35
|
+
const enc = (id: string): string => encodeURIComponent(id);
|
|
36
|
+
async function http(fn: () => Promise<OpenWOPResponse>): Promise<OpenWOPResponse | null> { try { return await fn(); } catch { return null; } }
|
|
37
|
+
|
|
38
|
+
/** Wait until the run is terminal or suspended (any `waiting-*`), or `ms` elapses. */
|
|
39
|
+
async function settle(runId: string, ms = 10_000): Promise<string | null> {
|
|
40
|
+
const end = Date.now() + ms;
|
|
41
|
+
for (;;) {
|
|
42
|
+
const r = await http(() => driver.get(`/runs/${enc(runId)}`));
|
|
43
|
+
const s = r?.status === 200 ? String((r.json as { status?: unknown } | null)?.status ?? '') : null;
|
|
44
|
+
if (s !== null && (TERMINAL.has(s) || s.startsWith('waiting-'))) return s;
|
|
45
|
+
if (Date.now() > end) return s;
|
|
46
|
+
await new Promise((ok) => setTimeout(ok, 200));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe('v2 clarification resume value (interrupt.md §Re-entry and resume values)', () => {
|
|
51
|
+
it('a clarification resolves with { answers: [{ id, answer }] } and the run completes', async () => {
|
|
52
|
+
if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', `${FIXTURE} is not advertised — the suite cannot raise a clarification`);
|
|
53
|
+
try { await v2Discovery(); } catch { return softSkip('blocked', 'v2 discovery unreachable'); }
|
|
54
|
+
const create = await http(() => driver.post('/runs', { workflowId: FIXTURE }));
|
|
55
|
+
if (create === null) return softSkip('blocked', 'POST /runs unreachable (fetch failed)');
|
|
56
|
+
const runId = (create.json as { runId?: unknown } | null)?.runId;
|
|
57
|
+
if (create.status !== 201 || typeof runId !== 'string') return softSkip('blocked', `POST /runs (${FIXTURE}) answered ${create.status} ${readErrorCode(create.json) ?? ''}`.trim());
|
|
58
|
+
const suspended = await settle(runId);
|
|
59
|
+
if (suspended !== 'waiting-input') return softSkip('blocked', `the ${FIXTURE} run did not suspend waiting-input (status ${String(suspended)})`);
|
|
60
|
+
const res = await http(() => driver.post(`/runs/${enc(runId)}/interrupts/${NODE}`, { resumeValue: { answers: [{ id: 'q1', answer: 'blue' }] } }));
|
|
61
|
+
if (res === null) return softSkip('blocked', 'the resolve was unreachable (fetch failed)');
|
|
62
|
+
expect(res.status, req(ID, DOC, `a clarification resolve carrying { answers: [{ id, answer }] } MUST be accepted (got ${res.status} ${readErrorCode(res.json) ?? ''})`)).toBeGreaterThanOrEqual(200);
|
|
63
|
+
expect(res.status, req(ID, DOC, 'the resolve MUST be a 2xx')).toBeLessThan(300);
|
|
64
|
+
expect(await settle(runId), req(ID, DOC, 'the resolved run MUST complete')).toBe('completed');
|
|
65
|
+
});
|
|
66
|
+
});
|