@openwop/openwop-conformance 2.45.4 → 2.45.5

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.5] — 2026-10-01 — a prefix floor row is written only for a claimed profile
4
+
5
+ - **The 2.45.5 cycle opens.** A runner change alters the packed content.
6
+ - **Fix: an unclaimed prefix floor no longer blocks a major-1 bundle.** The runner wrote `openwop.floor.any.interrupt-` for every floor in the v1 table. On a major-1 host that does not claim `openwop-interrupts`, no `interrupt-*` file passes, so the row was `blocked`, and a v3 bundle with any `blocked` row certifies nothing (RFC 0168 §E.1). The row is now written only when the profile is claimed, as the any-of rows have been since 2.45.4. A claimed profile is unchanged.
7
+ - **Who is affected:** a major-1 host that cuts a v3 bundle without claiming `openwop-interrupts`. No such host is known. Major-2 bundles never carried the row.
8
+ - **Proof.** `floor-prefix-claimed.test.ts`: the same evidence yields no row unclaimed and a `blocked` row claimed; a witnessed `interrupt-*` pass still satisfies a claimed floor.
9
+
3
10
  ## [2.45.4] — 2026-10-01 — v2 ports of production-backpressure and budget-enforcement, on a per-major profile
4
11
 
5
12
  - **The gate runs every host-free scenario** (not packed; no scenario changes). New `scripts/list-host-free-scenarios.mjs` lists the scenarios whose import closure never reaches `lib/driver`, `lib/sse` or `lib/env` and never calls `fetch(`: 70 files today. `scripts/openwop-check.sh` runs them with `OPENWOP_BASE_URL` and `OPENWOP_API_KEY` unset, after the nine hand-listed files.
@@ -366,11 +366,21 @@ document) {
366
366
  // `openwop.floor.any.interrupt-` row recorded `blocked` ("no interrupt-*
367
367
  // scenario ran"), which by RFC 0168 §E.1 denied certification to every
368
368
  // profile on every major-2 bundle. The fifth unjoined floor site.
369
+ //
370
+ // Only for a CLAIMED profile's floor (2.45.5), as the any-of rows below have
371
+ // been since 2.45.4, and for the same reason: a floor nobody claims is not a
372
+ // requirement on this host, and its summary row is `blocked` whenever no
373
+ // matching file passed. A major-1 host that does not claim
374
+ // `openwop-interrupts` got an `openwop.floor.any.interrupt-` row it could
375
+ // only satisfy by passing a scenario of a profile it never claimed, and a v3
376
+ // bundle with any `blocked` row certifies nothing (RFC 0168 §E.1).
377
+ const claimed = new Set(claimedProfiles.map((p) => DEPRECATED_PROFILE_ALIASES[p] ?? p));
369
378
  const prefixIds = new Set();
370
379
  if (!v2FloorsActive())
371
- for (const floor of Object.values(PROFILE_FLOOR_SCENARIOS))
372
- for (const p of floor.requiredAnyPrefix ?? [])
373
- prefixIds.add(p);
380
+ for (const [profile, floor] of Object.entries(PROFILE_FLOOR_SCENARIOS))
381
+ if (claimed.has(profile))
382
+ for (const p of floor.requiredAnyPrefix ?? [])
383
+ prefixIds.add(p);
374
384
  for (const prefix of [...prefixIds].sort()) {
375
385
  const matching = [...perFile.entries()].filter(([f]) => f.startsWith(prefix)).map(([, r]) => r);
376
386
  const id = requirementIdForPrefix(prefix);
@@ -407,7 +417,6 @@ document) {
407
417
  // members `inapplicable`, got one `blocked` row for a profile it never
408
418
  // claimed, and a bundle with any `blocked` row certifies nothing (RFC 0168
409
419
  // §E.1). A group nobody claims is not a requirement on this host.
410
- const claimed = new Set(claimedProfiles.map((p) => DEPRECATED_PROFILE_ALIASES[p] ?? p));
411
420
  if (!v2FloorsActive())
412
421
  for (const [profile, floor] of Object.entries(PROFILE_FLOOR_SCENARIOS))
413
422
  if (claimed.has(profile))
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@openwop/spec-artifacts",
3
- "version": "2.45.4",
4
- "stampSha256": "1b559bef6691e393c6dc1cdd29e661a8bbec495e43529135d56aba30e1d0a704"
3
+ "version": "2.45.5",
4
+ "stampSha256": "cdc1ddd3b7638a291b2179ef220c96c8d8e67179e005c7650ac9d913f73dd179"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.45.4",
3
+ "version": "2.45.5",
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.45.4"
59
+ "@openwop/spec-artifacts": "2.45.5"
60
60
  }
61
61
  }
@@ -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.4",
5
- "corpusTag": "v2.45.4",
4
+ "version": "2.45.5",
5
+ "corpusTag": "v2.45.5",
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": "ad37a5a5c732ad46100fc03c3f4243fdd4f2976e330f02a8791b6b5b10a8a0c1",
11
11
  "api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
12
- "api/seams-v2.yaml": "e4a8e19b494d12c0d105ed8d1d27337995564a6443cb8a747521a9d67977b52b",
13
- "api/v2/asyncapi.yaml": "d53ca2c06a47282a0cc39d9e0b6b488068da0ad2c91c3166598b005dcf72aa21",
14
- "api/v2/openapi.yaml": "24bce91f02de6527121f12ab23916c4f96bab2cbf8f2203208c1d3a444c632c5",
12
+ "api/seams-v2.yaml": "8ecb968c18b03fde88e807855cfbe761db387e9a51550f8a9c525348c224fef1",
13
+ "api/v2/asyncapi.yaml": "0f2fd3ea79ca0c3964d7e81881c371bde8006ca0e23a32aaf37f4c201ab0ebbe",
14
+ "api/v2/openapi.yaml": "910a3e2cc53ae10251cf6b3e82317adc76923aa94c13438cbb50c7197a2f5487",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "75d5049dea8bd873ff0e7546f1c60c8d36c219bec7084264360be54a8be30ae1",
@@ -204,7 +204,7 @@
204
204
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
205
205
  "spec/v1/alias-detectors.json": "0b2f28808ffe0b9d98a187775038c3406bb70919747a788a6e4f866e293ae6d3",
206
206
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
207
- "spec/v1/core-standard-manifest.json": "aa1ecb9c1f1c1c3039f948b137e4672031fad29103bb9ac4166eb4ff89b7c85e",
207
+ "spec/v1/core-standard-manifest.json": "ca151601427c2887b0c3ecc9498f5f0de1c4f6d1724b7e06eb7043be20eef1b1",
208
208
  "spec/v1/deprecations.json": "a3293072ea951857395d05f0437264e88965f1e9019ff61c55bacfa9c1aaa17c",
209
209
  "spec/v1/deprecations.schema.json": "3e393c405d2a41b467d8c5e3c468549078df1ce6a6d2588fc488097b95d9b55b",
210
210
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
@@ -303,9 +303,9 @@
303
303
  "spec/v2/path-manifest.json": "27c2307b84376b2f22bea4e2213fc7e33ef3bf8fd1d18039f7955edb00dc9c9a",
304
304
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
305
305
  "spec/v2/profiles.json": "180beb9ef2d161766fa23b2987e7e829851e3d316273147cf6a4a3f324befd6b",
306
- "spec/v2/release.json": "d1b495b89fc43030e607d7dc312732500f0433e84656ccc88ad8c80c2ac444b1",
306
+ "spec/v2/release.json": "5eb3b4b185365381f4bbe0443bf08c231af3001ebc5393b8fcc28f1d93b01a8f",
307
307
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
308
- "spec/v2/surface-baseline.json": "9e17340cea86146899703c91246ddd5a5403c68e40e749f0ad1958801f60b619"
308
+ "spec/v2/surface-baseline.json": "20fa0652d150e712e5403d2635d4ff5b53c0123d5af25e45c060582835f7cb35"
309
309
  },
310
- "corpusCommit": "5a4ad1ab0a3584c7ea30f4b32f4599e53ce1f75a"
310
+ "corpusCommit": "b18ad74419ad18353685a28306424865a5d09f90"
311
311
  }
@@ -450,8 +450,17 @@ export function deriveRequirementDispositions(
450
450
  // `openwop.floor.any.interrupt-` row recorded `blocked` ("no interrupt-*
451
451
  // scenario ran"), which by RFC 0168 §E.1 denied certification to every
452
452
  // profile on every major-2 bundle. The fifth unjoined floor site.
453
+ //
454
+ // Only for a CLAIMED profile's floor (2.45.5), as the any-of rows below have
455
+ // been since 2.45.4, and for the same reason: a floor nobody claims is not a
456
+ // requirement on this host, and its summary row is `blocked` whenever no
457
+ // matching file passed. A major-1 host that does not claim
458
+ // `openwop-interrupts` got an `openwop.floor.any.interrupt-` row it could
459
+ // only satisfy by passing a scenario of a profile it never claimed, and a v3
460
+ // bundle with any `blocked` row certifies nothing (RFC 0168 §E.1).
461
+ const claimed = new Set(claimedProfiles.map((p) => DEPRECATED_PROFILE_ALIASES[p] ?? p));
453
462
  const prefixIds = new Set<string>();
454
- if (!v2FloorsActive()) for (const floor of Object.values(PROFILE_FLOOR_SCENARIOS)) for (const p of floor.requiredAnyPrefix ?? []) prefixIds.add(p);
463
+ if (!v2FloorsActive()) for (const [profile, floor] of Object.entries(PROFILE_FLOOR_SCENARIOS)) if (claimed.has(profile)) for (const p of floor.requiredAnyPrefix ?? []) prefixIds.add(p);
455
464
  for (const prefix of [...prefixIds].sort()) {
456
465
  const matching = [...perFile.entries()].filter(([f]) => f.startsWith(prefix)).map(([, r]) => r);
457
466
  const id = requirementIdForPrefix(prefix);
@@ -486,7 +495,6 @@ export function deriveRequirementDispositions(
486
495
  // members `inapplicable`, got one `blocked` row for a profile it never
487
496
  // claimed, and a bundle with any `blocked` row certifies nothing (RFC 0168
488
497
  // §E.1). A group nobody claims is not a requirement on this host.
489
- const claimed = new Set(claimedProfiles.map((p) => DEPRECATED_PROFILE_ALIASES[p] ?? p));
490
498
  if (!v2FloorsActive()) for (const [profile, floor] of Object.entries(PROFILE_FLOOR_SCENARIOS)) if (claimed.has(profile)) for (const g of floor.requiredAnyOf ?? []) groups.set(requirementIdForAnyOf(g), g);
491
499
  for (const [id, members] of [...groups.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
492
500
  const scenarioId = `anyof:${members.join('|')}`;