@openwop/openwop-conformance 2.0.0-rc.0 → 2.0.0-rc.2
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/README.md +2 -2
- package/dist/cli.js +209 -14
- package/dist/lib/certification-bundle-v3.js +142 -0
- package/dist/lib/requirement-ids.js +23 -0
- package/dist/lib/requirement-ledger.js +1 -0
- package/dist/lib/scenario-disposition.js +5 -1
- package/dist/spec-artifacts.lock.json +2 -2
- package/package.json +2 -2
- package/requirements.json +2744 -4
- package/scenario-majors.json +155 -2
- package/schemas/CORPUS-STAMP.json +17 -17
- package/src/cli.ts +190 -19
- package/src/lib/certification-bundle-v3.ts +175 -0
- package/src/lib/driver.ts +9 -1
- package/src/lib/era2-seed.ts +197 -0
- package/src/lib/requirement-ids.ts +21 -0
- package/src/lib/requirement-ledger.ts +7 -1
- package/src/lib/scenario-disposition.ts +5 -1
- package/src/lib/seams.ts +45 -0
- package/src/lib/v2.ts +62 -0
- package/src/scenarios/v2-approver-enforced.test.ts +97 -0
- package/src/scenarios/v2-assurance-downgrade-audited.test.ts +75 -0
- package/src/scenarios/v2-bundle-v3-signed.test.ts +96 -0
- package/src/scenarios/v2-capabilities-root-closed.test.ts +63 -0
- package/src/scenarios/v2-capability-record-shape.test.ts +104 -0
- package/src/scenarios/v2-chain-pin-exact.test.ts +118 -0
- package/src/scenarios/v2-coherence-not-in-bundle.test.ts +98 -0
- package/src/scenarios/v2-compensation-read-projection.test.ts +85 -0
- package/src/scenarios/v2-configurable-closed.test.ts +67 -0
- package/src/scenarios/v2-dual-stack-negotiation.test.ts +118 -0
- package/src/scenarios/v2-effect-identity-business-key.test.ts +132 -0
- package/src/scenarios/v2-effect-seam-manifest.test.ts +163 -0
- package/src/scenarios/v2-enum-growth-rule.test.ts +69 -0
- package/src/scenarios/v2-era-2-append-vocabulary.test.ts +140 -0
- package/src/scenarios/v2-era-key.test.ts +86 -0
- package/src/scenarios/v2-error-registry.test.ts +89 -0
- package/src/scenarios/v2-event-type-closed.test.ts +97 -0
- package/src/scenarios/v2-fork-a-v1-run.test.ts +109 -0
- package/src/scenarios/v2-form-when-reuses-edge-conditions.test.ts +70 -0
- package/src/scenarios/v2-header-scheme.test.ts +67 -0
- package/src/scenarios/v2-id-grammar.test.ts +77 -0
- package/src/scenarios/v2-idempotency-key-grammar.test.ts +65 -0
- package/src/scenarios/v2-interrupt-token-scheme.test.ts +55 -0
- package/src/scenarios/v2-lane-issuer-advertised.test.ts +62 -0
- package/src/scenarios/v2-legacy-profiles-absent.test.ts +78 -0
- package/src/scenarios/v2-manifest-ceiling-refused.test.ts +130 -0
- package/src/scenarios/v2-manifest-hatch-carried.test.ts +120 -0
- package/src/scenarios/v2-min-client-version.test.ts +48 -0
- package/src/scenarios/v2-minimum-version-refused.test.ts +141 -0
- package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +95 -0
- package/src/scenarios/v2-negotiation-authenticated.test.ts +125 -0
- package/src/scenarios/v2-negotiation-decided-emitted.test.ts +149 -0
- package/src/scenarios/v2-no-transport-advertisement.test.ts +57 -0
- package/src/scenarios/v2-owner-subject-required.test.ts +72 -0
- package/src/scenarios/v2-pack-isolation.test.ts +147 -0
- package/src/scenarios/v2-payload-registry-closed.test.ts +110 -0
- package/src/scenarios/v2-peer-dependency-declared.test.ts +132 -0
- package/src/scenarios/v2-pinned-run-disposition.test.ts +124 -0
- package/src/scenarios/v2-poll-cursor-v2.test.ts +114 -0
- package/src/scenarios/v2-preferred-version-default.test.ts +83 -0
- package/src/scenarios/v2-profiles-derived-only.test.ts +70 -0
- package/src/scenarios/v2-provider-conflict.test.ts +115 -0
- package/src/scenarios/v2-refresh-sla.test.ts +78 -0
- package/src/scenarios/v2-relaxation-recorded.test.ts +134 -0
- package/src/scenarios/v2-revocation-honored.test.ts +66 -0
- package/src/scenarios/v2-subject-link-record.test.ts +102 -0
- package/src/scenarios/v2-unmapped-type-refused.test.ts +95 -0
- package/src/scenarios/v2-v1-events-translated.test.ts +105 -0
- package/src/scenarios/v2-v1-signed-webhook-accepted.test.ts +109 -0
- package/src/scenarios/v2-webhook-durable-delivery.test.ts +238 -0
- package/src/scenarios/v2-well-known-one-resource.test.ts +129 -0
- package/src/setup.ts +40 -4
package/src/setup.ts
CHANGED
|
@@ -31,7 +31,9 @@ import { OtelCollector, setCollector } from './lib/otel-collector.js';
|
|
|
31
31
|
import { McpFakeServer, setMcpFakeServer } from './lib/mcp-fake-server.js';
|
|
32
32
|
import { A2AFakePeer, setA2AFakePeer } from './lib/a2a-fake-peer.js';
|
|
33
33
|
import { afterAll, afterEach, beforeAll, beforeEach, expect } from 'vitest';
|
|
34
|
-
import { basename } from 'node:path';
|
|
34
|
+
import { basename, join } from 'node:path';
|
|
35
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
36
|
+
import { PKG_ROOT_PATH } from './lib/paths.js';
|
|
35
37
|
import { recordRequirement, hasRequirement, journalLength, journalSince } from './lib/requirement-ledger.js';
|
|
36
38
|
import { requirementIdForFile, resolveFileRecord, type FileTestState } from './lib/scenario-disposition.js';
|
|
37
39
|
import { softSkipDisposition } from './lib/soft-skip.js';
|
|
@@ -243,6 +245,34 @@ function _assertionCalls(): number {
|
|
|
243
245
|
return 0;
|
|
244
246
|
}
|
|
245
247
|
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* (file, title) → the explicit `req()` id the scenario cites, read from the
|
|
251
|
+
* generated `requirements.json` that ships with the package. Only ids under
|
|
252
|
+
* `openwop.requirement.` are returned: a per-`it` id is what the allocator
|
|
253
|
+
* would mint anyway.
|
|
254
|
+
*/
|
|
255
|
+
let _registry: Map<string, string> | undefined;
|
|
256
|
+
function registeredExplicitId(file: string, title: string): string | null {
|
|
257
|
+
if (_registry === undefined) {
|
|
258
|
+
_registry = new Map();
|
|
259
|
+
for (const root of [PKG_ROOT_PATH, join(PKG_ROOT_PATH, '..')]) {
|
|
260
|
+
const path = join(root, 'requirements.json');
|
|
261
|
+
if (!existsSync(path)) continue;
|
|
262
|
+
try {
|
|
263
|
+
const doc = JSON.parse(readFileSync(path, 'utf8')) as { records?: Array<{ file?: unknown; title?: unknown; explicitId?: unknown }> };
|
|
264
|
+
for (const r of doc.records ?? []) {
|
|
265
|
+
if (typeof r.file === 'string' && typeof r.title === 'string' && typeof r.explicitId === 'string' && r.explicitId.startsWith('openwop.requirement.')) {
|
|
266
|
+
_registry.set(`${r.file}\u0000${r.title}`, r.explicitId);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
} catch { /* an unreadable registry simply yields no fallback */ }
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return _registry.get(`${file}\u0000${title}`) ?? null;
|
|
274
|
+
}
|
|
275
|
+
|
|
246
276
|
function _fileOf(task: { file?: { filepath?: string; name?: string } } | undefined): string | null {
|
|
247
277
|
const f = task?.file?.filepath ?? task?.file?.name;
|
|
248
278
|
return typeof f === 'string' && f.length > 0 ? basename(f) : null;
|
|
@@ -297,7 +327,13 @@ afterEach(({ task }) => {
|
|
|
297
327
|
takeExplicitRequirementId();
|
|
298
328
|
return;
|
|
299
329
|
}
|
|
300
|
-
|
|
330
|
+
// A leg that soft-skips before its first assertion never calls `req()`, so the
|
|
331
|
+
// runtime override is empty and the row lands under the per-`it` id instead of
|
|
332
|
+
// the requirement the leg is about — leaving that requirement with no row in
|
|
333
|
+
// any bundle, which is the §F Witness gate's subject. The generated registry
|
|
334
|
+
// already knows (file, title) → explicit id statically, so fall back to it and
|
|
335
|
+
// the disposition is attributed either way.
|
|
336
|
+
const explicit = takeExplicitRequirementId() ?? registeredExplicitId(file, task.name);
|
|
301
337
|
const alloc = _itAllocators.get(file) ?? new ItIdAllocator();
|
|
302
338
|
_itAllocators.set(file, alloc);
|
|
303
339
|
const itId = explicit ?? alloc.allocate(file, task.name);
|
|
@@ -329,7 +365,7 @@ afterEach(({ task }) => {
|
|
|
329
365
|
detail = 'vitest skipped the test (ctx.skip / it.skip) without a recorded gate reason';
|
|
330
366
|
}
|
|
331
367
|
try {
|
|
332
|
-
recordRequirement(itId, disposition, detail, { assertionCount: calls });
|
|
368
|
+
recordRequirement(itId, disposition, detail, { assertionCount: calls, scenarioFile: file });
|
|
333
369
|
} catch {
|
|
334
370
|
/* never fail a test for bookkeeping */
|
|
335
371
|
}
|
|
@@ -376,7 +412,7 @@ afterAll(({}, suite) => {
|
|
|
376
412
|
// of both now.
|
|
377
413
|
if (!hasRequirement(fileRequirementId)) {
|
|
378
414
|
try {
|
|
379
|
-
recordRequirement(fileRequirementId, disposition, detail, { assertionCount });
|
|
415
|
+
recordRequirement(fileRequirementId, disposition, detail, { assertionCount, scenarioFile: file });
|
|
380
416
|
} catch {
|
|
381
417
|
/* never fail a file for bookkeeping */
|
|
382
418
|
}
|