@openwop/openwop-conformance 2.0.0-rc.38 → 2.0.0-rc.39
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@openwop/spec-artifacts",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
4
|
-
"stampSha256": "
|
|
3
|
+
"version": "2.0.0-rc.39",
|
|
4
|
+
"stampSha256": "48fe38e1460f068bcfbfd25df16894cca8ad480378f66bc1c8ef154e9c6c412c"
|
|
5
5
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.39",
|
|
4
4
|
"description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
|
|
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.0.0-rc.
|
|
59
|
+
"@openwop/spec-artifacts": "2.0.0-rc.39"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/requirements.json
CHANGED
|
@@ -25810,7 +25810,7 @@
|
|
|
25810
25810
|
{
|
|
25811
25811
|
"id": "openwop.it.v2-advertised-path-space-served.a-host-advertising-major-2-reaches-the-surfaces-it-already-serves-under-v1",
|
|
25812
25812
|
"file": "v2-advertised-path-space-served.test.ts",
|
|
25813
|
-
"line":
|
|
25813
|
+
"line": 107,
|
|
25814
25814
|
"title": "a host advertising major 2 reaches the surfaces it already serves under /v1",
|
|
25815
25815
|
"explicitId": null,
|
|
25816
25816
|
"citations": [
|
|
@@ -1,7 +1,7 @@
|
|
|
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.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.39",
|
|
5
5
|
"corpusTag": null,
|
|
6
6
|
"files": {
|
|
7
7
|
"api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
|
|
10
10
|
"api/openapi.yaml": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
|
|
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": "23904b23283a4ee111c5289eff8902bf22319dfd804310e47a9f2928ef669aac",
|
|
13
|
+
"api/v2/asyncapi.yaml": "40b9caf405de92acdfb57952809b77585f61a8696ef369afcdb675e6cad5b4ad",
|
|
14
|
+
"api/v2/openapi.yaml": "348a67f3bc5813f0ec2553338fc40829695b5aad2dc512a21ac0dca048ec15a7",
|
|
15
15
|
"api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
|
|
16
16
|
"schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
|
|
17
17
|
"schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
|
|
200
200
|
"spec/v1/alias-detectors.json": "fee4594ef49953953ffcd0b3813300067d16b3e65ebff2aac722034ac9b3f545",
|
|
201
201
|
"spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
|
|
202
|
-
"spec/v1/core-standard-manifest.json": "
|
|
202
|
+
"spec/v1/core-standard-manifest.json": "5a18865afd4cce904be3cf41f9f3d3f408806a7310015f91fe8b740db4050817",
|
|
203
203
|
"spec/v1/deprecations.json": "1d5acb69a9b8ccb57275a95605f74aef1d920685f8407c9d382a46b59dc803bb",
|
|
204
204
|
"spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
|
|
205
205
|
"spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
"spec/v2/path-manifest.json": "034152e09b1458c66810d4050e20a273b2b9b8fe2d92b66e8b819477de58a1be",
|
|
231
231
|
"spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
|
|
232
232
|
"spec/v2/profiles.json": "1f0ee40491131cf561ef19a0394c47ba476b4567514fe16befb6cada4a10a5a4",
|
|
233
|
-
"spec/v2/release.json": "
|
|
233
|
+
"spec/v2/release.json": "1b7a260912de2445ebf11ec2a88be4e16f0ca19b64a297ced18dce1088fe1d95"
|
|
234
234
|
},
|
|
235
|
-
"corpusCommit": "
|
|
235
|
+
"corpusCommit": "29863c56a13b476152ced906d14396ce143ecbe9"
|
|
236
236
|
}
|
|
@@ -54,7 +54,7 @@ const DOC = 'spec/v2/core/versioning.md §1.2';
|
|
|
54
54
|
/** The well-known resource is the one the HEADER selects; it has no /v1 twin to pair against. */
|
|
55
55
|
const NOT_PAIRABLE = new Set(['/.well-known/openwop']);
|
|
56
56
|
|
|
57
|
-
interface Probe { readonly status: number | null }
|
|
57
|
+
interface Probe { readonly status: number | null; readonly version: string | null; readonly html: boolean }
|
|
58
58
|
|
|
59
59
|
async function get(path: string, major2: boolean): Promise<Probe> {
|
|
60
60
|
const { baseUrl, apiKey } = loadEnv();
|
|
@@ -63,12 +63,32 @@ async function get(path: string, major2: boolean): Promise<Probe> {
|
|
|
63
63
|
if (apiKey) headers['authorization'] = `Bearer ${apiKey}`;
|
|
64
64
|
try {
|
|
65
65
|
const res = await fetch(`${baseUrl.replace(/\/$/, '')}${path}`, { headers });
|
|
66
|
-
|
|
66
|
+
const ct = res.headers.get('content-type') ?? '';
|
|
67
|
+
return { status: res.status, version: res.headers.get('openwop-version'), html: /text\/html/i.test(ct) };
|
|
67
68
|
} catch {
|
|
68
|
-
return { status: null };
|
|
69
|
+
return { status: null, version: null, html: false };
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* "Reached under major 2" is NOT "any status but 404". A hosting layer in
|
|
75
|
+
* front of the host answers every unrouted path with `200 text/html` — the
|
|
76
|
+
* SPA shell — and no `OpenWOP-Version` header, and that satisfied the first
|
|
77
|
+
* version of this check. Measured 2026-09-05 on a tier-1 host's public origin:
|
|
78
|
+
* `/.well-known/openwop` and `/v1/**` were rewritten to the backend and every
|
|
79
|
+
* unversioned major-2 path fell through to `index.html` with a 200, while the
|
|
80
|
+
* Cloud Run URL one hop behind answered every one correctly. The scenario was
|
|
81
|
+
* green on production for ten hours because a shell and a mount produced the
|
|
82
|
+
* same status code. `versioning.md` §1.4 requires `OpenWOP-Version` on every
|
|
83
|
+
* response; a response without it did not come from the host.
|
|
84
|
+
*/
|
|
85
|
+
function reachedUnderMajor2(p: Probe): boolean {
|
|
86
|
+
if (p.status === null || p.status === 404) return false;
|
|
87
|
+
if (p.version === null) return false;
|
|
88
|
+
if (p.html) return false;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
72
92
|
function parameterlessGets(): string[] {
|
|
73
93
|
try {
|
|
74
94
|
const manifest = JSON.parse(
|
|
@@ -117,10 +137,15 @@ describe('v2-advertised-path-space-served (RFC 0172 §A.1)', () => {
|
|
|
117
137
|
|
|
118
138
|
const v2 = await get(path, true);
|
|
119
139
|
if (v2.status === null) return softSkip('blocked', `the host became unreachable while probing ${path}`);
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
140
|
+
// 401/403/422 all answer "this path exists" and count as reached. A 404
|
|
141
|
+
// does not — and neither does a 200 that did not come from the host: no
|
|
142
|
+
// OpenWOP-Version header, or an HTML body, is a hosting fallback wearing
|
|
143
|
+
// a success code (see reachedUnderMajor2).
|
|
144
|
+
if (!reachedUnderMajor2(v2)) {
|
|
145
|
+
overstated.push(`${path} (/v1 → ${v1.status}, major 2 → ${v2.status}${v2.version === null ? ', no OpenWOP-Version header' : ''}${v2.html ? ', text/html body' : ''})`);
|
|
146
|
+
} else {
|
|
147
|
+
served.push(path);
|
|
148
|
+
}
|
|
124
149
|
}
|
|
125
150
|
|
|
126
151
|
if (pairable === 0) {
|