@openwop/openwop-conformance 2.45.27 → 2.45.28

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # `@openwop/openwop-conformance` Changelog
2
2
 
3
+ ## [2.45.28] — 2026-10-08 — two more seam-driven legs, and the backoff ratio, on a public seam-free cut
4
+
5
+ - **Found by the v2 reference host's first public seams-off cut** (2.45.27, RFC 0241's evidence): all seven target rows `executed-pass`, but four other rows kept the bundle from certifying. Neither shows on a loopback cut.
6
+ - **`0199.mcp-url-mode` (`v2-mcp-mount-map`) and `0199.a2a-auth-required` (`v2-a2a-operation-map`):** both mint a fresh Subject through the credential mint seam, without checking for the seams profile, and recorded `blocked` when it was absent. They run only where `oauth.credentialInterrupt` is advertised, which this host does only with an https public base. Now `inapplicable` without the seams profile.
7
+ - **`v2-webhook-durable-delivery`, the exponential-backoff check:** it required the second retry gap to be at least 1.5x the first. Each gap also carries a constant, the receiver round trip a host waits on before scheduling the retry, so the gaps are B + c and 2B + c; through a tunnel (c ≈ 270 ms, base 500 ms) a correct host measured 1.43x. The second gap must now exceed the first by at least a quarter of it.
8
+ - Proven on the v2 reference host: seams off with an https base, both 0199 rows `inapplicable`; the backoff leg passes on the host as is, and fails (510 ms after 604 ms) with the backoff made constant.
9
+
3
10
  ## [2.45.27] — 2026-10-08 — a seam-free host's seam-driven legs record `inapplicable`, not `blocked`
4
11
 
5
12
  - **Three scenarios recorded `blocked` on a host without the seams profile**, which denies the bundle certification, where the rest of the suite records a seam-driven leg `inapplicable`. Found by the v2 reference host's first seams-off cut (RFC 0241's evidence): 11 rows `blocked`, all `executed-pass` with the seams profile.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@openwop/spec-artifacts",
3
- "version": "2.45.27",
4
- "stampSha256": "0ed61d1135dbf584a64a1d1780c8919a45a4e46da25798ad095629b94b61f0a1"
3
+ "version": "2.45.28",
4
+ "stampSha256": "0e47a879900333edf1f01645a54edb7935cf263125d4ab3dc90405f81189d8a3"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.45.27",
3
+ "version": "2.45.28",
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.45.27"
59
+ "@openwop/spec-artifacts": "2.45.28"
60
60
  }
61
61
  }
package/requirements.json CHANGED
@@ -32919,7 +32919,7 @@
32919
32919
  {
32920
32920
  "id": "openwop.it.v2-mcp-mount-map.form-mode-is-never-emitted-for-a-nested-schema-or-a-sensitive-format-password-fi",
32921
32921
  "file": "v2-mcp-mount-map.test.ts",
32922
- "line": 344,
32922
+ "line": 345,
32923
32923
  "title": "form mode is never emitted for a nested schema or a sensitive (format password) field",
32924
32924
  "explicitId": "openwop.requirement.0199.form-mode-no-secret",
32925
32925
  "citations": [
@@ -38110,7 +38110,7 @@
38110
38110
  {
38111
38111
  "id": "openwop.it.v2-webhook-durable-delivery.an-exhausted-delivery-is-dead-lettered-never-dropped",
38112
38112
  "file": "v2-webhook-durable-delivery.test.ts",
38113
- "line": 430,
38113
+ "line": 435,
38114
38114
  "title": "an exhausted delivery is dead-lettered, never dropped",
38115
38115
  "explicitId": "openwop.requirement.0173.webhook-durable-delivery.dead-letter",
38116
38116
  "citations": [
@@ -38149,7 +38149,7 @@
38149
38149
  {
38150
38150
  "id": "openwop.it.v2-webhook-durable-delivery.the-dead-letter-read-is-served-and-its-records-carry-no-payload",
38151
38151
  "file": "v2-webhook-durable-delivery.test.ts",
38152
- "line": 539,
38152
+ "line": 544,
38153
38153
  "title": "the dead-letter read is served and its records carry no payload",
38154
38154
  "explicitId": "openwop.requirement.0188.dead-letter-read",
38155
38155
  "citations": [
@@ -38162,7 +38162,7 @@
38162
38162
  {
38163
38163
  "id": "openwop.it.v2-webhook-durable-delivery.after-unregister-the-dead-letter-read-answers-404-not-found-as-for-a-subscriptio",
38164
38164
  "file": "v2-webhook-durable-delivery.test.ts",
38165
- "line": 560,
38165
+ "line": 565,
38166
38166
  "title": "after unregister, the dead-letter read answers 404 not_found, as for a subscription that never existed",
38167
38167
  "explicitId": "openwop.requirement.0217.dead-letter-read-after-unregister",
38168
38168
  "citations": [
@@ -38189,7 +38189,7 @@
38189
38189
  {
38190
38190
  "id": "openwop.it.v2-webhook-durable-delivery.a-dead-letter-record-carries-no-delivered-payload",
38191
38191
  "file": "v2-webhook-durable-delivery.test.ts",
38192
- "line": 593,
38192
+ "line": 598,
38193
38193
  "title": "a dead-letter record carries no delivered payload",
38194
38194
  "explicitId": "openwop.requirement.0188.dead-letter-content-free",
38195
38195
  "citations": [
@@ -38207,7 +38207,7 @@
38207
38207
  {
38208
38208
  "id": "openwop.it.v2-webhook-durable-delivery.every-logged-event-of-a-subscribed-type-reaches-a-healthy-receiver-at-least-once",
38209
38209
  "file": "v2-webhook-durable-delivery.test.ts",
38210
- "line": 688,
38210
+ "line": 693,
38211
38211
  "title": "every logged event of a subscribed type reaches a healthy receiver at least once within the retry bound",
38212
38212
  "explicitId": "openwop.requirement.0173.webhook-delivery-complete",
38213
38213
  "citations": [
@@ -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.45.27",
5
- "corpusTag": "v2.45.27",
4
+ "version": "2.45.28",
5
+ "corpusTag": "v2.45.28",
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": "9b9455816461b5fc267d1f9a1624667f9f6bd81d2e251731767cca142cd9d0e0",
13
- "api/v2/asyncapi.yaml": "ec80cec238dcb350f741b49138ed92c9d60f110fcb8ad4bdff2cf44c83c8e1d8",
14
- "api/v2/openapi.yaml": "e3cff1191d97def0575096d0ec450622a39c1126ca4baaa72c24079ab3b50774",
12
+ "api/seams-v2.yaml": "1408a344c243a2a54de2f19b839efd2a9ad45ffa94ab72c2b3e352cbce2804f3",
13
+ "api/v2/asyncapi.yaml": "84aa6ad5580f097da601bb257a859c8c4ef745051c77d39b5de222c59734a89b",
14
+ "api/v2/openapi.yaml": "3a85fa3b6d637123554921da4e003a69aabe2c1dc3144b0dd090b68cf0301553",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "276fc1d51eb08e14e9127b9fd27761d7046ee33c12000f3a64a801322db8bf58",
17
17
  "schemas/a2a-task-state.schema.json": "75d5049dea8bd873ff0e7546f1c60c8d36c219bec7084264360be54a8be30ae1",
@@ -208,7 +208,7 @@
208
208
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
209
209
  "spec/v1/alias-detectors.json": "22444c22bb88c568339ef512553f9fc38146e22b566d11ab8608f655d688d19c",
210
210
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
211
- "spec/v1/core-standard-manifest.json": "7e44d633d25ceae4d0d8de5462337e666c3a827c1a003e27b7005edd915fc909",
211
+ "spec/v1/core-standard-manifest.json": "54ae669965b91b6526ce05a6dcc4ce7bbf419dba030e9f23edeb174b1806b3c2",
212
212
  "spec/v1/deprecations.json": "e723bc11d7272c71789ad1303bb7f21809a8a024abf57594f9d5c35dc199ece9",
213
213
  "spec/v1/deprecations.schema.json": "3e393c405d2a41b467d8c5e3c468549078df1ce6a6d2588fc488097b95d9b55b",
214
214
  "spec/v1/end-of-support.json": "35f0bf3b70fe78b16e2a2fd81a153fc27e703f6c16376c6fe7cdf1f4f2c4e6d4",
@@ -313,9 +313,9 @@
313
313
  "spec/v2/path-manifest.json": "7b5679a4dad98c80d855361d88a98c8a4e045af15e310862a05b285b815dc9fc",
314
314
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
315
315
  "spec/v2/profiles.json": "180beb9ef2d161766fa23b2987e7e829851e3d316273147cf6a4a3f324befd6b",
316
- "spec/v2/release.json": "5edf0eb76b4b2d61addd3ebda82c0fa7cbfe9228665050da798cf1f26962cdbe",
316
+ "spec/v2/release.json": "1001b6d3376418eda319c7bbd6a1f77f45f39d3574df0b977ca474c1f4f3622c",
317
317
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
318
- "spec/v2/surface-baseline.json": "d75c8f150df9625594cb6405b603e4f6f4d0e8d0d62ce198d0028c1133e9cbfd"
318
+ "spec/v2/surface-baseline.json": "9553399d274a2d244ba5ac4de7ccc97b6d7ade51ebb92303938fe684d4cb4d2f"
319
319
  },
320
- "corpusCommit": "4bf2cc5a47102975d8710f50f619b3e4f1fcd9d8"
320
+ "corpusCommit": "19b9fd8ea3ae511f8d1b461e99d55564db3857e0"
321
321
  }
@@ -38,7 +38,7 @@ import { isFixtureAdvertised } from '../lib/fixtures.js';
38
38
  import { softSkip } from '../lib/soft-skip.js';
39
39
  import { SCHEMAS_DIR } from '../lib/paths.js';
40
40
  import { req } from '../lib/requirement-ids.js';
41
- import { SEAMS_PREFIX } from '../lib/seams.js';
41
+ import { SEAMS_PREFIX, seamsProfileAdvertised } from '../lib/seams.js';
42
42
  import { unservedDestination } from '../lib/scoped-receiver.js';
43
43
  import { errorInfos, normaliseErrorData, isOpenwopEnvelope, A2A_ERROR_DOMAIN } from '../lib/a2a-error-info.js';
44
44
 
@@ -513,6 +513,7 @@ describe('RFC 0208 — v2-a2a-operation-map (host as A2A 1.0 server, gated on a2
513
513
  const oauth = await familyAdvertised('oauth');
514
514
  if (oauth?.['credentialInterrupt'] !== true) return softSkip('inapplicable', 'oauth.credentialInterrupt is not advertised — the host raises no credential interrupt to project (RFC 0199 §C.1)');
515
515
  if (!isFixtureAdvertised('conformance-credential')) return softSkip('blocked', 'fixture conformance-credential is not in the advertised fixtures[]');
516
+ if (!seamsProfileAdvertised(await v2Discovery().catch(() => null))) return softSkip('inapplicable', 'a fresh Subject is minted through the seams profile (credential mint seam) — conformance.seamsProfile is not openwop-conformance-seams-v2');
516
517
  // A fresh Subject, so no credential another scenario acquired satisfies the node.
517
518
  const minted = await driver.post(`${SEAMS_PREFIX}/sample/auth/credential/mint`, { lane: 'api-key' }).catch(() => null);
518
519
  const bearer = (minted?.json as { credential?: unknown } | undefined)?.credential;
@@ -34,7 +34,7 @@ import { loadEnv } from '../lib/env.js';
34
34
  import { softSkip } from '../lib/soft-skip.js';
35
35
  import { SCHEMAS_DIR } from '../lib/paths.js';
36
36
  import { req } from '../lib/requirement-ids.js';
37
- import { SEAMS_PREFIX } from '../lib/seams.js';
37
+ import { SEAMS_PREFIX, seamsProfileAdvertised } from '../lib/seams.js';
38
38
 
39
39
  export const HOST_CALLBACK_NOT_REQUIRED = 'the suite is the MCP client: every leg POSTs JSON-RPC to the mount the host advertises in mcp.serverUrls; nothing harness-hosted is handed to the host';
40
40
 
@@ -308,6 +308,7 @@ describe('RFC 0208 — v2-mcp-mount-map (host as MCP 2026-07-28 server, gated on
308
308
  if (oauth?.['credentialInterrupt'] !== true) return softSkip('inapplicable', 'oauth.credentialInterrupt is not advertised — the host raises no credential interrupt to bridge (RFC 0199 §C.1)');
309
309
  const missing = needFixtures(['conformance-credential']);
310
310
  if (missing) return softSkip('blocked', missing);
311
+ if (!seamsProfileAdvertised(await v2Discovery().catch(() => null))) return softSkip('inapplicable', 'a fresh Subject is minted through the seams profile (credential mint seam) — conformance.seamsProfile is not openwop-conformance-seams-v2');
311
312
  const minted = await driver.post(`${SEAMS_PREFIX}/sample/auth/credential/mint`, { lane: 'api-key' }).catch(() => null);
312
313
  const bearer = (minted?.json as { credential?: unknown } | undefined)?.credential;
313
314
  if (typeof bearer !== 'string') return softSkip('blocked', 'the credential mint seam did not mint a fresh Subject — a Subject that may already hold a credential makes the leg vacuous');
@@ -403,18 +403,23 @@ describe('RFC 0173 §B — webhook-durable-delivery (gated on webhooks)', () =>
403
403
  // Unfailable-leg audit (2026-09-26): `> 0 ms` alone let a host advertising
404
404
  // `backoff: exponential` that retried in a tight loop (any constant
405
405
  // spacing, even a few ms) pass. An exponential backoff MUST widen, so with
406
- // three or more attempts the second gap is at least 1.5x the first (not
407
- // 2x: jitter tolerance). Only the first two gaps are compared, so a host
408
- // whose schedule hits its cap later is not convicted. `fixed` gets no
409
- // equivalent: its base interval is not on the wire (see the comment above
410
- // the `!retried` branch), so there is no floor to measure against.
406
+ // three or more attempts the second gap is wider than the first by at least
407
+ // a quarter of it. Not 1.5x: each gap also carries a constant c, the
408
+ // receiver round trip a host waits on before scheduling the retry, so the
409
+ // gaps are B + c and 2B + c, and a public cut's tunnel (c ≈ 270 ms
410
+ // against a 500 ms base, 2026-10-08) put a correct host at 1.43x. A
411
+ // constant spacing still fails: its gaps differ only by jitter. Only the
412
+ // first two gaps are compared, so a host whose schedule hits its cap
413
+ // later is not convicted. `fixed` gets no equivalent: its base interval
414
+ // is not on the wire (see the comment above the `!retried` branch), so
415
+ // there is no floor to measure against.
411
416
  if (policy.backoff === 'exponential' && times.length >= 3) {
412
417
  const gap1 = times[1]! - times[0]!;
413
418
  const gap2 = times[2]! - times[1]!;
414
419
  expect(
415
- gap2,
416
- req('openwop.requirement.0173.webhook-durable-delivery', 'webhooks.md §Durability', `retry attempts for ${key} MUST follow the advertised exponential backoff — the second gap (${gap2}ms) MUST be at least 1.5x the first (${gap1}ms); a constant spacing is not exponential`),
417
- ).toBeGreaterThanOrEqual(1.5 * gap1);
420
+ gap2 - gap1,
421
+ req('openwop.requirement.0173.webhook-durable-delivery', 'webhooks.md §Durability', `retry attempts for ${key} MUST follow the advertised exponential backoff — the second gap (${gap2}ms) MUST exceed the first (${gap1}ms) by at least a quarter of it; a constant spacing is not exponential`),
422
+ ).toBeGreaterThanOrEqual(0.25 * gap1);
418
423
  }
419
424
  }
420
425
  } else {