@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.38",
4
- "stampSha256": "3fe6266c2542cbeb718b22938297cba87b0deb4567b213dbef983a51d2b35155"
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.38",
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.38"
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": 87,
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.38",
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": "6a9d80a1b6e0854f31a49d3cf24b74c9f9d7fb3bf667fa4fafbad0b6d5587cfc",
13
- "api/v2/asyncapi.yaml": "593e3bbe491f22b16e814feba6612e3bbdf94b95bbec9257fbf68eb0e5ae185f",
14
- "api/v2/openapi.yaml": "975bdab57e6ce837a615e32f4284b1de9701155dcdf208b89da28cc9a9839330",
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": "3ac636a1fa387e3aede5648e1d002873c74ebb90f14aa23cc766fb293c24b38f",
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": "fa794ab0e06c4a574b7bbd8a207dc131c024ce8ca460e1add3a48659bd35e146"
233
+ "spec/v2/release.json": "1b7a260912de2445ebf11ec2a88be4e16f0ca19b64a297ced18dce1088fe1d95"
234
234
  },
235
- "corpusCommit": "16c4d2ac92f8af03452ab80880211bbd274eda0d"
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
- return { status: res.status };
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
- // Any status but 404 means the route is MOUNTED 401/403/422 all answer
121
- // "this path exists". Only 404 says major 2 cannot reach it.
122
- if (v2.status === 404) overstated.push(`${path} (/v1 → ${v1.status}, major 2 404)`);
123
- else served.push(path);
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) {