@openwop/openwop-conformance 2.46.26 → 2.46.28

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.
@@ -0,0 +1,214 @@
1
+ /**
2
+ * v2 — an eval run names its modes and its regression baseline (RFC 0251;
3
+ * the rules are the `agents.evalSuite.baselineSelection` facet description in
4
+ * `spec/v2/facets/agents.schema.json` and the `createRun` `evalModes` /
5
+ * `baselineRunId` descriptions), and RFC 0244 §F pairing, which a
6
+ * client-named baseline makes causable.
7
+ *
8
+ * Server-free leg:
9
+ * 1. `0251.shape` — the facet member is a boolean, and the derived
10
+ * `createRun` eval body carries `evalModes` (closed mode enum, non-empty,
11
+ * distinct) and `baselineRunId`.
12
+ *
13
+ * Host legs — gated on `baselineSelection`, `regression` in `modes`, and both
14
+ * `conformance-eval-regression-base` and `-candidate` in discovery `fixtures`.
15
+ * One base run (`evalModes: [golden]`), then one candidate run
16
+ * (`evalModes: [golden, regression]`, the base run as baseline). The two
17
+ * fixtures share a `suiteId`; every paired score is equal while the
18
+ * aggregates differ by 1/3. Judges in `lib/eval-regression-witness.ts`.
19
+ * 2. `0251.baseline-echoed` — `eval.started.baselineRunId` and
20
+ * `regression.baselineRunId` name the base run; `scoreDelta` is the
21
+ * aggregate difference.
22
+ * 3. `0244.regression-paired` — `pairedTaskCount` is 2 (needs
23
+ * `regressionVerdict`).
24
+ * 4. `0244.regression-no-false-verdict` — the verdict is present and is
25
+ * neither `improved` nor `regressed` (needs `regressionVerdict`).
26
+ * 5. `0251.baseline-refused` — an unknown id, and a completed run of
27
+ * another suite (`conformance-eval-trajectory`, when listed), are refused
28
+ * `400 validation_error` without the id.
29
+ * 6. `0251.baseline-uniform` — tenant B's run
30
+ * (`OPENWOP_TEST_TENANT_B_API_KEY`) is refused exactly as the unknown id.
31
+ * 7. `0251.fields-refused` — `baselineRunId` without `regression` in
32
+ * `evalModes`, and `regression` without a baseline, are refused.
33
+ *
34
+ * @see RFCS/0251-eval-run-mode-and-baseline-selection.md
35
+ * @see RFCS/0244-eval-trajectories-trials-and-recorded-fixtures.md §F
36
+ */
37
+
38
+ import { describe, it, expect } from 'vitest';
39
+ import { readFileSync } from 'node:fs';
40
+ import { join } from 'node:path';
41
+ import { randomBytes } from 'node:crypto';
42
+ import { driver, type OpenWOPResponse } from '../lib/driver.js';
43
+ import { v2Discovery, v2RefValidator } from '../lib/v2.js';
44
+ import { softSkip } from '../lib/soft-skip.js';
45
+ import { req } from '../lib/requirement-ids.js';
46
+ import { readErrorCode } from '../lib/error-envelope.js';
47
+ import { majorProfile } from '../lib/major-profile.js';
48
+ import { isFixtureAdvertised } from '../lib/fixtures.js';
49
+ import { API_DIR } from '../lib/paths.js';
50
+ import { pollTerminal, readEvents, isRecord, type Ev } from '../lib/fixture-run-observer.js';
51
+ import { judgeBaselineEchoed, judgeNoFalseVerdict, judgePaired, judgeRefused, judgeUniform, type Answer, type RegressionFinding } from '../lib/eval-regression-witness.js';
52
+
53
+ const PROFILE = majorProfile(2);
54
+ const UNREADABLE = 'v2 discovery unreachable — /.well-known/openwop did not answer 200 JSON under OpenWOP-Version: 2.0';
55
+ const DOC = 'agents.schema.json §evalSuite.baselineSelection, createRun evalModes / baselineRunId (RFC 0251)';
56
+ const DOC_F = 'eval-summary.schema.json regression (RFC 0244 §F)';
57
+ const AGENT = 'core.conformance.agents.scripted';
58
+ const SUITE_URI = (id: string) => `https://conformance.openwop.dev/eval-suites/${id}`;
59
+ const BASE = 'conformance-eval-regression-base';
60
+ const CANDIDATE = 'conformance-eval-regression-candidate';
61
+ const OTHER = 'conformance-eval-trajectory';
62
+ const ID_SHAPE = 'openwop.requirement.0251.shape';
63
+ const ID_ECHOED = 'openwop.requirement.0251.baseline-echoed';
64
+ const ID_PAIRED = 'openwop.requirement.0244.regression-paired';
65
+ const ID_NO_FALSE = 'openwop.requirement.0244.regression-no-false-verdict';
66
+ const ID_REFUSED = 'openwop.requirement.0251.baseline-refused';
67
+ const ID_UNIFORM = 'openwop.requirement.0251.baseline-uniform';
68
+ const ID_FIELDS = 'openwop.requirement.0251.fields-refused';
69
+
70
+ type Skip = { skip: [Parameters<typeof softSkip>[0], string] };
71
+ type Done = { runId: string; events: Ev[]; summary: Record<string, unknown> };
72
+
73
+ async function http(fn: () => Promise<OpenWOPResponse>): Promise<OpenWOPResponse | null> {
74
+ try { return await fn(); } catch { return null; }
75
+ }
76
+ const answer = (r: OpenWOPResponse): Answer => ({ status: r.status, json: r.json, text: r.text });
77
+ const expectAll = (id: string, doc: string, findings: readonly RegressionFinding[]): void => {
78
+ for (const x of findings) expect(x.ok, req(id, doc, x.message)).toBe(true);
79
+ };
80
+
81
+ async function evalSuiteFacet(): Promise<Record<string, unknown> | null | undefined> {
82
+ let doc: Record<string, unknown> | null;
83
+ try { doc = await v2Discovery(); } catch { return undefined; }
84
+ const agents = doc?.['agents'];
85
+ return isRecord(agents) && isRecord(agents['evalSuite']) ? agents['evalSuite'] : null;
86
+ }
87
+
88
+ /** The gate every host leg shares. */
89
+ async function gate(): Promise<Skip | { facet: Record<string, unknown> }> {
90
+ const facet = await evalSuiteFacet();
91
+ if (facet === undefined) return { skip: ['blocked', UNREADABLE] };
92
+ if (facet === null || facet['baselineSelection'] !== true) return { skip: ['inapplicable', 'the host does not advertise agents.evalSuite.baselineSelection'] };
93
+ if (!Array.isArray(facet['modes']) || !facet['modes'].includes('regression')) return { skip: ['inapplicable', 'the host does not advertise regression in agents.evalSuite.modes'] };
94
+ for (const id of [BASE, CANDIDATE]) if (!isFixtureAdvertised(id)) return { skip: ['inapplicable', `the host does not advertise fixture ${id}`] };
95
+ return { facet };
96
+ }
97
+
98
+ const create = (id: string, extra: Record<string, unknown>, headers?: Record<string, string>) =>
99
+ http(() => driver.post(PROFILE.runsPath, { mode: 'eval', evalSuiteRef: SUITE_URI(id), agentId: AGENT, ...extra }, headers ? { headers } : {}));
100
+
101
+ async function complete(id: string, extra: Record<string, unknown>): Promise<Skip | Done> {
102
+ const res = await create(id, extra);
103
+ if (res === null) return { skip: ['blocked', 'POST /runs unreachable (fetch failed)'] };
104
+ if (res.status === 429) return { skip: ['blocked', 'POST /runs answered 429 — the run budget, not the wire'] };
105
+ const runId = isRecord(res.json) && typeof res.json['runId'] === 'string' ? res.json['runId'] : undefined;
106
+ if ((res.status !== 201 && res.status !== 202) || runId === undefined) return { skip: ['blocked', `createRun of ${id} answered ${res.status} ${readErrorCode(res.json) ?? ''}`.trim()] };
107
+ const terminal = await pollTerminal(PROFILE, runId, { timeoutMs: 60_000 });
108
+ if (terminal.snapshot['status'] !== 'completed') return { skip: ['blocked', `eval run ${runId} ended ${String(terminal.snapshot['status'])}, not completed`] };
109
+ const s = await http(() => driver.get(`${PROFILE.runsPath}/${PROFILE.idSegment(runId)}/eval-summary`));
110
+ if (s === null || s.status !== 200 || !isRecord(s.json)) return { skip: ['blocked', `GET …/eval-summary answered ${s?.status ?? 'nothing'}`] };
111
+ return { runId, events: await readEvents(PROFILE, runId), summary: s.json };
112
+ }
113
+
114
+ let pair: Promise<Skip | { base: Done; cand: Done }> | undefined;
115
+ /** Base, then candidate against it, once per worker: the host legs read the same two runs. */
116
+ function runs(): Promise<Skip | { base: Done; cand: Done }> {
117
+ pair ??= (async () => {
118
+ const base = await complete(BASE, { evalModes: ['golden'] });
119
+ if ('skip' in base) return base;
120
+ const cand = await complete(CANDIDATE, { evalModes: ['golden', 'regression'], baselineRunId: base.runId });
121
+ if ('skip' in cand) return cand;
122
+ return { base, cand };
123
+ })();
124
+ return pair;
125
+ }
126
+
127
+ /** An id in the caller's own tenant, with the runId grammar, that the host never minted. */
128
+ const unknownBeside = (runId: string): string => `${runId.split('/')[0]}/${randomBytes(16).toString('hex')}`;
129
+
130
+ describe('v2 RFC 0251 — wire shape (server-free)', () => {
131
+ it('the baselineSelection member and the createRun eval properties are in the derived contract', () => {
132
+ const v = v2RefValidator('capabilities.schema.json#/properties/agents/properties/evalSuite/properties/baselineSelection');
133
+ expect(v(true).ok, req(ID_SHAPE, DOC, 'baselineSelection: true MUST validate')).toBe(true);
134
+ expect(v('yes').ok, req(ID_SHAPE, DOC, 'baselineSelection MUST be a boolean')).toBe(false);
135
+ const api = readFileSync(join(API_DIR, 'v2', 'openapi.yaml'), 'utf8');
136
+ const at = api.indexOf('operationId: createRun');
137
+ const next = api.indexOf('operationId:', at + 1);
138
+ const block = at < 0 ? '' : api.slice(at, next < 0 ? undefined : next);
139
+ expect(block, req(ID_SHAPE, DOC, 'createRun MUST carry evalModes over the RFC 0081 §D modes')).toMatch(/evalModes:[\s\S]*?enum:\s*\n?\s*-?\s*\[?\s*golden/);
140
+ expect(block, req(ID_SHAPE, DOC, 'evalModes MUST be non-empty and distinct')).toMatch(/evalModes:\s*\n\s*type: array\s*\n\s*minItems: 1\s*\n\s*uniqueItems: true/);
141
+ expect(block, req(ID_SHAPE, DOC, 'createRun MUST carry baselineRunId as a runId')).toMatch(/baselineRunId:\s*\n\s*\$ref: \.\.\/\.\.\/schemas\/v2\/ids\.schema\.json#\/\$defs\/runId/);
142
+ });
143
+ });
144
+
145
+ describe('v2 RFC 0251 — a client-named regression baseline (host)', () => {
146
+ it('the candidate run names the baseline it was given, and scoreDelta is the aggregate difference', async () => {
147
+ const g = await gate();
148
+ if ('skip' in g) return softSkip(...g.skip);
149
+ const r = await runs();
150
+ if ('skip' in r) return softSkip(...r.skip);
151
+ expectAll(ID_ECHOED, DOC, judgeBaselineEchoed(r.base.runId, r.cand.events, r.cand.summary, r.base.summary));
152
+ });
153
+
154
+ it('only the tasks in both runs are paired (RFC 0244 §F)', async () => {
155
+ const g = await gate();
156
+ if ('skip' in g) return softSkip(...g.skip);
157
+ if (g.facet['regressionVerdict'] !== true) return softSkip('inapplicable', 'the host does not advertise agents.evalSuite.regressionVerdict');
158
+ const r = await runs();
159
+ if ('skip' in r) return softSkip(...r.skip);
160
+ expectAll(ID_PAIRED, DOC_F, judgePaired(r.cand.summary));
161
+ });
162
+
163
+ it('equal paired scores never yield improved or regressed (RFC 0244 §F)', async () => {
164
+ const g = await gate();
165
+ if ('skip' in g) return softSkip(...g.skip);
166
+ if (g.facet['regressionVerdict'] !== true) return softSkip('inapplicable', 'the host does not advertise agents.evalSuite.regressionVerdict');
167
+ const r = await runs();
168
+ if ('skip' in r) return softSkip(...r.skip);
169
+ expectAll(ID_NO_FALSE, DOC_F, judgeNoFalseVerdict(r.cand.summary));
170
+ });
171
+
172
+ it('an unknown baseline, and a run of another suite, are refused without the id', async () => {
173
+ const g = await gate();
174
+ if ('skip' in g) return softSkip(...g.skip);
175
+ const r = await runs();
176
+ if ('skip' in r) return softSkip(...r.skip);
177
+ const unknownId = unknownBeside(r.base.runId);
178
+ const unknown = await create(CANDIDATE, { evalModes: ['golden', 'regression'], baselineRunId: unknownId });
179
+ if (unknown === null) return softSkip('blocked', 'POST /runs unreachable (fetch failed)');
180
+ expectAll(ID_REFUSED, DOC, judgeRefused(answer(unknown), unknownId, 'an unknown baselineRunId'));
181
+ const other = isFixtureAdvertised(OTHER) ? await complete(OTHER, {}) : undefined;
182
+ const res = other !== undefined && !('skip' in other) ? await create(CANDIDATE, { evalModes: ['golden', 'regression'], baselineRunId: other.runId }) : null;
183
+ if (other !== undefined && !('skip' in other) && res !== null) expectAll(ID_REFUSED, DOC, judgeRefused(answer(res), other.runId, 'a baseline that ran another suite'));
184
+ });
185
+
186
+ it("another tenant's run is refused exactly as an id that never existed", async () => {
187
+ const g = await gate();
188
+ if ('skip' in g) return softSkip(...g.skip);
189
+ const tenantB = process.env['OPENWOP_TEST_TENANT_B_API_KEY']?.trim();
190
+ if (!tenantB) return softSkip('blocked', 'OPENWOP_TEST_TENANT_B_API_KEY (a credential bound to a second tenant) is not set');
191
+ if (tenantB === process.env['OPENWOP_API_KEY']) return softSkip('blocked', 'OPENWOP_TEST_TENANT_B_API_KEY equals OPENWOP_API_KEY — the leg needs a second tenant');
192
+ const foreign = await create(BASE, { evalModes: ['golden'] }, { Authorization: `Bearer ${tenantB}` });
193
+ const foreignId = foreign && isRecord(foreign.json) && typeof foreign.json['runId'] === 'string' ? foreign.json['runId'] : undefined;
194
+ if (foreignId === undefined) return softSkip('blocked', `tenant B's createRun of ${BASE} answered ${foreign?.status ?? 'nothing'}`);
195
+ const r = await runs();
196
+ if ('skip' in r) return softSkip(...r.skip);
197
+ const unknown = await create(CANDIDATE, { evalModes: ['golden', 'regression'], baselineRunId: unknownBeside(r.base.runId) });
198
+ const viaForeign = await create(CANDIDATE, { evalModes: ['golden', 'regression'], baselineRunId: foreignId });
199
+ if (unknown === null || viaForeign === null) return softSkip('blocked', 'POST /runs unreachable (fetch failed)');
200
+ expectAll(ID_UNIFORM, DOC, judgeUniform(answer(unknown), answer(viaForeign), foreignId));
201
+ });
202
+
203
+ it('a baseline without regression, and regression without a baseline, are refused', async () => {
204
+ const g = await gate();
205
+ if ('skip' in g) return softSkip(...g.skip);
206
+ const r = await runs();
207
+ if ('skip' in r) return softSkip(...r.skip);
208
+ const noMode = await create(CANDIDATE, { evalModes: ['golden'], baselineRunId: r.base.runId });
209
+ const noBase = await create(CANDIDATE, { evalModes: ['golden', 'regression'] });
210
+ if (noMode === null || noBase === null) return softSkip('blocked', 'POST /runs unreachable (fetch failed)');
211
+ expectAll(ID_FIELDS, DOC, judgeRefused(answer(noMode), undefined, 'baselineRunId without regression in evalModes'));
212
+ expectAll(ID_FIELDS, DOC, judgeRefused(answer(noBase), undefined, 'regression in evalModes without baselineRunId'));
213
+ });
214
+ });
@@ -36,8 +36,20 @@
36
36
  * length (the mean over identical trials), and on the one-trial run the
37
37
  * counts sum to the log's `agent.tool-called` events. `efficiency` is
38
38
  * optional, so a host that reports none records `inapplicable`. Judge in
39
- * `lib/eval-efficiency-witness.ts`. The never-gated rule is not judged:
40
- * no fixture makes efficiency the only difference between two verdicts.
39
+ * `lib/eval-efficiency-witness.ts`.
40
+ * 6d. §C never-gated (2.46.27), `conformance-eval-efficiency-ungated`: two
41
+ * tasks with one output and one expectation, `lean` (1 scripted call) and
42
+ * `busy` (8). `busy` passes and scores what `lean` scores, and the suite
43
+ * passes at `passScore` 1 (`0244.efficiency-never-gated`). `blocked` when
44
+ * the calls never ran or `lean` itself fails. Gated on `agents.evalSuite`
45
+ * and the fixture only: the rule binds whether or not a host reports
46
+ * `efficiency`.
47
+ * 6e. §B trial isolation (2.46.27, G3), `conformance-eval-memory-isolation`,
48
+ * gated on `trials`: two trials of read seed, read note, write note, read
49
+ * note through the reserved memory tool `conformance.eval:memory`. Every
50
+ * trial reads the seed, and each trial's first note read finds nothing
51
+ * (`0244.trial-memory-isolated`); a tool whose writes never read back is
52
+ * `blocked`. Judge in `lib/eval-memory-witness.ts`.
41
53
  * 6c. §C model usage and §B cost (2.46.26), on the same runs. The per-task
42
54
  * `modelCallCount`, `inputTokens` and `outputTokens`, times the trial
43
55
  * count, sum to the agent's `provider.usage` inside its
@@ -109,7 +121,8 @@ import { judgeEvalEnvelope, judgeSummaryServed } from '../lib/eval-envelope-witn
109
121
  import { gradeTrajectory, passAtK, passHatK, scoreStderr, withinTolerance, type TrajectorySpec } from '../lib/eval-trajectory.js';
110
122
  import { judgeMeanGated, judgeSuiteGated } from '../lib/eval-gate-witness.js';
111
123
  import { judgeFixtureErrorReplayed } from '../lib/eval-fixture-error-witness.js';
112
- import { agentUsage, judgeCostEveryTrial, judgeModelUsage, judgeToolCallCount } from '../lib/eval-efficiency-witness.js';
124
+ import { agentUsage, judgeCostEveryTrial, judgeModelUsage, judgeNeverGated, judgeToolCallCount } from '../lib/eval-efficiency-witness.js';
125
+ import { judgeTrialMemoryIsolated, memoryCalls } from '../lib/eval-memory-witness.js';
113
126
  import { counterCalls, judgeFirstUnconsumed, judgeLiveMiss, judgeMissNoLiveCall, type CounterCall } from '../lib/eval-counter-witness.js';
114
127
 
115
128
  const PROFILE = majorProfile(2);
@@ -128,6 +141,8 @@ const ID_REFUSED = 'openwop.requirement.0244.unadvertised-feature-refused';
128
141
  const ID_EFFICIENCY = 'openwop.requirement.0244.efficiency-tool-calls';
129
142
  const ID_MODEL_USAGE = 'openwop.requirement.0244.efficiency-model-usage';
130
143
  const ID_COST_TRIALS = 'openwop.requirement.0244.cost-every-trial';
144
+ const ID_NEVER_GATED = 'openwop.requirement.0244.efficiency-never-gated';
145
+ const ID_MEMORY_ISOLATED = 'openwop.requirement.0244.trial-memory-isolated';
131
146
  const ID_LIVE_MISS = 'openwop.requirement.0244.live-miss-counted';
132
147
  const ID_FIRST_UNCONSUMED = 'openwop.requirement.0244.first-unconsumed';
133
148
  const ID_NO_LIVE_CALL = 'openwop.requirement.0244.miss-no-live-call';
@@ -224,7 +239,7 @@ describe('v2 RFC 0244 — wire shape (server-free)', () => {
224
239
  });
225
240
 
226
241
  it('the eval-suite fixtures validate against the v2 suite schema', () => {
227
- for (const id of ['conformance-eval-trajectory', 'conformance-eval-trials', 'conformance-eval-fixture-miss', 'conformance-eval-trajectory-gate', 'conformance-eval-trajectory-gate-mean', 'conformance-eval-fixture-error', 'conformance-eval-counter-live', 'conformance-eval-counter-miss']) {
242
+ for (const id of ['conformance-eval-trajectory', 'conformance-eval-trials', 'conformance-eval-fixture-miss', 'conformance-eval-trajectory-gate', 'conformance-eval-trajectory-gate-mean', 'conformance-eval-fixture-error', 'conformance-eval-counter-live', 'conformance-eval-counter-miss', 'conformance-eval-efficiency-ungated', 'conformance-eval-memory-isolation', 'conformance-eval-regression-base', 'conformance-eval-regression-candidate']) {
228
243
  const r = suiteSchema(fixture(id));
229
244
  expect(r.ok, req(ID_FIXTURES, 'fixtures.md §eval-suites', `${id} MUST validate: ${r.errors}`)).toBe(true);
230
245
  }
@@ -376,6 +391,37 @@ describe('v2 RFC 0244 — host behaviour', () => {
376
391
  for (const x of v.findings) expect(x.ok, req(ID_COST_TRIALS, 'agent-eval-suite.schema.json thresholds.maxCostUsd, eval-summary.schema.json totalCostUsd (RFC 0244 §B)', x.message)).toBe(true);
377
392
  });
378
393
 
394
+ it('a host does not fail a task or a suite on efficiency (§C)', async () => {
395
+ const { doc, facet } = await evalSuiteFacet();
396
+ if (!doc) return softSkip('blocked', UNREADABLE);
397
+ if (facet === null) return softSkip('inapplicable', 'the host does not advertise agents.evalSuite');
398
+ const id = 'conformance-eval-efficiency-ungated';
399
+ if (!isFixtureAdvertised(id)) return softSkip('inapplicable', `the host does not advertise fixture ${id}`);
400
+ const o = await runSuite(id);
401
+ if (o.kind === 'skip') return softSkip(o.disposition, o.reason);
402
+ const task = (taskId: string) => ({ taskId, scriptLength: fixture(id).tasks.find((t) => t.taskId === taskId)!.input.script.length });
403
+ const logCalls = o.events.filter((e) => e.type === 'agent.tool-called' && e.payload['agentId'] === AGENT).length;
404
+ const v = judgeNeverGated(o.summary, task('lean'), task('busy'), logCalls);
405
+ if ('blocked' in v) return softSkip('blocked', v.blocked);
406
+ for (const x of v.findings) expect(x.ok, req(ID_NEVER_GATED, 'eval-summary.schema.json efficiency (RFC 0244 §C)', x.message)).toBe(true);
407
+ });
408
+
409
+ it('memory one trial writes is not visible to another trial (§B)', async () => {
410
+ const { doc, facet } = await evalSuiteFacet();
411
+ if (!doc) return softSkip('blocked', UNREADABLE);
412
+ const trials = facet?.['trials'];
413
+ if (!isRecord(trials)) return softSkip('inapplicable', 'the host does not advertise agents.evalSuite.trials');
414
+ const id = 'conformance-eval-memory-isolation';
415
+ const n = fixture(id).trials!.count;
416
+ if (typeof trials['maxTrials'] === 'number' && trials['maxTrials'] < n) return softSkip('inapplicable', `the host advertises trials.maxTrials ${trials['maxTrials']}, below the fixture's ${n}`);
417
+ if (!isFixtureAdvertised(id)) return softSkip('inapplicable', `the host does not advertise fixture ${id}, its opt-in to the memory-tool contract`);
418
+ const o = await runSuite(id);
419
+ if (o.kind === 'skip') return softSkip(o.disposition, o.reason);
420
+ const v = judgeTrialMemoryIsolated(memoryCalls(o.events, AGENT), n);
421
+ if (v.kind === 'blocked') return softSkip('blocked', v.reason);
422
+ for (const x of v.findings) expect(x.ok, req(ID_MEMORY_ISOLATED, 'agent-eval-suite.schema.json trials, fixtures.md memory contract (RFC 0244 §B)', x.message)).toBe(true);
423
+ });
424
+
379
425
  type CounterRuns = { skip: [Parameters<typeof softSkip>[0], string] } | { a: CounterCall[]; b: CounterCall[]; c: CounterCall[]; aMisses: unknown };
380
426
  let counterSeq: Promise<CounterRuns> | undefined;
381
427
  /** A → B → C, strictly in order, once per worker: the three counter legs read the same runs. */