@gate-forge/witness 0.0.0-stage → 0.9.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 (123) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +114 -2
  3. package/dist/adapter/contract-suite.d.ts +167 -0
  4. package/dist/adapter/contract-suite.d.ts.map +1 -0
  5. package/dist/adapter/contract-suite.js +348 -0
  6. package/dist/adapter/contract-suite.js.map +1 -0
  7. package/dist/adapter/contract.d.ts +266 -0
  8. package/dist/adapter/contract.d.ts.map +1 -0
  9. package/dist/adapter/contract.js +2 -0
  10. package/dist/adapter/contract.js.map +1 -0
  11. package/dist/adapter/index.d.ts +8 -0
  12. package/dist/adapter/index.d.ts.map +1 -0
  13. package/dist/adapter/index.js +2 -0
  14. package/dist/adapter/index.js.map +1 -0
  15. package/dist/adapter-kit/config.d.ts +163 -0
  16. package/dist/adapter-kit/config.d.ts.map +1 -0
  17. package/dist/adapter-kit/config.js +21 -0
  18. package/dist/adapter-kit/config.js.map +1 -0
  19. package/dist/adapter-kit/define.d.ts +47 -0
  20. package/dist/adapter-kit/define.d.ts.map +1 -0
  21. package/dist/adapter-kit/define.js +336 -0
  22. package/dist/adapter-kit/define.js.map +1 -0
  23. package/dist/adapter-kit/index.d.ts +34 -0
  24. package/dist/adapter-kit/index.d.ts.map +1 -0
  25. package/dist/adapter-kit/index.js +32 -0
  26. package/dist/adapter-kit/index.js.map +1 -0
  27. package/dist/adapter-kit/projection.d.ts +69 -0
  28. package/dist/adapter-kit/projection.d.ts.map +1 -0
  29. package/dist/adapter-kit/projection.js +85 -0
  30. package/dist/adapter-kit/projection.js.map +1 -0
  31. package/dist/adapter-kit/session.d.ts +105 -0
  32. package/dist/adapter-kit/session.d.ts.map +1 -0
  33. package/dist/adapter-kit/session.js +230 -0
  34. package/dist/adapter-kit/session.js.map +1 -0
  35. package/dist/client/witness-client.d.ts +193 -0
  36. package/dist/client/witness-client.d.ts.map +1 -0
  37. package/dist/client/witness-client.js +321 -0
  38. package/dist/client/witness-client.js.map +1 -0
  39. package/dist/constants.d.ts +189 -0
  40. package/dist/constants.d.ts.map +1 -0
  41. package/dist/constants.js +197 -0
  42. package/dist/constants.js.map +1 -0
  43. package/dist/index.d.ts +15 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +20 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/json.d.ts +16 -0
  48. package/dist/json.d.ts.map +1 -0
  49. package/dist/json.js +21 -0
  50. package/dist/json.js.map +1 -0
  51. package/dist/queue/bullmq.d.ts +28 -0
  52. package/dist/queue/bullmq.d.ts.map +1 -0
  53. package/dist/queue/bullmq.js +210 -0
  54. package/dist/queue/bullmq.js.map +1 -0
  55. package/dist/queue/observer.d.ts +130 -0
  56. package/dist/queue/observer.d.ts.map +1 -0
  57. package/dist/queue/observer.js +179 -0
  58. package/dist/queue/observer.js.map +1 -0
  59. package/dist/surface.d.ts +211 -0
  60. package/dist/surface.d.ts.map +1 -0
  61. package/dist/surface.js +268 -0
  62. package/dist/surface.js.map +1 -0
  63. package/dist/witness/adapter-registry.d.ts +92 -0
  64. package/dist/witness/adapter-registry.d.ts.map +1 -0
  65. package/dist/witness/adapter-registry.js +370 -0
  66. package/dist/witness/adapter-registry.js.map +1 -0
  67. package/dist/witness/behavior-request.d.ts +80 -0
  68. package/dist/witness/behavior-request.d.ts.map +1 -0
  69. package/dist/witness/behavior-request.js +335 -0
  70. package/dist/witness/behavior-request.js.map +1 -0
  71. package/dist/witness/behavior.d.ts +52 -0
  72. package/dist/witness/behavior.d.ts.map +1 -0
  73. package/dist/witness/behavior.js +118 -0
  74. package/dist/witness/behavior.js.map +1 -0
  75. package/dist/witness/bin.d.ts +21 -0
  76. package/dist/witness/bin.d.ts.map +1 -0
  77. package/dist/witness/bin.js +254 -0
  78. package/dist/witness/bin.js.map +1 -0
  79. package/dist/witness/browser.d.ts +221 -0
  80. package/dist/witness/browser.d.ts.map +1 -0
  81. package/dist/witness/browser.js +644 -0
  82. package/dist/witness/browser.js.map +1 -0
  83. package/dist/witness/chaos.d.ts +179 -0
  84. package/dist/witness/chaos.d.ts.map +1 -0
  85. package/dist/witness/chaos.js +270 -0
  86. package/dist/witness/chaos.js.map +1 -0
  87. package/dist/witness/classifications.d.ts +42 -0
  88. package/dist/witness/classifications.d.ts.map +1 -0
  89. package/dist/witness/classifications.js +87 -0
  90. package/dist/witness/classifications.js.map +1 -0
  91. package/dist/witness/env-attestation.d.ts +98 -0
  92. package/dist/witness/env-attestation.d.ts.map +1 -0
  93. package/dist/witness/env-attestation.js +202 -0
  94. package/dist/witness/env-attestation.js.map +1 -0
  95. package/dist/witness/fixture-provider.d.ts +89 -0
  96. package/dist/witness/fixture-provider.d.ts.map +1 -0
  97. package/dist/witness/fixture-provider.js +116 -0
  98. package/dist/witness/fixture-provider.js.map +1 -0
  99. package/dist/witness/loopback-pins.d.ts +79 -0
  100. package/dist/witness/loopback-pins.d.ts.map +1 -0
  101. package/dist/witness/loopback-pins.js +244 -0
  102. package/dist/witness/loopback-pins.js.map +1 -0
  103. package/dist/witness/run-options.d.ts +47 -0
  104. package/dist/witness/run-options.d.ts.map +1 -0
  105. package/dist/witness/run-options.js +179 -0
  106. package/dist/witness/run-options.js.map +1 -0
  107. package/dist/witness/server.d.ts +34 -0
  108. package/dist/witness/server.d.ts.map +1 -0
  109. package/dist/witness/server.js +4963 -0
  110. package/dist/witness/server.js.map +1 -0
  111. package/dist/witness/task.d.ts +77 -0
  112. package/dist/witness/task.d.ts.map +1 -0
  113. package/dist/witness/task.js +201 -0
  114. package/dist/witness/task.js.map +1 -0
  115. package/dist/witness/twin-shapes.d.ts +51 -0
  116. package/dist/witness/twin-shapes.d.ts.map +1 -0
  117. package/dist/witness/twin-shapes.js +127 -0
  118. package/dist/witness/twin-shapes.js.map +1 -0
  119. package/dist/witness/types.d.ts +1094 -0
  120. package/dist/witness/types.d.ts.map +1 -0
  121. package/dist/witness/types.js +2 -0
  122. package/dist/witness/types.js.map +1 -0
  123. package/package.json +98 -4
@@ -0,0 +1,348 @@
1
+ /**
2
+ * The runner-adapter contract suite (plan 2026-09-25 phase 0).
3
+ *
4
+ * One shared conformance suite every runner adapter must pass. The suite
5
+ * owns the ASSERTIONS; a {@link RunnerContractHost} owns only the
6
+ * runner mechanics (which files to materialize, how to spawn the runner,
7
+ * where its structured report lands). Nothing here parses a runner's
8
+ * output — the adapter does that, and the suite checks the adapter did
9
+ * it honestly.
10
+ *
11
+ * The suite is deliberately framework-free (no test runner import): each
12
+ * adapter's package runs {@link runRunnerAdapterContract} and asserts
13
+ * the returned violation list is empty. That keeps one implementation
14
+ * of "what a runner adapter must do" instead of N look-alike copies.
15
+ *
16
+ * Grading always runs through `superviseExecution`
17
+ * (`@gate-forge/core`) — the neutral completeness rules. The suite never
18
+ * invents a verdict of its own, so a contract pass means the adapter
19
+ * feeds the same enforcement point a Playwright run feeds.
20
+ */
21
+ import { superviseExecution } from '@gate-forge/core';
22
+ /** The session context a run wires for a planned test. */
23
+ function sessionContext(overrides = {}) {
24
+ return {
25
+ witnessUrl: 'http://127.0.0.1:1',
26
+ runToken: 'contract-suite-run-token',
27
+ sessionId: 'contract-suite-session',
28
+ sessionToken: 'contract-suite-session-token',
29
+ sessionProxyUrl: 'http://127.0.0.1:1/session/contract-suite-session',
30
+ appBaseUrl: 'http://127.0.0.1:2',
31
+ ...overrides,
32
+ };
33
+ }
34
+ /**
35
+ * The identity key an adapter's outcome `logicalKey` encodes: the
36
+ * repo-relative file and the full title path, joined the way the engine
37
+ * already keys claim injections (`<file>#<titlePath.join('>')>`). The
38
+ * contract reads it back so a scenario can grade an outcome the adapter
39
+ * did not plan — which is exactly what an unplanned run produces.
40
+ */
41
+ function identityOfOutcome(logicalKey) {
42
+ const hash = logicalKey.indexOf('#');
43
+ if (hash < 0)
44
+ return { file: logicalKey, titlePath: [] };
45
+ return {
46
+ file: logicalKey.slice(0, hash),
47
+ titlePath: logicalKey.slice(hash + 1).split('>'),
48
+ };
49
+ }
50
+ /** The identity key an enumerated test is joined on. */
51
+ function identityOfTest(test) {
52
+ return `${test.project ?? '-'}\u0000${test.file}\u0000${test.titlePath.join('>')}`;
53
+ }
54
+ /** The identity key a scenario's planned test is joined on. */
55
+ function identityOfScenario(scenario) {
56
+ return `${scenario.project ?? '-'}\u0000${scenario.file}\u0000${scenario.titlePath.join('>')}`;
57
+ }
58
+ /**
59
+ * The canonical scenario for one kind, with the host's own scenario
60
+ * naming when it declared one (runner-native file/title path; see
61
+ * {@link RunnerContractHost.scenario}).
62
+ */
63
+ function scenarioFor(host, kind) {
64
+ return contractScenario(kind, { project: host.project, ...(host.scenario ?? {}) });
65
+ }
66
+ /** The planned instance for a scenario (the expected set, fixed pre-run). */
67
+ function plannedOf(scenario) {
68
+ return scenario.expectedLogicalKeys.map((logicalKey) => ({
69
+ logicalKey,
70
+ project: scenario.project,
71
+ file: scenario.file,
72
+ titlePath: scenario.titlePath,
73
+ blockingAnnotations: [],
74
+ }));
75
+ }
76
+ /** Env names that must never reach a runner child through any channel. */
77
+ const FORBIDDEN_CHILD_ENV = [
78
+ 'GATEFORGE_WITNESS_VERIFIER_KEY',
79
+ 'GATEFORGE_WITNESS_VERIFIER_KEY_FILE',
80
+ 'GATEFORGE_OBLIGATIONS',
81
+ 'GATEFORGE_OUTCOMES_FILE',
82
+ 'GATEFORGE_ADAPTERS_DIR',
83
+ 'GATEFORGE_CLASSIFICATIONS',
84
+ 'GATEFORGE_ADAPTER_BASE_URL',
85
+ ];
86
+ /** The scenarios every adapter is graded on, in a stable order. */
87
+ export const CONTRACT_SCENARIOS = [
88
+ 'pass',
89
+ 'fail',
90
+ 'skip',
91
+ 'retry',
92
+ 'unplanned',
93
+ 'zero',
94
+ ];
95
+ /** Builds the canonical scenario for one kind (single planned test). */
96
+ export function contractScenario(kind, overrides = {}) {
97
+ const file = overrides.file ?? 'e2e/contract.spec.ts';
98
+ const titlePath = overrides.titlePath ?? ['contract'];
99
+ return {
100
+ kind,
101
+ file,
102
+ titlePath,
103
+ project: overrides.project ?? null,
104
+ expectedLogicalKeys: overrides.expectedLogicalKeys ?? [
105
+ `${file}#${titlePath.join('>')}`,
106
+ ],
107
+ };
108
+ }
109
+ /**
110
+ * Runs the full contract against one adapter.
111
+ *
112
+ * Every check is fail-closed: an adapter that throws, reports a missing
113
+ * field, or grades a dishonest run green produces a violation. The
114
+ * returned list is the whole result — an empty list is a pass.
115
+ *
116
+ * Args:
117
+ * adapter: the adapter under test.
118
+ * host: the runner mechanics for `adapter.runner`.
119
+ *
120
+ * Returns:
121
+ * Promise<ContractViolation[]>: every contract case that failed.
122
+ */
123
+ export async function runRunnerAdapterContract(adapter, host) {
124
+ const violations = [];
125
+ const fail = (name, detail) => {
126
+ violations.push({ case: name, detail });
127
+ };
128
+ if (host.runner !== adapter.runner) {
129
+ fail('runner-name-matches', `the contract host serves '${host.runner}' but the adapter reports '${adapter.runner}'`);
130
+ return violations;
131
+ }
132
+ if (adapter.capabilities.inventory !== 'available') {
133
+ fail('capabilities-declared', `a witness-producing adapter must declare inventory 'available' (got '${adapter.capabilities.inventory}')`);
134
+ }
135
+ if (adapter.capabilities.execute !== 'available') {
136
+ fail('capabilities-declared', `a witness-producing adapter must declare execute 'available' (got '${adapter.capabilities.execute}')`);
137
+ }
138
+ await checkEnumeration(adapter, host, fail);
139
+ await checkTagging(adapter, fail);
140
+ checkReportParsing(adapter, host, fail);
141
+ await checkExecute(adapter, host, fail);
142
+ for (const kind of CONTRACT_SCENARIOS) {
143
+ await checkScenario(adapter, host, kind, fail);
144
+ }
145
+ return violations;
146
+ }
147
+ /** The expected set must be listed before the run, and never faked empty. */
148
+ async function checkEnumeration(adapter, host, fail) {
149
+ const scenario = scenarioFor(host, 'pass');
150
+ const root = await host.materialize(scenario);
151
+ let enumeration;
152
+ try {
153
+ enumeration = await adapter.enumerate(root);
154
+ }
155
+ catch (error) {
156
+ fail('enumeration-lists-the-expected-set', `enumerate threw: ${errorMessage(error)}`);
157
+ return;
158
+ }
159
+ if (enumeration.status !== 'discovered') {
160
+ fail('enumeration-lists-the-expected-set', `enumerate returned '${enumeration.status}' (${enumeration.detail}) for a project that has tests`);
161
+ return;
162
+ }
163
+ // Joined on IDENTITY (project + file + title path), the same join
164
+ // supervision uses — never on a key format the contract would have to
165
+ // predict for every runner.
166
+ const found = new Set(enumeration.tests.map(identityOfTest));
167
+ if (!found.has(identityOfScenario(scenario))) {
168
+ fail('enumeration-lists-the-expected-set', `enumerate omitted the planned test (saw [${[...found].join(' | ')}])`);
169
+ }
170
+ for (const test of enumeration.tests) {
171
+ if (test.file === '' || test.titlePath.length === 0) {
172
+ fail('enumeration-carries-identity', `enumerated test '${test.logicalKey}' has no file/titlePath identity — supervision cannot join it`);
173
+ }
174
+ }
175
+ const emptyRoot = await host.materialize(scenarioFor(host, 'zero'));
176
+ let empty;
177
+ try {
178
+ empty = await adapter.enumerate(emptyRoot);
179
+ }
180
+ catch (error) {
181
+ fail('zero-tests-never-reads-as-discovered', `enumerate threw: ${errorMessage(error)}`);
182
+ return;
183
+ }
184
+ if (empty.status !== 'unavailable' || empty.tests.length !== 0) {
185
+ fail('zero-tests-never-reads-as-discovered', `a project with no runnable tests must enumerate as 'unavailable', got '${empty.status}' with ${String(empty.tests.length)} test(s)`);
186
+ }
187
+ }
188
+ /**
189
+ * The tag must vary per session: a constant tag is unattributed traffic
190
+ * wearing a tag, which is exactly the rule the witness already enforces
191
+ * for traffic that bypasses every session channel.
192
+ */
193
+ async function checkTagging(adapter, fail) {
194
+ const first = adapter.childEnv({ logicalKey: 'a#one', frameworkId: 'one', project: null }, sessionContext());
195
+ const second = adapter.childEnv({ logicalKey: 'a#two', frameworkId: 'two', project: null }, sessionContext({ sessionId: 'contract-suite-session-2', sessionToken: 'contract-suite-session-token-2', sessionProxyUrl: 'http://127.0.0.1:1/session/contract-suite-session-2' }));
196
+ if (first.tagChannel === 'none' || second.tagChannel === 'none') {
197
+ fail('traffic-is-tagged', `childEnv reported tagChannel 'none' — a runner whose traffic cannot be attributed can never produce witness evidence`);
198
+ }
199
+ const identity = new Set([...first.identityVars, ...second.identityVars]);
200
+ if (identity.size === 0) {
201
+ fail('traffic-is-tagged', 'childEnv declared no identity variables — nothing tags the test');
202
+ return;
203
+ }
204
+ const differing = [...identity].filter((name) => first.vars[name] !== second.vars[name]);
205
+ if (differing.length === 0) {
206
+ fail('tag-varies-per-session', `no identity variable (${[...identity].join(', ')}) differs between two sessions — every test would be attributed to the same session`);
207
+ }
208
+ for (const [name, value] of Object.entries({ ...first.vars, ...second.vars })) {
209
+ if (FORBIDDEN_CHILD_ENV.includes(name)) {
210
+ fail('child-env-carries-no-parent-side-wiring', `childEnv leaked parent-side '${name}' to the runner child`);
211
+ }
212
+ if (value === '') {
213
+ fail('child-env-carries-no-parent-side-wiring', `childEnv emitted an empty value for '${name}'`);
214
+ }
215
+ }
216
+ const channel = first.tagChannel;
217
+ if (channel === 'session-proxy' && (first.vars['GATEFORGE_SESSION_PROXY_URL'] ?? '') === '') {
218
+ fail('traffic-is-tagged', "tagChannel 'session-proxy' requires GATEFORGE_SESSION_PROXY_URL in the child env");
219
+ }
220
+ }
221
+ /** An unreadable report is never a green run, and never a fabricated set. */
222
+ function checkReportParsing(adapter, host, fail) {
223
+ const garbage = adapter.parseResults({ processExit: 0, report: '' });
224
+ if (garbage.complete) {
225
+ fail('unreadable-report-fails-closed', 'parseResults read an empty report as a complete run — a missing report never proves anything');
226
+ }
227
+ if (garbage.outcomes.length !== 0) {
228
+ fail('unreadable-report-fails-closed', `parseResults invented ${String(garbage.outcomes.length)} outcome(s) from an empty report`);
229
+ }
230
+ const noExit = adapter.parseResults({ processExit: null, report: '' });
231
+ if (noExit.complete) {
232
+ fail('unreadable-report-fails-closed', 'a run with no exit status is incomplete, never complete');
233
+ }
234
+ // A row the adapter cannot identify belongs to NO test: untagged
235
+ // traffic is never attributed, which is the same rule the witness
236
+ // applies to a request that bypassed every session channel.
237
+ const untagged = adapter.parseResults({ processExit: 0, report: host.untaggedReport() });
238
+ if (untagged.complete) {
239
+ fail('untagged-traffic-is-not-attributed', 'a report whose rows carry no runner framework id graded complete — a test the adapter cannot identify is never attributed to a test');
240
+ }
241
+ }
242
+ /**
243
+ * The job-3 check: the adapter must be able to RUN a suite itself, not
244
+ * only read reports. One real supervised `execute` over the `pass`
245
+ * project, graded exactly like a scenario.
246
+ */
247
+ async function checkExecute(adapter, host, fail) {
248
+ const name = 'execute-runs-a-suite';
249
+ const scenario = scenarioFor(host, 'pass');
250
+ const root = await host.materialize(scenario);
251
+ const request = host.executeRequest(root, scenario);
252
+ let envelope;
253
+ try {
254
+ envelope = await adapter.execute(request);
255
+ }
256
+ catch (error) {
257
+ fail(name, `execute threw: ${errorMessage(error)}`);
258
+ return;
259
+ }
260
+ if (envelope.outcomes.length === 0) {
261
+ fail(name, 'execute reported no outcomes for a project that has a passing test');
262
+ return;
263
+ }
264
+ const graded = superviseExecution(plannedOf(scenario), {
265
+ processExit: envelope.processExit,
266
+ complete: envelope.complete,
267
+ ...(envelope.incompleteDetail !== undefined ? { incompleteDetail: envelope.incompleteDetail } : {}),
268
+ outcomes: envelope.outcomes.map((outcome) => ({
269
+ ...identityOfOutcome(outcome.logicalKey),
270
+ logicalKey: outcome.logicalKey,
271
+ project: outcome.project,
272
+ status: outcome.status,
273
+ attempt: outcome.attempt,
274
+ expectedFailure: outcome.expectedFailure ?? false,
275
+ })),
276
+ fixtureOutcome: envelope.fixtureOutcome ?? 'unknown',
277
+ shards: envelope.shards ?? null,
278
+ retriesDetected: envelope.retriesDetected ?? false,
279
+ ...(envelope.retriesDetail !== undefined ? { retriesDetail: envelope.retriesDetail } : {}),
280
+ });
281
+ if (!graded.complete) {
282
+ fail(name, `execute ran the passing project but supervision blocked it: ${graded.findings[0]?.detail ?? ''}`);
283
+ }
284
+ }
285
+ /** One scenario: run it and assert supervision blocks exactly as it must. */
286
+ async function checkScenario(adapter, host, kind, fail) {
287
+ const name = `scenario-${kind}`;
288
+ const scenario = scenarioFor(host, kind);
289
+ const root = await host.materialize(scenario);
290
+ let observation;
291
+ try {
292
+ observation = await host.run(adapter, root, scenario);
293
+ }
294
+ catch (error) {
295
+ fail(name, `the host could not run the scenario: ${errorMessage(error)}`);
296
+ return;
297
+ }
298
+ const planned = plannedOf(scenario);
299
+ const graded = superviseExecution(planned, {
300
+ processExit: observation.envelope.processExit,
301
+ complete: observation.envelope.complete,
302
+ ...(observation.envelope.incompleteDetail !== undefined
303
+ ? { incompleteDetail: observation.envelope.incompleteDetail }
304
+ : {}),
305
+ outcomes: observation.envelope.outcomes.map((outcome) => ({
306
+ ...identityOfOutcome(outcome.logicalKey),
307
+ logicalKey: outcome.logicalKey,
308
+ project: outcome.project,
309
+ status: outcome.status,
310
+ attempt: outcome.attempt,
311
+ expectedFailure: outcome.expectedFailure ?? false,
312
+ })),
313
+ fixtureOutcome: observation.envelope.fixtureOutcome ?? 'unknown',
314
+ shards: observation.envelope.shards ?? null,
315
+ retriesDetected: observation.envelope.retriesDetected ?? false,
316
+ ...(observation.envelope.retriesDetail !== undefined
317
+ ? { retriesDetail: observation.envelope.retriesDetail }
318
+ : {}),
319
+ });
320
+ const causes = graded.findings.map((finding) => finding.cause);
321
+ switch (kind) {
322
+ case 'pass':
323
+ if (!graded.complete) {
324
+ fail(name, `a complete first-attempt passing run was blocked: ${graded.findings[0]?.detail ?? ''}`);
325
+ }
326
+ if (observation.envelope.outcomes.length !== scenario.expectedLogicalKeys.length) {
327
+ fail(name, `a passing run reported ${String(observation.envelope.outcomes.length)} outcome(s) for ${String(scenario.expectedLogicalKeys.length)} planned test(s)`);
328
+ }
329
+ return;
330
+ case 'zero':
331
+ if (graded.complete) {
332
+ fail(name, 'a run that executed no test graded complete — nothing executed proves nothing');
333
+ }
334
+ return;
335
+ default:
336
+ if (graded.complete) {
337
+ fail(name, `a '${kind}' run graded complete — it must block`);
338
+ }
339
+ if (!causes.includes('TEST_NOT_EXECUTED') && !causes.includes('TEST_FAILED') && !causes.includes('RUN_INCOMPLETE')) {
340
+ fail(name, `a '${kind}' run blocked with no typed cause (saw [${causes.join(', ')}])`);
341
+ }
342
+ }
343
+ }
344
+ /** Single-line message of an unknown thrown value. */
345
+ function errorMessage(error) {
346
+ return error instanceof Error ? error.message : String(error);
347
+ }
348
+ //# sourceMappingURL=contract-suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-suite.js","sourceRoot":"","sources":["../../src/adapter/contract-suite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * The runner-adapter contract (plan 2026-09-25 phase 0): the four jobs
3
+ * every test runner performs so the witness can produce the SAME trusted
4
+ * evidence for it.
5
+ *
6
+ * WHY this shape. The witness is an HTTP proxy plus a DB/queue reader; a
7
+ * proxy does not care who sends the traffic. Everything runner-specific
8
+ * collapses into four operations:
9
+ *
10
+ * 1. `enumerate()` — LIST the tests BEFORE the run. The expected set is
11
+ * fixed first (the same rule the Playwright path already follows).
12
+ * 2. `childEnv()` — TAG every request with the test identity: a
13
+ * per-test session proxy URL (what Playwright uses today) or a signed
14
+ * session header.
15
+ * 3. `execute()` — RUN the suite under trusted supervision.
16
+ * 4. `parseResults()` — READ the outcome in a structured format (native
17
+ * JSON or JUnit XML). Terminal colors are never parsed.
18
+ *
19
+ * Honesty rules baked into the contract (frozen JSON keys, cause codes
20
+ * and exit codes — additions only):
21
+ * - A runner's own "passed" is never authority. `parseResults` produces
22
+ * reporter INPUT; the verdict comes from `superviseExecution` in
23
+ * `@gate-forge/core` plus the witness-issued session trace.
24
+ * - An empty enumeration is `unavailable`, never a discovered run of
25
+ * zero tests: nothing executed proves nothing.
26
+ * - A runner that cannot attribute its traffic (no session tag) says so
27
+ * with `tagChannel: 'none'`; the supervisor then refuses to attribute
28
+ * ANY exchange to that test instead of guessing.
29
+ * - `execute` and `parseResults` share the envelope so a caller can read
30
+ * a runner's report without spawning the runner.
31
+ */
32
+ import type { RunnerCapabilities, RunnerExecutionEnvelope } from '@gate-forge/core';
33
+ /** Runner name the contract's cross-references accept today. */
34
+ export type RunnerName = 'playwright' | 'cypress' | 'pytest' | 'vitest' | (string & {});
35
+ /**
36
+ * How a runner's traffic is attributed to one test.
37
+ *
38
+ * - `session-proxy`: the test addresses the witness through a per-test
39
+ * session proxy prefix (Playwright's `page`-level proxy today).
40
+ * - `signed-header`: the test carries a per-test signed session header
41
+ * on every request (no proxy address to rewrite).
42
+ * - `none`: the runner cannot tag its traffic. Traffic is NEVER
43
+ * attributed to a test in this mode — the same fail-closed rule the
44
+ * Playwright path applies to "bypassed every session channel".
45
+ */
46
+ export type RunnerTagChannel = 'session-proxy' | 'signed-header' | 'none';
47
+ /**
48
+ * One test the runner is expected to run, enumerated BEFORE the run.
49
+ *
50
+ * Mirrors `PlannedInstanceInput` from `@gate-forge/core` so the
51
+ * expected set crosses into supervision without a lossy re-shape.
52
+ */
53
+ export interface RunnerTestIdentity {
54
+ /** Stable logical key (the identity join key). */
55
+ logicalKey: string;
56
+ /** Runner project, or null when the runner reports none. */
57
+ project: string | null;
58
+ /** Repo-relative posix file (the identity join key). */
59
+ file: string;
60
+ /** Full title path (the identity join key). */
61
+ titlePath: readonly string[];
62
+ /** Blocking annotations observed pre-run (`.skip` / `.only` / `.fixme`). */
63
+ blockingAnnotations: readonly string[];
64
+ /**
65
+ * The runner's own id for this test, EXACTLY as the runner-side
66
+ * reporter writes it into the lifecycle spool (additive, plan
67
+ * 2026-09-25 runner-agnostic evidence): the pytest node id, the
68
+ * `<file>#<title path>` key for vitest and cypress. Optional — the
69
+ * trusted supervisor registers the expected set with it so the
70
+ * witness-side trace names the same identities the child will spool;
71
+ * a missing id falls back to the logical key.
72
+ */
73
+ frameworkId?: string;
74
+ }
75
+ /** Outcome of one `enumerate()` call (never a silent empty success). */
76
+ export interface RunnerEnumeration {
77
+ /**
78
+ * `discovered` only when the runner reported a real, non-empty test
79
+ * set. A zero-test run, a missing runner, and a collection error are
80
+ * all `unavailable` — nothing executed proves nothing.
81
+ */
82
+ status: 'discovered' | 'unavailable';
83
+ /** Single-cause detail (bounded), always populated when unavailable. */
84
+ detail: string;
85
+ /** The enumerated tests (empty exactly when `status` is `unavailable`). */
86
+ tests: readonly RunnerTestIdentity[];
87
+ /** Runner version the enumeration observed, when the runner reports one. */
88
+ engineVersion?: string;
89
+ }
90
+ /** The one test a `childEnv()` call is tagging. */
91
+ export interface RunnerSessionTag {
92
+ /** The logical key the traffic will be attributed to. */
93
+ logicalKey: string;
94
+ /** The runner's own instance id for this test (spec id, node id). */
95
+ frameworkId: string;
96
+ /** Runner project, or null. */
97
+ project: string | null;
98
+ }
99
+ /**
100
+ * Run-scoped wiring the adapter needs to build a child's environment.
101
+ *
102
+ * Every field is NON-SECRET: the witness's run token and the per-test
103
+ * session token are the only signing material a test may hold, and
104
+ * neither can mint, seal or re-seal a session (the supervisor's channel
105
+ * is verifier-key authenticated and unreachable from the suite).
106
+ */
107
+ export interface RunnerChildEnvContext {
108
+ /** Absolute witness base URL the child talks to. */
109
+ witnessUrl: string;
110
+ /** Run token the child presents on witness calls. */
111
+ runToken: string;
112
+ /** Per-test session id the supervisor opened for the tagged test. */
113
+ sessionId: string;
114
+ /** Per-test session token the child presents for interval/HTTP calls. */
115
+ sessionToken: string;
116
+ /** Absolute per-test session proxy prefix (empty for header tagging). */
117
+ sessionProxyUrl: string;
118
+ /** Absolute base URL of the application under test. */
119
+ appBaseUrl: string;
120
+ }
121
+ /** The environment one tagged test's process must see. */
122
+ export interface RunnerChildEnv {
123
+ /**
124
+ * The variables to ADD to the runner child. The adapter never returns
125
+ * a wholesale `process.env` copy: the caller owns the allowlist.
126
+ */
127
+ vars: Readonly<Record<string, string>>;
128
+ /** How the child's traffic is attributed (see {@link RunnerTagChannel}). */
129
+ tagChannel: RunnerTagChannel;
130
+ /**
131
+ * The variable names carrying the TEST IDENTITY. At least one must
132
+ * differ between two sessions of the same run — the contract suite
133
+ * asserts exactly that, because a constant tag is unattributed
134
+ * traffic wearing a tag.
135
+ */
136
+ identityVars: readonly string[];
137
+ /**
138
+ * The runner-side mechanism the tag travels on (a support-file
139
+ * injection, a plugin fixture, an interceptor). Diagnostic: it is what
140
+ * a failing run's report should name.
141
+ */
142
+ mechanism: string;
143
+ }
144
+ /** The raw, structured results of one runner execution. */
145
+ export interface RunnerRawResults {
146
+ /** The runner process exit status (null when it never started). */
147
+ processExit: number | null;
148
+ /**
149
+ * The working directory the report's file paths are relative to, when
150
+ * the runner reports ABSOLUTE paths (some JSON reporters do). Absent
151
+ * means the report's paths are already repo-relative — or that the
152
+ * adapter attributes nothing, rather than guessing a base.
153
+ */
154
+ cwd?: string;
155
+ /**
156
+ * The runner's structured report: native JSON, JUnit XML, or the
157
+ * witness-facing outcomes document. Never terminal output.
158
+ */
159
+ report: string;
160
+ /** True when the runner reported the run was sharded. */
161
+ sharded?: boolean;
162
+ /** Shard completeness detail, when the runner reported shards. */
163
+ shardDetail?: string;
164
+ /**
165
+ * Setup/teardown/runner-body outcome the runner reported. Absent =
166
+ * unknown, which grades fail-closed downstream.
167
+ */
168
+ fixtureOutcome?: 'passed' | 'failed' | 'unknown';
169
+ }
170
+ /** What `execute()` is asked to run. */
171
+ export interface RunnerExecuteRequest {
172
+ /** Exact logical keys selected for the run (never a wildcard). */
173
+ logicalKeys: readonly string[];
174
+ /** Absolute run-state directory (excluded from tracked inputs). */
175
+ stateDir: string;
176
+ /** Run id the execution binds to. */
177
+ runId: string;
178
+ /** Whole-run wall-clock bound; expiry is an incomplete run. */
179
+ timeoutMs: number;
180
+ /** Absolute repo root the runner configuration lives under. */
181
+ cwd: string;
182
+ /**
183
+ * Selection mode (additive; absent = `full-relevant-suite`, whose
184
+ * execution is byte-identical to before). A `named-selection` run
185
+ * executes ONLY the named tests: the adapter narrows below file
186
+ * granularity wherever its runner can, and any test it cannot
187
+ * exclude is reported, never silently graded.
188
+ */
189
+ mode?: 'full-relevant-suite' | 'mapped-selection' | 'named-selection';
190
+ /**
191
+ * Exact repo-relative `file:line` locations of the selected tests, as
192
+ * the plan fixed them before the run. Playwright executes exactly
193
+ * these. Undefined = file granularity.
194
+ */
195
+ testLocations?: readonly string[];
196
+ /**
197
+ * The runner's own project names to run, exactly as `enumerate`
198
+ * reported them. Part of the identity join key, so a run that does
199
+ * not select them grades its outcomes against a different identity
200
+ * than the expected set was fixed with.
201
+ */
202
+ projects?: readonly string[];
203
+ }
204
+ /**
205
+ * The runner-adapter contract.
206
+ *
207
+ * @typeParam TReport - the runner's native report shape, when an adapter
208
+ * wants to expose it (the contract itself only needs the text).
209
+ */
210
+ export interface RunnerAdapter<TReport = unknown> {
211
+ /** Runner name this adapter serves, e.g. `cypress`. */
212
+ readonly runner: RunnerName;
213
+ /** Declared capabilities — callers honor, never assume. */
214
+ readonly capabilities: RunnerCapabilities;
215
+ /**
216
+ * Job 1: lists the runner's tests BEFORE the run.
217
+ *
218
+ * Args:
219
+ * cwd: absolute repo root the runner configuration lives under.
220
+ *
221
+ * Returns:
222
+ * Promise<RunnerEnumeration>: the expected set, or an `unavailable`
223
+ * verdict with a single cause. Never an empty `discovered` list.
224
+ */
225
+ enumerate(cwd: string): Promise<RunnerEnumeration>;
226
+ /**
227
+ * Job 2: builds the environment that tags one test's traffic.
228
+ *
229
+ * Args:
230
+ * session: the test being tagged.
231
+ * context: run-scoped, non-secret witness wiring.
232
+ *
233
+ * Returns:
234
+ * RunnerChildEnv: the variables plus the channel the tag travels on.
235
+ */
236
+ childEnv(session: RunnerSessionTag, context: RunnerChildEnvContext): RunnerChildEnv;
237
+ /**
238
+ * Job 3: runs the suite under trusted supervision.
239
+ *
240
+ * Args:
241
+ * request: the exact selection, run identity, and wall-clock bound.
242
+ *
243
+ * Returns:
244
+ * Promise<RunnerExecutionEnvelope>: the structured outcome envelope
245
+ * (a runner exit code alone is never a gate result).
246
+ */
247
+ execute(request: RunnerExecuteRequest): Promise<RunnerExecutionEnvelope>;
248
+ /**
249
+ * Job 4: reads one structured report into the outcome envelope.
250
+ *
251
+ * Args:
252
+ * raw: the runner's structured report plus its exit status.
253
+ *
254
+ * Returns:
255
+ * RunnerExecutionEnvelope: reporter INPUT for supervision, never a
256
+ * verdict. An unreadable report is `complete: false`.
257
+ */
258
+ parseResults(raw: RunnerRawResults): RunnerExecutionEnvelope;
259
+ /**
260
+ * The runner's native parsed report, for callers that need the
261
+ * runner-specific shape (diagnostics surfaces). Optional: an adapter
262
+ * whose report is only ever read as an envelope omits it.
263
+ */
264
+ parseReport?(raw: RunnerRawResults): TReport;
265
+ }
266
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/adapter/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEpF,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAExF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,eAAe,GAAG,MAAM,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC;IACrC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvC,4EAA4E;IAC5E,UAAU,EAAE,gBAAgB,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CAClD;AAED,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,qBAAqB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;IACtE;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,OAAO;IAC9C,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C;;;;;;;;;OASG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACnD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAAC;IACpF;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzE;;;;;;;;;OASG;IACH,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC7D;;;;OAIG;IACH,WAAW,CAAC,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC;CAC9C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/adapter/contract.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `@gate-forge/witness/adapter` — the runner-adapter contract and the
3
+ * conformance suite every runner must pass (plan 2026-09-25 phase 0).
4
+ */
5
+ export type { RunnerAdapter, RunnerChildEnv, RunnerChildEnvContext, RunnerEnumeration, RunnerExecuteRequest, RunnerName, RunnerRawResults, RunnerSessionTag, RunnerTagChannel, RunnerTestIdentity, } from './contract.js';
6
+ export type { ContractObservation, ContractScenario, ContractScenarioKind, ContractViolation, RunnerContractHost, } from './contract-suite.js';
7
+ export { CONTRACT_SCENARIOS, contractScenario, runRunnerAdapterContract } from './contract-suite.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EACV,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}