@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.
|
|
372
|
-
|
|
373
|
-
|
|
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))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "2.45.
|
|
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.
|
|
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.
|
|
5
|
-
"corpusTag": "v2.45.
|
|
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": "
|
|
13
|
-
"api/v2/asyncapi.yaml": "
|
|
14
|
-
"api/v2/openapi.yaml": "
|
|
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": "
|
|
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": "
|
|
306
|
+
"spec/v2/release.json": "5eb3b4b185365381f4bbe0443bf08c231af3001ebc5393b8fcc28f1d93b01a8f",
|
|
307
307
|
"spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
|
|
308
|
-
"spec/v2/surface-baseline.json": "
|
|
308
|
+
"spec/v2/surface-baseline.json": "20fa0652d150e712e5403d2635d4ff5b53c0123d5af25e45c060582835f7cb35"
|
|
309
309
|
},
|
|
310
|
-
"corpusCommit": "
|
|
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.
|
|
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('|')}`;
|