@gate-forge/pack-playwright 0.1.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 (140) hide show
  1. package/LICENSE +202 -0
  2. package/bin/gateforge-witness.js +40 -0
  3. package/dist/attestation/proxy.d.ts +40 -0
  4. package/dist/attestation/proxy.d.ts.map +1 -0
  5. package/dist/attestation/proxy.js +78 -0
  6. package/dist/attestation/proxy.js.map +1 -0
  7. package/dist/constants.d.ts +130 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +138 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/discovery/adapters.d.ts +167 -0
  12. package/dist/discovery/adapters.d.ts.map +1 -0
  13. package/dist/discovery/adapters.js +276 -0
  14. package/dist/discovery/adapters.js.map +1 -0
  15. package/dist/discovery/discover.d.ts +57 -0
  16. package/dist/discovery/discover.d.ts.map +1 -0
  17. package/dist/discovery/discover.js +544 -0
  18. package/dist/discovery/discover.js.map +1 -0
  19. package/dist/discovery/index.d.ts +15 -0
  20. package/dist/discovery/index.d.ts.map +1 -0
  21. package/dist/discovery/index.js +15 -0
  22. package/dist/discovery/index.js.map +1 -0
  23. package/dist/discovery/inference.d.ts +63 -0
  24. package/dist/discovery/inference.d.ts.map +1 -0
  25. package/dist/discovery/inference.js +173 -0
  26. package/dist/discovery/inference.js.map +1 -0
  27. package/dist/discovery/pytest-adapter.d.ts +205 -0
  28. package/dist/discovery/pytest-adapter.d.ts.map +1 -0
  29. package/dist/discovery/pytest-adapter.js +548 -0
  30. package/dist/discovery/pytest-adapter.js.map +1 -0
  31. package/dist/discovery/reconcile.d.ts +106 -0
  32. package/dist/discovery/reconcile.d.ts.map +1 -0
  33. package/dist/discovery/reconcile.js +268 -0
  34. package/dist/discovery/reconcile.js.map +1 -0
  35. package/dist/discovery/runner-env.d.ts +80 -0
  36. package/dist/discovery/runner-env.d.ts.map +1 -0
  37. package/dist/discovery/runner-env.js +139 -0
  38. package/dist/discovery/runner-env.js.map +1 -0
  39. package/dist/discovery/static-discovery.d.ts +121 -0
  40. package/dist/discovery/static-discovery.d.ts.map +1 -0
  41. package/dist/discovery/static-discovery.js +1028 -0
  42. package/dist/discovery/static-discovery.js.map +1 -0
  43. package/dist/discovery/supervised-run.d.ts +110 -0
  44. package/dist/discovery/supervised-run.d.ts.map +1 -0
  45. package/dist/discovery/supervised-run.js +328 -0
  46. package/dist/discovery/supervised-run.js.map +1 -0
  47. package/dist/discovery/trusted-config.d.ts +103 -0
  48. package/dist/discovery/trusted-config.d.ts.map +1 -0
  49. package/dist/discovery/trusted-config.js +117 -0
  50. package/dist/discovery/trusted-config.js.map +1 -0
  51. package/dist/fixture/evidence.d.ts +191 -0
  52. package/dist/fixture/evidence.d.ts.map +1 -0
  53. package/dist/fixture/evidence.js +366 -0
  54. package/dist/fixture/evidence.js.map +1 -0
  55. package/dist/fixture/fixture.d.ts +37 -0
  56. package/dist/fixture/fixture.d.ts.map +1 -0
  57. package/dist/fixture/fixture.js +38 -0
  58. package/dist/fixture/fixture.js.map +1 -0
  59. package/dist/fixture/witness-client.d.ts +164 -0
  60. package/dist/fixture/witness-client.d.ts.map +1 -0
  61. package/dist/fixture/witness-client.js +253 -0
  62. package/dist/fixture/witness-client.js.map +1 -0
  63. package/dist/index.d.ts +64 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +55 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/json.d.ts +16 -0
  68. package/dist/json.d.ts.map +1 -0
  69. package/dist/json.js +21 -0
  70. package/dist/json.js.map +1 -0
  71. package/dist/reporter/ledger.d.ts +105 -0
  72. package/dist/reporter/ledger.d.ts.map +1 -0
  73. package/dist/reporter/ledger.js +197 -0
  74. package/dist/reporter/ledger.js.map +1 -0
  75. package/dist/reporter/reporter.cjs +105 -0
  76. package/dist/reporter/reporter.cjs.map +1 -0
  77. package/dist/reporter/reporter.d.cts +35 -0
  78. package/dist/reporter/reporter.d.cts.map +1 -0
  79. package/dist/reporter/reporter.d.ts +167 -0
  80. package/dist/reporter/reporter.d.ts.map +1 -0
  81. package/dist/reporter/reporter.js +673 -0
  82. package/dist/reporter/reporter.js.map +1 -0
  83. package/dist/setup.d.ts +49 -0
  84. package/dist/setup.d.ts.map +1 -0
  85. package/dist/setup.js +167 -0
  86. package/dist/setup.js.map +1 -0
  87. package/dist/supervisor/client.d.ts +73 -0
  88. package/dist/supervisor/client.d.ts.map +1 -0
  89. package/dist/supervisor/client.js +164 -0
  90. package/dist/supervisor/client.js.map +1 -0
  91. package/dist/supervisor/drain.d.ts +45 -0
  92. package/dist/supervisor/drain.d.ts.map +1 -0
  93. package/dist/supervisor/drain.js +235 -0
  94. package/dist/supervisor/drain.js.map +1 -0
  95. package/dist/supervisor/index.d.ts +16 -0
  96. package/dist/supervisor/index.d.ts.map +1 -0
  97. package/dist/supervisor/index.js +13 -0
  98. package/dist/supervisor/index.js.map +1 -0
  99. package/dist/supervisor/spool.d.ts +137 -0
  100. package/dist/supervisor/spool.d.ts.map +1 -0
  101. package/dist/supervisor/spool.js +263 -0
  102. package/dist/supervisor/spool.js.map +1 -0
  103. package/dist/surface.d.ts +134 -0
  104. package/dist/surface.d.ts.map +1 -0
  105. package/dist/surface.js +139 -0
  106. package/dist/surface.js.map +1 -0
  107. package/dist/witness/adapter-registry.d.ts +38 -0
  108. package/dist/witness/adapter-registry.d.ts.map +1 -0
  109. package/dist/witness/adapter-registry.js +158 -0
  110. package/dist/witness/adapter-registry.js.map +1 -0
  111. package/dist/witness/bin.d.ts +21 -0
  112. package/dist/witness/bin.d.ts.map +1 -0
  113. package/dist/witness/bin.js +172 -0
  114. package/dist/witness/bin.js.map +1 -0
  115. package/dist/witness/browser.d.ts +173 -0
  116. package/dist/witness/browser.d.ts.map +1 -0
  117. package/dist/witness/browser.js +580 -0
  118. package/dist/witness/browser.js.map +1 -0
  119. package/dist/witness/classifications.d.ts +42 -0
  120. package/dist/witness/classifications.d.ts.map +1 -0
  121. package/dist/witness/classifications.js +87 -0
  122. package/dist/witness/classifications.js.map +1 -0
  123. package/dist/witness/env-attestation.d.ts +98 -0
  124. package/dist/witness/env-attestation.d.ts.map +1 -0
  125. package/dist/witness/env-attestation.js +202 -0
  126. package/dist/witness/env-attestation.js.map +1 -0
  127. package/dist/witness/loopback-pins.d.ts +79 -0
  128. package/dist/witness/loopback-pins.d.ts.map +1 -0
  129. package/dist/witness/loopback-pins.js +244 -0
  130. package/dist/witness/loopback-pins.js.map +1 -0
  131. package/dist/witness/server.d.ts +34 -0
  132. package/dist/witness/server.d.ts.map +1 -0
  133. package/dist/witness/server.js +2539 -0
  134. package/dist/witness/server.js.map +1 -0
  135. package/dist/witness/types.d.ts +643 -0
  136. package/dist/witness/types.d.ts.map +1 -0
  137. package/dist/witness/types.js +2 -0
  138. package/dist/witness/types.js.map +1 -0
  139. package/package.json +64 -0
  140. package/python/gateforge_persistence_intents.py +100 -0
@@ -0,0 +1,544 @@
1
+ /**
2
+ * Catalog orchestration (plan 2026-09-13 phase 2 item 1): builds the
3
+ * validated {@link TestCatalog} from the static scan, the native
4
+ * playwright reconciliation, kind/category inference, and the configured
5
+ * pytest diagnostic suites.
6
+ *
7
+ * Invariants enforced here (fail closed as DATA, never silence):
8
+ * - every statically detected call, unresolved gap, and parse error is a
9
+ * catalog row — a failed scan never reads as "no tests";
10
+ * - reconciliation is STATIC-FIRST with a native fallback: a case the
11
+ * static scan derived (and the native list confirmed) is `matched`
12
+ * with origin `'static'`; a case ONLY the native runner enumerated is
13
+ * still a DISCOVERED row (origin `'native-list'`, reconciliation
14
+ * `list-only`) — the runner proved it exists and will execute it —
15
+ * while a case ONLY the static scan found stays `static-only` and
16
+ * unresolved (the runner cannot execute what it never enumerated);
17
+ * - `inventoryComplete` is true only when every enabled enumeration
18
+ * step ran clean (parse errors, budget cuts, unresolved static-only
19
+ * rows, native reporter errors, and failed pytest collection all make
20
+ * it false);
21
+ * - the final document passes the strict core schema (duplicate logical
22
+ * keys are typed errors listing both sources).
23
+ *
24
+ * Output ordering is deterministic: entries sort by (file, titlePath,
25
+ * project); unresolved/parse errors sort by location.
26
+ */
27
+ import { join } from 'node:path';
28
+ import { canonicalJson, deriveLogicalKey, TestCatalogSchema, } from '@gate-forge/core';
29
+ import { inferTestKind } from './inference.js';
30
+ import { collectPytestSuite, repoRelative, } from './pytest-adapter.js';
31
+ import { fileDigest, listNativePlaywrightTests, reconciliationKey, } from './reconcile.js';
32
+ import { scanTestFiles, UNRESOLVED_TITLE_PLACEHOLDER, } from './static-discovery.js';
33
+ /**
34
+ * Runs discovery + reconciliation and returns the validated catalog.
35
+ *
36
+ * Pytest suites (plan §3.5) are registered-but-diagnostic-only by
37
+ * default: they appear in `runnerSummaries` with status `registered`
38
+ * (their configured identities, no execution, no collection). With
39
+ * `collectPytest: true` (CLI `--pytest`), the adapter runs the
40
+ * configured argv with `--collect-only -q` and adds one entry per
41
+ * collected node id; diagnostic EXECUTION remains Phase 4 work.
42
+ *
43
+ * Args:
44
+ * options: cwd, config, optional pytest collection + timeouts.
45
+ *
46
+ * Returns:
47
+ * Promise<DiscoverResult>: validated catalog + canonical JSON.
48
+ *
49
+ * Throws:
50
+ * TestDiscoveryError: when an enabled native enumeration could not
51
+ * run at all (spawn failure, timeout, unparseable output) — the CLI
52
+ * maps this to exit 2. Scanner-detectable problems are rows, not
53
+ * throws.
54
+ */
55
+ export async function discoverTestCatalog(options) {
56
+ const { cwd, config } = options;
57
+ const scan = scanTestFiles({
58
+ cwd,
59
+ include: config.project.paths.include,
60
+ exclude: config.project.paths.exclude,
61
+ });
62
+ const native = await listNativePlaywrightTests({
63
+ cwd,
64
+ timeoutMs: options.playwrightTimeoutMs,
65
+ });
66
+ const builder = new CatalogBuilder(cwd, scan, native);
67
+ const runnerSummaries = [builder.playwrightSummary()];
68
+ const entries = builder.buildEntries();
69
+ // Registered pytest suites: diagnostic-only identities (§3.5).
70
+ const suites = config.diagnostics?.suites ?? [];
71
+ for (const suite of suites) {
72
+ if (options.collectPytest === true) {
73
+ const collection = await collectPytestSuite(suite, join(cwd, suite.cwd));
74
+ runnerSummaries.push({
75
+ runner: 'pytest',
76
+ name: suite.name,
77
+ status: collection.status === 'discovered' ? 'discovered' : 'unavailable',
78
+ detail: collection.detail,
79
+ });
80
+ if (collection.status !== 'discovered')
81
+ continue;
82
+ for (const testCase of collection.cases) {
83
+ // Collected files are suite-cwd-relative; the catalog rows and
84
+ // digests use repo-relative posix paths.
85
+ const repoFile = repoRelative(cwd, join(cwd, suite.cwd, testCase.file));
86
+ const row = builder.pytestEntry(suite.name, testCase.nodeId, repoFile, testCase.titlePath);
87
+ if (row !== null)
88
+ entries.push(row);
89
+ }
90
+ }
91
+ else {
92
+ runnerSummaries.push({
93
+ runner: 'pytest',
94
+ name: suite.name,
95
+ status: 'registered',
96
+ detail: 'registered for diagnostics; collection not requested (run tests discover --pytest); execution is Phase 4',
97
+ });
98
+ }
99
+ }
100
+ const catalog = builder.finalize(entries, runnerSummaries);
101
+ return { catalog, json: canonicalJson(catalog) };
102
+ }
103
+ /** Assembles catalog rows from the scan + native enumeration. */
104
+ class CatalogBuilder {
105
+ cwd;
106
+ scan;
107
+ native;
108
+ /** Static entries keyed by file#titlePath for matching. */
109
+ staticByKey = new Map();
110
+ constructor(cwd, scan, native) {
111
+ this.cwd = cwd;
112
+ this.scan = scan;
113
+ this.native = native;
114
+ for (const entry of scan.entries) {
115
+ this.staticByKey.set(reconciliationKey(entry.file, entry.titlePath), entry);
116
+ }
117
+ }
118
+ /** The playwright runner summary line for this run. */
119
+ playwrightSummary() {
120
+ if (this.native.status === 'unavailable') {
121
+ return { runner: 'playwright', name: 'playwright', status: 'unavailable', detail: this.native.detail };
122
+ }
123
+ // Native reporter errors (e.g. a spec that fails to load) are DATA:
124
+ // surfaced on the summary and reflected in inventoryComplete.
125
+ const errors = this.native.errors.length > 0 ? `; native errors: ${this.native.errors.join(' | ').slice(0, 500)}` : '';
126
+ return { runner: 'playwright', name: 'playwright', status: 'discovered', detail: `${this.native.detail}${errors}` };
127
+ }
128
+ /** Builds every playwright row: matched, list-only, static-only, gaps. */
129
+ buildEntries() {
130
+ const rows = [];
131
+ const matchedStaticKeys = new Set();
132
+ // Parameterized static templates (`for (const x of ITEMS)
133
+ // test(\`...${x}...\`)`): the template title is not itself runnable —
134
+ // its concrete instances are. A template whose enumerated instances
135
+ // all share its file + describe ancestry merges its static facts
136
+ // into each instance row (origin 'static' + a template-expansion
137
+ // weak signal) instead of leaving a blocking static-only gap beside
138
+ // fact-less list-only rows (consumer migration, E22). Templates with
139
+ // ZERO enumerated instances stay static-only and blocking (a
140
+ // parameterized case no configuration executes — the owner wires it
141
+ // into a project or removes it). An instance matching two templates,
142
+ // or exactly matching a static entry, merges into no template
143
+ // (ambiguity and exact identity win). Only the LAST titlePath segment
144
+ // may carry `${}` slots; a template slot in a describe segment stays
145
+ // static-only (documented limit).
146
+ const templateConsumed = new Set();
147
+ const instanceTemplate = new Map();
148
+ if (this.native.status === 'discovered') {
149
+ const enumeratedKeys = new Set(this.native.instances.map((instance) => reconciliationKey(instance.file, instance.titlePath)));
150
+ const templates = [...this.staticByKey.values()].filter((entry) => !enumeratedKeys.has(reconciliationKey(entry.file, entry.titlePath)) &&
151
+ templateTitlePattern(entry.title) !== null);
152
+ const claimsByInstance = new Map();
153
+ for (const template of templates) {
154
+ const pattern = templateTitlePattern(template.title);
155
+ if (pattern === null)
156
+ continue;
157
+ const templateKey = reconciliationKey(template.file, template.titlePath);
158
+ const describes = template.titlePath.slice(0, -1);
159
+ for (const instance of this.native.instances) {
160
+ const instanceKey = reconciliationKey(instance.file, instance.titlePath);
161
+ // Exact static identity wins over template expansion.
162
+ if (this.staticByKey.has(instanceKey))
163
+ continue;
164
+ if (instance.file !== template.file)
165
+ continue;
166
+ if (instance.titlePath.length !== template.titlePath.length)
167
+ continue;
168
+ if (!describes.every((segment, index) => segment === instance.titlePath[index]))
169
+ continue;
170
+ if (!pattern.test(instance.titlePath[instance.titlePath.length - 1] ?? ''))
171
+ continue;
172
+ const claims = claimsByInstance.get(instanceKey) ?? [];
173
+ claims.push(templateKey);
174
+ claimsByInstance.set(instanceKey, claims);
175
+ }
176
+ }
177
+ // An instance claimed by two templates merges into neither.
178
+ for (const [instanceKey, templateKeys] of claimsByInstance) {
179
+ if (templateKeys.length !== 1 || templateKeys[0] === undefined)
180
+ continue;
181
+ const template = this.staticByKey.get(templateKeys[0]);
182
+ if (template === undefined)
183
+ continue;
184
+ templateConsumed.add(templateKeys[0]);
185
+ instanceTemplate.set(instanceKey, template);
186
+ }
187
+ }
188
+ // Static unresolved gaps, keyed by reconciliation identity, with
189
+ // duplicates merged (§5.2: line numbers are never identity — two
190
+ // unprovable calls sharing a title path collapse into one gap).
191
+ const gapsByKey = new Map();
192
+ const gapExtras = new Map();
193
+ for (const gap of this.scan.unresolved) {
194
+ const key = reconciliationKey(gap.file, gap.titlePath);
195
+ const existing = gapsByKey.get(key);
196
+ if (existing === undefined) {
197
+ gapsByKey.set(key, gap);
198
+ continue;
199
+ }
200
+ const extras = gapExtras.get(key) ?? [];
201
+ extras.push(`${gap.location.file}:${String(gap.location.line)}`);
202
+ gapExtras.set(key, extras);
203
+ }
204
+ // A gap the native runner ALSO enumerated is RESOLVED BY THE RUNNER:
205
+ // the --list run loaded the file and will execute that exact case, so
206
+ // the discovered row stands and the gap merges into it as a weak
207
+ // signal — a second row over the same identity would duplicate the
208
+ // logical key (the strict schema correctly rejects that).
209
+ const enumeratedKeys = new Set();
210
+ if (this.native.status === 'discovered') {
211
+ for (const instance of this.native.instances) {
212
+ const key = reconciliationKey(instance.file, instance.titlePath);
213
+ enumeratedKeys.add(key);
214
+ const template = instanceTemplate.get(key);
215
+ const staticEntry = this.staticByKey.get(key) ?? template;
216
+ if (staticEntry !== undefined)
217
+ matchedStaticKeys.add(key);
218
+ const gap = gapsByKey.get(key);
219
+ rows.push(this.playwrightRow(instance, staticEntry, gap, template));
220
+ }
221
+ }
222
+ for (const [key, staticEntry] of this.staticByKey) {
223
+ if (matchedStaticKeys.has(key) || templateConsumed.has(key))
224
+ continue;
225
+ rows.push(this.staticOnlyRow(staticEntry));
226
+ }
227
+ // Remaining unresolved static gaps become visible rows (never
228
+ // omitted): unprovable shapes the runner did NOT enumerate (they
229
+ // cannot execute) stay typed unresolved entries and block the
230
+ // inventory honestly.
231
+ for (const [key, gap] of [...gapsByKey.entries()].sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))) {
232
+ if (enumeratedKeys.has(key))
233
+ continue;
234
+ const row = this.unresolvedRow(gap);
235
+ const extras = gapExtras.get(key);
236
+ if (extras !== undefined && row.unresolvedReason !== undefined) {
237
+ row.unresolvedReason = {
238
+ ...row.unresolvedReason,
239
+ detail: `${row.unresolvedReason.detail} (further call sites: ${extras.join(', ')})`,
240
+ };
241
+ }
242
+ rows.push(row);
243
+ }
244
+ return rows;
245
+ }
246
+ /** One matched/native-list playwright instance row. */
247
+ playwrightRow(instance, staticEntry, staticGap, template) {
248
+ const digest = fileDigest(this.cwd, instance.file);
249
+ // The native list reports '' when the run has no projects; the
250
+ // catalog identity uses null for that (same as static-only rows) —
251
+ // an empty-string project is a schema violation, never an identity.
252
+ const project = instance.project === '' ? null : instance.project;
253
+ const matched = staticEntry !== undefined;
254
+ // Static-first: when the static scan derived the case, its facts feed
255
+ // kind inference. When it could not (or the file is outside the
256
+ // configured globs), the native runner's OWN enumeration is the
257
+ // identity source (resolution origin 'native-list'): the row is
258
+ // DISCOVERED — the runner proved the case exists and will execute it
259
+ // in the supervised run — but honestly weaker-classified: no static
260
+ // call-site facts were read, so no strong kind rule may fire.
261
+ const inference = staticEntry === undefined
262
+ ? nativeOnlyInference(instance)
263
+ : inferTestKind({ file: staticEntry.file, title: staticEntry.title, titlePath: staticEntry.titlePath, facts: staticEntry.facts });
264
+ const suppression = matched
265
+ ? suppressionOf(staticEntry, instance.annotations, instance.location)
266
+ : { mocks: nativeSuppression(instance.annotations, instance.location), flags: [] };
267
+ const weakSignals = [...inference.weakSignals];
268
+ if (template !== undefined) {
269
+ // The identity is a concrete enumerated instance; the static facts
270
+ // came from its parameterized template (same loop body, same
271
+ // fixtures — sound per-instance). Recorded, never silent.
272
+ weakSignals.push({
273
+ ruleId: 'template-expansion',
274
+ evidence: `static parameterized title '${template.title}' expanded over the enumerated instance (same file, same describe ancestry)`,
275
+ location: template.location,
276
+ });
277
+ }
278
+ if (staticGap !== undefined) {
279
+ // The static scan could not PROVE this call a test (wrapper/
280
+ // dynamic title), yet the runner enumerated it: the runner wins
281
+ // for identity, and the unprovability stays visible as a weak
282
+ // signal (never silently dropped, never blocking twice).
283
+ weakSignals.push({
284
+ ruleId: staticGap.code,
285
+ evidence: `${staticGap.detail} (resolved by native enumeration)`,
286
+ location: staticGap.location,
287
+ });
288
+ }
289
+ return {
290
+ logicalKey: deriveLogicalKey({ runner: 'playwright', project, file: instance.file, titlePath: instance.titlePath }),
291
+ runner: 'playwright',
292
+ project,
293
+ file: instance.file,
294
+ titlePath: [...instance.titlePath],
295
+ title: instance.title,
296
+ sourceLocation: instance.location,
297
+ parameterIdentity: instance.frameworkId,
298
+ sourceDigest: digest ?? EMPTY_SHA256,
299
+ discoveryStatus: 'discovered',
300
+ reconciliation: matched ? 'matched' : 'list-only',
301
+ resolutionOrigin: matched ? 'static' : 'native-list',
302
+ inferredKind: inference.inferredKind,
303
+ kindSignals: inference.kindSignals,
304
+ weakSignals,
305
+ rulesFired: inference.rulesFired,
306
+ categorySignals: inference.categorySignals,
307
+ suppressionSignals: suppression.mocks,
308
+ };
309
+ }
310
+ /** One static-only row: static scan found it, native list did not. */
311
+ staticOnlyRow(staticEntry) {
312
+ const inference = inferTestKind({
313
+ file: staticEntry.file,
314
+ title: staticEntry.title,
315
+ titlePath: staticEntry.titlePath,
316
+ facts: staticEntry.facts,
317
+ });
318
+ const digest = fileDigest(this.cwd, staticEntry.file);
319
+ const suppression = suppressionOf(staticEntry, [], staticEntry.location);
320
+ return {
321
+ logicalKey: deriveLogicalKey({ runner: 'playwright', project: null, file: staticEntry.file, titlePath: staticEntry.titlePath }),
322
+ runner: 'playwright',
323
+ project: null,
324
+ file: staticEntry.file,
325
+ titlePath: [...staticEntry.titlePath],
326
+ title: staticEntry.title,
327
+ sourceLocation: staticEntry.location,
328
+ parameterIdentity: staticEntry.parameterIdentity,
329
+ sourceDigest: digest ?? EMPTY_SHA256,
330
+ discoveryStatus: 'unresolved',
331
+ reconciliation: this.native.status === 'unavailable' ? 'unavailable' : 'static-only',
332
+ resolutionOrigin: 'static',
333
+ inferredKind: inference.inferredKind,
334
+ kindSignals: inference.kindSignals,
335
+ weakSignals: inference.weakSignals,
336
+ rulesFired: inference.rulesFired,
337
+ categorySignals: inference.categorySignals,
338
+ suppressionSignals: [...suppression.mocks, ...suppression.flags],
339
+ unresolvedReason: {
340
+ code: this.native.status === 'unavailable'
341
+ ? 'reconciliation-unavailable'
342
+ : 'reconciliation-static-only',
343
+ detail: this.native.status === 'unavailable'
344
+ ? 'no native playwright enumeration ran (no playwright config) — the case is statically visible only'
345
+ : 'the static scan found this case but the runner did not enumerate it (check configured globs, dynamic titles, or filters)',
346
+ },
347
+ };
348
+ }
349
+ /** One unresolved-gap row (unresolvable wrapper, budget, dynamic title). */
350
+ unresolvedRow(gap) {
351
+ return {
352
+ logicalKey: deriveLogicalKey({
353
+ runner: 'playwright',
354
+ project: null,
355
+ file: gap.file,
356
+ titlePath: gap.titlePath.length > 0 ? gap.titlePath : [UNRESOLVED_TITLE_PLACEHOLDER],
357
+ }),
358
+ runner: 'playwright',
359
+ project: null,
360
+ file: gap.file,
361
+ titlePath: gap.titlePath.length > 0 ? gap.titlePath : [UNRESOLVED_TITLE_PLACEHOLDER],
362
+ title: gap.titlePath[gap.titlePath.length - 1] ?? UNRESOLVED_TITLE_PLACEHOLDER,
363
+ sourceLocation: gap.location,
364
+ parameterIdentity: null,
365
+ sourceDigest: fileDigest(this.cwd, gap.file) ?? EMPTY_SHA256,
366
+ discoveryStatus: 'unresolved',
367
+ reconciliation: this.native.status === 'unavailable' ? 'unavailable' : 'static-only',
368
+ resolutionOrigin: 'static',
369
+ inferredKind: 'unknown',
370
+ kindSignals: [],
371
+ weakSignals: [],
372
+ rulesFired: [],
373
+ categorySignals: [],
374
+ suppressionSignals: [],
375
+ unresolvedReason: { code: gap.code, detail: gap.detail },
376
+ };
377
+ }
378
+ /** One pytest collected-case row (diagnostic identity only, §3.5). */
379
+ pytestEntry(suiteName, nodeId, file, titlePath) {
380
+ // Suite-cwd-relative file → repo-relative for the digest lookup.
381
+ const repoFile = file;
382
+ const digest = fileDigest(this.cwd, repoFile);
383
+ if (digest === null)
384
+ return null; // unreadable file: no fabricated row
385
+ return {
386
+ logicalKey: deriveLogicalKey({ runner: 'pytest', project: suiteName, file: repoFile, titlePath }),
387
+ runner: 'pytest',
388
+ project: suiteName,
389
+ file: repoFile,
390
+ titlePath,
391
+ title: titlePath[titlePath.length - 1] ?? nodeId,
392
+ sourceLocation: { file: repoFile, line: 1, col: 0 },
393
+ parameterIdentity: nodeId,
394
+ sourceDigest: digest,
395
+ discoveryStatus: 'discovered',
396
+ reconciliation: 'unavailable',
397
+ inferredKind: 'unknown',
398
+ kindSignals: [],
399
+ weakSignals: [],
400
+ rulesFired: [],
401
+ categorySignals: [],
402
+ suppressionSignals: nodeId.includes('[xfail]') || nodeId.includes('[xpass]') ? [{ kind: 'fixme', detail: 'pytest xfail/xpass parameter', location: { file: repoFile, line: 1, col: 0 } }] : [],
403
+ };
404
+ }
405
+ /** Validates + orders everything into the final catalog. */
406
+ finalize(entries, runnerSummaries) {
407
+ const sorted = [...entries].sort((a, b) => compareRows(a, b));
408
+ const unresolved = sorted
409
+ .filter((row) => row.discoveryStatus === 'unresolved' && row.unresolvedReason !== undefined)
410
+ .map((row) => ({
411
+ logicalKey: row.logicalKey,
412
+ code: row.unresolvedReason?.code ?? 'unknown',
413
+ detail: row.unresolvedReason?.detail ?? '',
414
+ location: row.sourceLocation,
415
+ }))
416
+ .sort((a, b) => compareLocations(a.location, b.location) || (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));
417
+ const parseErrors = this.scan.parseErrors
418
+ .map((error) => ({ file: error.file, message: error.message, location: error.location }))
419
+ .sort((a, b) => compareLocations(a.location, b.location));
420
+ // Completeness is about ENUMERATION, never classification
421
+ // uncertainty (plan phase 2 item 7): unknown KINDS stay complete;
422
+ // failed parses, budget cuts, native reporter errors, unresolved
423
+ // static-only rows (cases the runner never enumerated — they cannot
424
+ // execute), and failed configured diagnostic suites do not. Rows
425
+ // discovered only through the native list (origin 'native-list')
426
+ // ARE complete enumeration: the runner itself proved the case.
427
+ // A repo with no playwright rows at all is vacuously complete even
428
+ // when native reconciliation reported unavailable (non-playwright
429
+ // repos).
430
+ const diagnosticUnavailable = runnerSummaries.some((summary) => summary.runner !== 'playwright' && summary.status === 'unavailable');
431
+ const complete = parseErrors.length === 0 &&
432
+ !this.scan.budgetExceeded &&
433
+ this.native.errors.length === 0 &&
434
+ !sorted.some((row) => row.runner === 'playwright' && row.discoveryStatus === 'unresolved') &&
435
+ !diagnosticUnavailable;
436
+ // Validate through the strict schema: duplicate logical keys and
437
+ // inconsistent roll-ups fail closed here, at construction time.
438
+ return TestCatalogSchema.parse({
439
+ schemaVersion: 1,
440
+ entries: sorted,
441
+ unresolved,
442
+ parseErrors,
443
+ inventoryComplete: complete,
444
+ runnerSummaries: [...runnerSummaries].sort((a, b) => (a.runner < b.runner ? -1 : a.runner > b.runner ? 1 : 0) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)),
445
+ });
446
+ }
447
+ }
448
+ /** sha256 of empty bytes — placeholder ONLY when a digest is unreadable. */
449
+ const EMPTY_SHA256 = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
450
+ /**
451
+ * Builds the instance-title matcher for a parameterized static title, or
452
+ * null when the title carries no `${}` template slots. Literal parts
453
+ * match exactly (regex-escaped); each slot matches any (possibly empty)
454
+ * text — the same expansion the runner performs over the loop values.
455
+ *
456
+ * Args:
457
+ * title: the static title (may contain `${}` slots).
458
+ *
459
+ * Returns:
460
+ * Anchored RegExp, or null for non-parameterized titles.
461
+ */
462
+ export function templateTitlePattern(title) {
463
+ if (!title.includes('${}'))
464
+ return null;
465
+ const escaped = title.split('${}').map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
466
+ return new RegExp(`^${escaped.join('.*')}$`);
467
+ }
468
+ /** Stable key for location dedupe. */
469
+ function locationKey(location) {
470
+ return `${location.file}:${String(location.line)}:${String(location.col)}`;
471
+ }
472
+ /** Row order: file, then titlePath, then project (deterministic). */
473
+ function compareRows(a, b) {
474
+ const projectA = a.project ?? '';
475
+ const projectB = b.project ?? '';
476
+ return ((a.file < b.file ? -1 : a.file > b.file ? 1 : 0) ||
477
+ (a.titlePath.join('>') < b.titlePath.join('>') ? -1 : a.titlePath.join('>') > b.titlePath.join('>') ? 1 : 0) ||
478
+ (projectA < projectB ? -1 : projectA > projectB ? 1 : 0));
479
+ }
480
+ /** Location order: file, line, col. */
481
+ function compareLocations(a, b) {
482
+ return ((a.file < b.file ? -1 : a.file > b.file ? 1 : 0) ||
483
+ a.line - b.line ||
484
+ a.col - b.col);
485
+ }
486
+ /**
487
+ * Inference for rows whose ONLY enumeration source is the native runner
488
+ * list (resolution origin `'native-list'`): no static facts were read,
489
+ * so NO strong kind rule may fire (running the rules over empty facts
490
+ * would fabricate a `unit` proposal from absence). The kind stays
491
+ * `unknown` and the native-only identity is recorded as a weak signal.
492
+ */
493
+ function nativeOnlyInference(instance) {
494
+ const weak = {
495
+ ruleId: 'native-list-only',
496
+ evidence: 'identity resolved by the native runner enumeration alone; the static scan did not derive this case ' +
497
+ '(outside configured globs or not statically followable) — no call-site facts were read',
498
+ location: instance.location,
499
+ };
500
+ return { inferredKind: 'unknown', kindSignals: [], weakSignals: [weak], rulesFired: [], categorySignals: [], mockSignals: [] };
501
+ }
502
+ /** Splits static signals into mock vs skip/only/fixme rows. */
503
+ function suppressionOf(staticEntry, annotations, annotationLocation) {
504
+ const mocks = mockSignalsOf(staticEntry);
505
+ const flags = staticEntry.signals.map((signal) => ({
506
+ kind: signal.kind,
507
+ detail: signal.detail,
508
+ location: signal.location,
509
+ }));
510
+ for (const annotation of annotations) {
511
+ if (annotation === 'skip' || annotation === 'fixme') {
512
+ flags.push({
513
+ kind: annotation,
514
+ detail: `native ${annotation} annotation`,
515
+ location: annotationLocation,
516
+ });
517
+ }
518
+ }
519
+ return { mocks, flags };
520
+ }
521
+ /** Suppression rows derived from native annotations alone. */
522
+ function nativeSuppression(annotations, location) {
523
+ return annotations
524
+ .filter((annotation) => annotation === 'skip' || annotation === 'fixme')
525
+ .map((annotation) => ({
526
+ kind: annotation,
527
+ detail: `native ${annotation} annotation`,
528
+ location,
529
+ }));
530
+ }
531
+ /** Mock suppression signals from a static entry's facts. */
532
+ function mockSignalsOf(staticEntry) {
533
+ const signals = [];
534
+ if (staticEntry.facts.pageRoute !== null) {
535
+ signals.push({ kind: 'mock', detail: 'page.route interception inside the test body', location: staticEntry.facts.pageRoute });
536
+ }
537
+ if (staticEntry.facts.fileMockImport !== null) {
538
+ signals.push({ kind: 'mock', detail: 'vi.mock/jest.mock module mock in the test file', location: staticEntry.facts.fileMockImport });
539
+ }
540
+ return signals;
541
+ }
542
+ // Re-exports kept minimal: the CLI needs repoRelative nowhere else today.
543
+ export { repoRelative };
544
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/discovery/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Test discovery surface of the Playwright pack (plan 2026-09-13
3
+ * phase 2): bounded static scanning, native reconciliation, kind
4
+ * inference, the runner adapters, and the pytest diagnostic adapter.
5
+ */
6
+ export * from './static-discovery.js';
7
+ export * from './inference.js';
8
+ export * from './reconcile.js';
9
+ export * from './pytest-adapter.js';
10
+ export * from './discover.js';
11
+ export * from './adapters.js';
12
+ export * from './supervised-run.js';
13
+ export * from './trusted-config.js';
14
+ export * from './runner-env.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Test discovery surface of the Playwright pack (plan 2026-09-13
3
+ * phase 2): bounded static scanning, native reconciliation, kind
4
+ * inference, the runner adapters, and the pytest diagnostic adapter.
5
+ */
6
+ export * from './static-discovery.js';
7
+ export * from './inference.js';
8
+ export * from './reconcile.js';
9
+ export * from './pytest-adapter.js';
10
+ export * from './discover.js';
11
+ export * from './adapters.js';
12
+ export * from './supervised-run.js';
13
+ export * from './trusted-config.js';
14
+ export * from './runner-env.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}