@openwop/openwop-conformance 2.0.6 → 2.0.7

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,64 @@
1
1
  # `@openwop/openwop-conformance` Changelog
2
2
 
3
+ ## [2.0.7] — 2026-09-06 — three claims of coverage that were not coverage
4
+
5
+ No host behaviour changes. One gate changes disposition, and the two prose
6
+ corrections remove claims the corpus was making about its own evidence.
7
+
8
+ **`vendorControlGate` answers `blocked`, not `inapplicable`, when
9
+ `spec/v2/declaration.json` cannot be resolved.** 2.0.6 — the release that fixed
10
+ this scenario — got the disposition wrong on the branch it had just repaired.
11
+ `inapplicable` asserts *the requirement does not bind this host*, which is a
12
+ statement about the host made on the strength of a fact about the suite, and a
13
+ false one: the rule binds exactly as before and the suite merely failed to read
14
+ its own corpus. It is also the quiet answer. `inapplicable` certifies;
15
+ `blocked` is bundle-wide fatal (RFC 0168 §E.1). The disposition that was wrong
16
+ was the one that made no sound.
17
+
18
+ As of 2.0.6 that branch is unreachable — the registry resolves in every layout
19
+ and the publish workflow asserts it. That is the argument *for* making it
20
+ fatal. An unreachable branch answering `inapplicable` is a trapdoor back to the
21
+ D1 resolution defect, which was invisible precisely because it degraded a live
22
+ witness into a quiet skip.
23
+
24
+ **The general rule is now written down** (`spec/v2/core/conformance.md`
25
+ §"Whose fact is the reason?"): a soft-skip reason MUST name a fact about the
26
+ host under test, and where the predicate is instead a fact about the suite —
27
+ its layout, its corpus, a fixture it cannot resolve — the row MUST record
28
+ `blocked`. Gate ordering follows (host facts before suite facts) but is not the
29
+ guarantee; ordering only decides which *true* reason is reported. The guarantee
30
+ is that a suite-side gate can never be silent, because it is never
31
+ `inapplicable`.
32
+
33
+ Credit where it is due: this came from a host operator who predicted a third
34
+ failure mode I had not considered — a row already `inapplicable` for a true host
35
+ reason, re-gated onto a suite-side precondition, stays `inapplicable`. `skip →
36
+ skip`, no count moves, no gate reddens, and the row silently stops describing
37
+ the host it names. Measured against the tree, their case does not bite this
38
+ scenario (the seams gate returns first, at `:96`, above the precondition at
39
+ `:97`), but the rule they proposed was right and the ordering only held by
40
+ construction — nothing written down stopped the next scenario from getting it
41
+ wrong.
42
+
43
+ `era2-unmapped-gates.test.ts` gains a row asserting that **no** reachable
44
+ verdict in either gate is `inapplicable`, so a future suite-side gate that
45
+ soft-skips quietly reddens a test instead of a bundle. Sabotage-verified:
46
+ restoring 2.0.6's disposition reddens exactly those two rows and no others.
47
+
48
+ ### Corpus prose
49
+
50
+ - **`persistence.md` §"The seat"** claimed `v2-v1-events-translated` reading
51
+ through poll, SSE and a fork meant "a wrapper-only adapter is caught". It does
52
+ not. Three wrappers pass those three legs exactly as one correctly seated
53
+ adapter does, and the rule binds *every* reader, including ones the suite has
54
+ no name for. The seat is a **claims-check** discharged by ADR disclosure and
55
+ audit; the scenario catches a reader that was *missed*, not an adapter that
56
+ was *misplaced*. The clause also cited a scenario by the wrong name and
57
+ pointed at `conformance.md`, which said nothing about any of it. Both MUSTs
58
+ are unchanged — only the false coverage claim is gone.
59
+ - **RFC 0180** supplies the vendor-org registration procedure the registry
60
+ never had, and `persistence.md` §"The codemap is data" now points at it.
61
+
3
62
  ## [2.0.6] — 2026-09-06 — the release that made a rule uncheckable
4
63
 
5
64
  **If you pinned 2.0.5, `v2-unmapped-type-refused` did not run against your
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@openwop/spec-artifacts",
3
- "version": "2.0.6",
4
- "stampSha256": "4f7707b8acb297687e2cc9017f2fa34191033dd0b5db6c1cc64c2c04477ecee6"
3
+ "version": "2.0.7",
4
+ "stampSha256": "1d8f7916c3c32af8dfffdd419b773358b812ff5954829b87bff576eb3f0dc669"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
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.6"
59
+ "@openwop/spec-artifacts": "2.0.7"
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.0.6",
5
- "corpusTag": "v2.0.6",
4
+ "version": "2.0.7",
5
+ "corpusTag": "v2.0.7",
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": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
11
11
  "api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
12
- "api/seams-v2.yaml": "594aad07baceb9c8e00dc9fe91dd8f6f99bc6624c64eaf5be91dbb5f22a35c48",
13
- "api/v2/asyncapi.yaml": "5839f6cb16ed8997a335491a6700ddc2f4166c994ca2838863d4029c1ef6d58e",
14
- "api/v2/openapi.yaml": "f1288076f774dbb46b885519b94719df84b31b4535fe2a5bccb9881d2e09b0ea",
12
+ "api/seams-v2.yaml": "0d18b9414567efb5662f0a8bc06725d0e038aab14f327db7a1b8ebe3b9f4cbb9",
13
+ "api/v2/asyncapi.yaml": "25196e36b92b0dab97904b1f3461826d2066e579963c26c7e6168d2e5688bdfe",
14
+ "api/v2/openapi.yaml": "e48e5669918ddda197a17508eca24ea42e834a62b309091c87d063cb52b1b2cb",
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": "0018230eb426fb0af82545b9f63920cc9504a9eed2a03c44ef61cf73f429e82b",
202
+ "spec/v1/core-standard-manifest.json": "0484560c0bb72e5da9fa393b0723961e1cb7837eaf90c035ff37b7e7fdad6476",
203
203
  "spec/v1/deprecations.json": "1d5acb69a9b8ccb57275a95605f74aef1d920685f8407c9d382a46b59dc803bb",
204
204
  "spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
205
205
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
@@ -213,7 +213,7 @@
213
213
  "spec/v1/spec-gaps.json": "6cc9962c6b969f632e07a78b52a4f61447ff579e2990cbae989866f584a86042",
214
214
  "spec/v2/README.md": "f56bd8d58be4ac04543c9f7b2fe92b294738d6121a4f21cbd1ce751e72b94c83",
215
215
  "spec/v2/core/capabilities.md": "0f222434bbe58c881362a626ab9db6bce0ae2e54cb858e3d71b662dd1fc13150",
216
- "spec/v2/core/conformance.md": "91418b882190e116ab9dac14527f52b8582b0462f41e96beeceb07e3fcc5f99a",
216
+ "spec/v2/core/conformance.md": "6dda58339117819b77710cd53d25f34cc9e602a35a7958d1afc4e3d4b6b7de23",
217
217
  "spec/v2/core/connection-packs.md": "34e519dbe5b091c9758729787d398b35b1dc41f1e01ebd028e7e6b838ce2f6ee",
218
218
  "spec/v2/core/errors.md": "671895de1b7c987a1dfd53fe0a814159efadae0ffd4c8c06bf1749d345270580",
219
219
  "spec/v2/core/events.md": "7b9207079cede7ec335126b98bcb95d655ae3b7322b18febd1b4df51750b0a33",
@@ -225,14 +225,14 @@
225
225
  "spec/v2/core/interrupt.md": "4bd345bccdb8e2762ca95833cc67086158640c27ffa5ef84915a4ab3de348440",
226
226
  "spec/v2/core/overview.md": "8ece6667535d24ed4013a046cb11e1a649f70e39625fc55e09ceb2c02505ed9c",
227
227
  "spec/v2/core/packs.md": "90f32947816b4ec2b045b063ad2914126c73353883514a270ad200205dc8e51b",
228
- "spec/v2/core/persistence.md": "e18195e078d7b0b799055005567e8d86a2ea7518c87809cfaf43dfe9f5d5c8ee",
228
+ "spec/v2/core/persistence.md": "e9830ae228bcbc33f03d81a5f2b51e031466feb84387971dd3459bf5e1687701",
229
229
  "spec/v2/core/replay.md": "19b2fcbda4693895d39b99593f498b76376d77472a813bba6c22fca02e106332",
230
230
  "spec/v2/core/runs.md": "f5f24df6da76b1d6e2cf655af3bbe3340195c36ec8d9ce0ca6e357385b1a8771",
231
231
  "spec/v2/core/security-defaults.md": "53a1bc549aaa356a4fcb56cdb1c4f5880d3fb65d5d49dd570a413bb29aff82e5",
232
232
  "spec/v2/core/versioning.md": "2eb4e8e5a1208a026a3d497d1e0fb76a4f7cb97e514d6f41f45dd66b89405abb",
233
233
  "spec/v2/core/webhooks.md": "1d2719335f8fb46cd31dbb836b44ea7d78ed54f98ea181927502814603c5b935",
234
234
  "spec/v2/core/workflow-chain-packs.md": "99ad4aeeeeb05521720dc2ae18ae63e6d604361780ed1b76778ca6d44da70eed",
235
- "spec/v2/declaration.json": "9e191dffae9f95e622b3fc7087b8c17a2f42177bb4db3c7ee5fdf650443e036d",
235
+ "spec/v2/declaration.json": "bd8a1dcee899a4478ac96b52da6ee07e1cb5fce4465939ac32e19e52f4d5c6b2",
236
236
  "spec/v2/declaration.schema.json": "eac5f8080bd572f147bd57d0c4ac8ad73b14536d9236222490ae29a33b21e184",
237
237
  "spec/v2/errors.json": "f179414a92f30b5dadf26e9e57699649a67324bd7186d5287647d17605d137d3",
238
238
  "spec/v2/event-codemap.json": "37869a03cdfd8758b57e6f350641a6ebbd383231cebda51f5473ad85f94ab74c",
@@ -268,8 +268,8 @@
268
268
  "spec/v2/path-manifest.json": "034152e09b1458c66810d4050e20a273b2b9b8fe2d92b66e8b819477de58a1be",
269
269
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
270
270
  "spec/v2/profiles.json": "0636f19fceae625390003a347e70ef4797d84766b5c24ce8a02cea52aadebca4",
271
- "spec/v2/release.json": "7735a176082e42a30d7884654d79ac7affd7fc50f4b7346085f7d841769c6819",
271
+ "spec/v2/release.json": "2937de1d170c218e4d336088035c2a4fe6b7e951b6c6bd8bd375f0580ae07a53",
272
272
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
273
273
  },
274
- "corpusCommit": "0ebdbc9ad741d49c44731e2bd255499a7da6c4a7"
274
+ "corpusCommit": "8f8818dd663240bdd1ea074a25fd9354d0fde2c3"
275
275
  }
@@ -253,11 +253,24 @@ export function unmappedRefusalGate(registered: ReadonlySet<string> | undefined,
253
253
  * not name MUST be read under its own name unchanged.
254
254
  *
255
255
  * This leg genuinely needs the registry to resolve — it asserts that an org IS
256
- * registered, and an absent registry cannot establish that. `inapplicable` here
257
- * is honest rather than over-gating.
256
+ * registered, and an absent registry cannot establish that.
257
+ *
258
+ * AN UNRESOLVABLE REGISTRY IS `blocked`, NOT `inapplicable` (conformance.md
259
+ * §Whose fact is the reason?). Suite 2.0.6 said `inapplicable`, which asserts
260
+ * the requirement does not bind this host — a statement about the HOST made on
261
+ * the strength of a fact about the SUITE, and a false one: the rule binds
262
+ * exactly as before and the suite merely failed to read its own corpus.
263
+ * `inapplicable` also certifies, while `blocked` is bundle-wide fatal
264
+ * (RFC 0168 §E.1), so the wrong disposition is the silent one.
265
+ *
266
+ * As of 2.0.6 this branch is unreachable — the registry resolves in every
267
+ * layout and the publish workflow asserts it. That is the argument FOR making
268
+ * it fatal, not against: an unreachable branch answering `inapplicable` is a
269
+ * trapdoor back to the D1 resolution defect, which was invisible precisely
270
+ * because it degraded a live witness into a quiet skip.
258
271
  */
259
272
  export function vendorControlGate(registered: ReadonlySet<string> | undefined, map: ReadonlyMap<string, string>, type: string): Gate {
260
- if (registered === undefined) return { ok: false, kind: 'inapplicable', reason: 'spec/v2/declaration.json is not resolvable in this layout — the control leg asserts that a REGISTERED org passes through, and guessing which orgs are registered would make the suite the registry' };
273
+ if (registered === undefined) return { ok: false, kind: 'blocked', reason: 'spec/v2/declaration.json is not resolvable in this layout — the control leg asserts that a REGISTERED org passes through, and guessing which orgs are registered would make the suite the registry. This is a fact about the SUITE, so it is blocked and not inapplicable (conformance.md §Whose fact is the reason?)' };
261
274
  if (!registered.has(orgOf(type))) return { ok: false, kind: 'blocked', reason: `the control leg needs org '${orgOf(type)}' registered in spec/v2/declaration.json extensions (registered: ${[...registered].join(', ') || 'none'}) — without a registered org the positive half of the vendor rule cannot be driven at all` };
262
275
  if (map.has(type)) return { ok: false, kind: 'blocked', reason: `${type} now has a codemap row (→ ${String(map.get(type))}) — the control leg requires a type the codemap does not name` };
263
276
  return { ok: true };