@openwop/openwop-conformance 2.37.0 → 2.38.0

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +3 -3
  3. package/dist/cli.js +8 -18
  4. package/dist/lib/certification-bundle-v3.js +46 -18
  5. package/dist/lib/jcs.js +274 -0
  6. package/dist/lib/requirement-ledger.js +44 -3
  7. package/dist/lib/scenario-disposition.js +37 -8
  8. package/dist/spec-artifacts.lock.json +2 -2
  9. package/package.json +2 -2
  10. package/requirements.json +323 -57
  11. package/scenario-majors.json +7 -3
  12. package/schemas/CORPUS-STAMP.json +30 -30
  13. package/src/cli.ts +8 -16
  14. package/src/lib/certification-bundle-v3.ts +42 -17
  15. package/src/lib/front-mux.ts +44 -2
  16. package/src/lib/jcs.ts +229 -0
  17. package/src/lib/llm-cache-key-recipe.ts +10 -20
  18. package/src/lib/requirement-ledger.ts +82 -4
  19. package/src/lib/scenario-disposition.ts +41 -3
  20. package/src/lib/scoped-receiver.ts +223 -0
  21. package/src/lib/triggerBridge.ts +49 -0
  22. package/src/scenarios/auth-subject-link.test.ts +18 -1
  23. package/src/scenarios/jcs-vectors.test.ts +108 -0
  24. package/src/scenarios/semantic-digest-vectors.test.ts +8 -0
  25. package/src/scenarios/trigger-bridge-delivery.test.ts +17 -2
  26. package/src/scenarios/trigger-stream-cdc-sources.test.ts +17 -2
  27. package/src/scenarios/v2-a2a-operation-map.test.ts +28 -0
  28. package/src/scenarios/v2-a2ui-v09-surface.test.ts +18 -4
  29. package/src/scenarios/v2-bound-id-kinds.test.ts +35 -22
  30. package/src/scenarios/v2-content-locale-keys.test.ts +10 -1
  31. package/src/scenarios/v2-idempotency-in-flight.test.ts +81 -26
  32. package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +7 -1
  33. package/src/scenarios/v2-oauth-client-pkce-state-iss.test.ts +7 -1
  34. package/src/scenarios/v2-webhook-delivery-shape.test.ts +31 -34
  35. package/src/scenarios/v2-webhook-durable-delivery.test.ts +63 -47
  36. package/src/scenarios/webhook-signed-delivery.test.ts +55 -42
  37. package/src/setup.ts +24 -4
  38. package/vectors/jcs-v1.json +294 -0
  39. package/vectors/semantic-request-digest-v2.json +52 -0
@@ -110,9 +110,13 @@ export function resolveItRecord(state, assertionCalls, gate, noted, firstError,
110
110
  * closed), none an optional extra. Scoped to major 2 because the 146 v1-side
111
111
  * sites were not measured and v1 bundles are read through its EOS.
112
112
  */
113
- blockedStands = false) {
114
- if (state === 'fail')
115
- return { disposition: 'executed-fail', detail: `the test executed and failed: ${(firstError ?? 'no message').slice(0, 300)}` };
113
+ blockedStands = false,
114
+ /** The `it` title, so a failed row says WHICH leg of the requirement failed. */
115
+ testName) {
116
+ if (state === 'fail') {
117
+ const where = testName === undefined || testName.trim() === '' ? '' : ` in "${testName.slice(0, 120)}"`;
118
+ return { disposition: 'executed-fail', detail: `the test executed and failed${where}: ${(firstError ?? 'no message').slice(0, 300)}` };
119
+ }
116
120
  if (state === 'pass' && assertionCalls > 0) {
117
121
  // `blockedDespiteAssertions` (soft-skip.ts): the leg says its setup
118
122
  // assertions are not the requirement, and the requirement went unobserved.
@@ -138,11 +142,34 @@ blockedStands = false) {
138
142
  return { disposition: 'blocked', detail: 'unclassified return: the test passed with zero assertions and recorded no reason — RFC 0148 §A resolves it to blocked, never to a pass' };
139
143
  return { disposition: 'skipped', detail: 'vitest skipped the test (ctx.skip / it.skip) without a recorded gate reason' };
140
144
  }
145
+ /**
146
+ * The `executed-fail` detail for a file row: WHICH cases failed, and what the
147
+ * first one said.
148
+ *
149
+ * Until 2.37.0 this was the fixed string "one or more assertions in the file
150
+ * failed". A tier-2 host read exactly that for `v2-run-bulk-cancel` — 10
151
+ * assertions, no case name, no message, and nothing else in the record for that
152
+ * file — and had to hand-probe every assertion in the file against production to
153
+ * find out what had happened. A bundle row whose only detail is that sentence is
154
+ * undiagnosable by construction, and every future flicker in any scenario had
155
+ * the same problem.
156
+ */
157
+ export function failureDetail(failures, failedCount) {
158
+ if (failures.length === 0) {
159
+ return `${failedCount} test(s) in the file failed; the runner captured no message`;
160
+ }
161
+ const head = failures[0];
162
+ const named = failures.slice(0, 3).map((f) => `"${f.name.slice(0, 120)}"`).join(', ');
163
+ const more = failures.length > 3 ? ` (+${failures.length - 3} more)` : '';
164
+ const msg = head.message === undefined || head.message.trim() === '' ? 'no message' : head.message.slice(0, 400);
165
+ return `${failures.length} test(s) failed — ${named}${more}; first failure: ${msg}`;
166
+ }
141
167
  /** Worker half: fold a file's per-test states (+ any gate-recorded reason) into
142
168
  * the ONE disposition the file records. */
143
- export function fileDisposition(states, gateReason, assertionCount) {
144
- if (states.some((s) => s === 'fail'))
145
- return { disposition: 'executed-fail', detail: 'one or more assertions in the file failed' };
169
+ export function fileDisposition(states, gateReason, assertionCount, failures = []) {
170
+ const failed = states.filter((s) => s === 'fail').length;
171
+ if (failed > 0)
172
+ return { disposition: 'executed-fail', detail: failureDetail(failures, failed) };
146
173
  if (states.some((s) => s === 'pass')) {
147
174
  // A test that early-returned through `behaviorGate` is reported by vitest
148
175
  // as a pass with zero assertions. When EVERY passing test in the file did
@@ -182,7 +209,9 @@ export function fileDisposition(states, gateReason, assertionCount) {
182
209
  * - every test `ctx.skip()`ped ⇒ the file's noted reason if it wrote one
183
210
  * BEFORE skipping (`ctx.skip()` throws), else `blocked` + the marker.
184
211
  */
185
- export function resolveFileRecord(states, gateReason, assertionCount, noted, specCoherenceFile) {
212
+ export function resolveFileRecord(states, gateReason, assertionCount, noted, specCoherenceFile,
213
+ /** The failed cases, so an `executed-fail` row NAMES them (2.37.0). */
214
+ failures = []) {
186
215
  // A scenario whose subject is the CORPUS, skipped because the published
187
216
  // tarball does not bundle spec/v1/. RFC 0148 §A: `blocked` is defined over
188
217
  // ADVERTISED BEHAVIOUR, and there is none here — nothing about the host was
@@ -196,7 +225,7 @@ export function resolveFileRecord(states, gateReason, assertionCount, noted, spe
196
225
  && assertionCount === 0) {
197
226
  return { disposition: 'inapplicable', detail: SPEC_COHERENCE_DETAIL };
198
227
  }
199
- let { disposition, detail } = fileDisposition(states, gateReason, assertionCount);
228
+ let { disposition, detail } = fileDisposition(states, gateReason, assertionCount, failures);
200
229
  if (disposition === 'executed-pass' && assertionCount === 0) {
201
230
  if (noted !== null) {
202
231
  disposition = noted.kind;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@openwop/spec-artifacts",
3
- "version": "2.37.0",
4
- "stampSha256": "7122d36a173c88dfe75b1fd136824e9a3601583b9035916a666b49e11010b77e"
3
+ "version": "2.38.0",
4
+ "stampSha256": "ad88f149547eb38bb873fa63e1d18e06e8810e6427d61a72fac94c32c5e28603"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.37.0",
3
+ "version": "2.38.0",
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.37.0"
59
+ "@openwop/spec-artifacts": "2.38.0"
60
60
  }
61
61
  }