@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,580 @@
1
+ /**
2
+ * The engine-owned browser (plan Phase 1 item 4): Chromium contexts the
3
+ * WITNESS process creates and drives itself — one isolated context per
4
+ * supervisor-opened test session, closed when the session seals.
5
+ *
6
+ * Test code NEVER touches these pages: the worker holds no handle, no
7
+ * URL, and no capability over them. The engine executes the constrained
8
+ * surface operations (create/read/update/archive) with the
9
+ * consumer-declared locators, and observes each step itself:
10
+ * - the rendered control it clicked and the values it typed;
11
+ * - the actual application request the action caused (captured from the
12
+ * engine page's own network, app-origin only);
13
+ * - the resulting navigation and the rendered row/form it read back.
14
+ *
15
+ * Forgery resistance (why this channel is proof):
16
+ * - fabricated DOM (`page.evaluate` in the worker page) is irrelevant:
17
+ * the engine reads its OWN page;
18
+ * - mocked responses (`page.route` in the worker) are irrelevant: the
19
+ * worker cannot route the engine's traffic;
20
+ * - direct API/Node mutations bypass the engine page entirely: no
21
+ * engine action runs, so no engine-observed action/visible records
22
+ * exist for them — invented suite-submitted records never satisfy;
23
+ * - HTTP-200-while-error: the engine asserts the rendered status
24
+ * itself (created/archived values) AND captures the app response
25
+ * status — a displayed error fails the action fail-closed.
26
+ *
27
+ * Surface selectors are LOCATORS, never proof: a lying descriptor only
28
+ * makes the engine fail to find elements (fail closed).
29
+ */
30
+ import { chromium } from 'playwright';
31
+ import { declaredSurfaceFields, renderSurfaceTemplate, } from '../surface.js';
32
+ /** Fail-closed engine browser error (surfaced as 409/503 downstream). */
33
+ export class EngineBrowserError extends Error {
34
+ constructor(message) {
35
+ super(message);
36
+ this.name = 'EngineBrowserError';
37
+ }
38
+ }
39
+ /** Bounded wait for a rendered selector (fail closed, never indefinite). */
40
+ const ENGINE_STEP_TIMEOUT_MS = 15_000;
41
+ /**
42
+ * Owns the engine Chromium instance and its per-session contexts.
43
+ *
44
+ * Args:
45
+ * launcher: browser launcher (default: the pinned Chromium). Tests
46
+ * inject a failing launcher to prove the fail-closed path; the
47
+ * driving and observation below stay engine code regardless of
48
+ * which executable launches.
49
+ */
50
+ export class EngineBrowserManager {
51
+ launcher;
52
+ browser = null;
53
+ launching = null;
54
+ sessions = new Map();
55
+ /**
56
+ * Pinned `--host-resolver-rules` value binding every attested hostname
57
+ * to its startup-approved loopback IPs. Set once at witness startup
58
+ * (before any launch); the browser is then incapable of resolving
59
+ * those names anywhere but loopback, regardless of later DNS changes.
60
+ */
61
+ dnsPinRules = null;
62
+ constructor(launcher = chromium) {
63
+ this.launcher = launcher;
64
+ }
65
+ /**
66
+ * Installs the DNS pin rules for the next (first) launch.
67
+ *
68
+ * Args:
69
+ * rules: the `--host-resolver-rules` value, or null when nothing is
70
+ * pinned (plain launch, previous behavior).
71
+ *
72
+ * Throws:
73
+ * EngineBrowserError: when the browser already launched — pins must
74
+ * precede every navigation (fail closed, never silently unbound).
75
+ */
76
+ setDnsPinRules(rules) {
77
+ if (this.browser !== null || this.launching !== null) {
78
+ throw new EngineBrowserError('DNS pin rules arrive after browser launch: pins must precede every navigation');
79
+ }
80
+ this.dnsPinRules = rules;
81
+ }
82
+ /**
83
+ * Returns the engine page for one session, creating the isolated
84
+ * context on first use.
85
+ *
86
+ * Args:
87
+ * sessionId: the supervisor-opened session the context belongs to.
88
+ *
89
+ * Returns:
90
+ * Promise<Page>: the session's engine-owned page.
91
+ *
92
+ * Throws:
93
+ * EngineBrowserError: when Chromium cannot launch (fail closed —
94
+ * the capability is honestly unavailable at runtime).
95
+ */
96
+ async pageFor(sessionId) {
97
+ const existing = this.sessions.get(sessionId);
98
+ if (existing !== undefined)
99
+ return existing.page;
100
+ const browser = await this.ensureBrowser();
101
+ const context = await browser.newContext();
102
+ const page = await context.newPage();
103
+ this.sessions.set(sessionId, { context, page });
104
+ return page;
105
+ }
106
+ /**
107
+ * Closes and forgets one session's engine context (session seal).
108
+ * Late engine calls for the session then recreate nothing — callers
109
+ * must refuse sealed sessions before driving (they do: every browser
110
+ * endpoint requires an OPEN session first).
111
+ *
112
+ * Args:
113
+ * sessionId: the sealed session.
114
+ */
115
+ async closeSession(sessionId) {
116
+ const entry = this.sessions.get(sessionId);
117
+ if (entry === undefined)
118
+ return;
119
+ this.sessions.delete(sessionId);
120
+ await entry.context.close().catch(() => undefined);
121
+ }
122
+ /** Closes every engine context and the browser (witness stop). */
123
+ async closeAll() {
124
+ const entries = [...this.sessions.values()];
125
+ this.sessions.clear();
126
+ await Promise.all(entries.map((entry) => entry.context.close().catch(() => undefined)));
127
+ const browser = this.browser;
128
+ this.browser = null;
129
+ this.launching = null;
130
+ if (browser !== null)
131
+ await browser.close().catch(() => undefined);
132
+ }
133
+ /** Lazy Chromium launch (single flight; fail closed with the cause). */
134
+ async ensureBrowser() {
135
+ if (this.browser !== null)
136
+ return this.browser;
137
+ this.launching ??= this.launcher
138
+ .launch({
139
+ headless: true,
140
+ // DNS binding (loopback-pins): attested hostnames resolve ONLY
141
+ // to their startup-approved loopback IPs inside this browser —
142
+ // a mid-run DNS change cannot move its traffic off loopback.
143
+ ...(this.dnsPinRules !== null ? { args: [`--host-resolver-rules=${this.dnsPinRules}`] } : {}),
144
+ })
145
+ .then((browser) => {
146
+ this.browser = browser;
147
+ return browser;
148
+ })
149
+ .catch((error) => {
150
+ this.launching = null;
151
+ throw new EngineBrowserError(`the engine-owned browser cannot launch: ${error.message} — browser ` +
152
+ 'contracts stay blocking until a working Chromium is available to the witness process');
153
+ });
154
+ return this.launching;
155
+ }
156
+ }
157
+ /** Captures app-origin responses on one page for the action window. */
158
+ async function captureExchanges(page, appOrigin, action) {
159
+ const captured = [];
160
+ // Replacement-origin enforcement (fake-frontend fix 2026-09-14): every
161
+ // URL the engine page touches during the window — main-frame
162
+ // navigations AND every hop of every redirect chain — must stay on the
163
+ // trusted origin. A form submit, link, or redirect landing elsewhere
164
+ // fails the action closed instead of observing a foreign frontend.
165
+ const violations = [];
166
+ const checkUrl = (url, where) => {
167
+ let origin;
168
+ try {
169
+ origin = new URL(url).origin;
170
+ }
171
+ catch {
172
+ return; // non-URL (about:blank, data:) — the final page.url check covers landing
173
+ }
174
+ if (origin !== appOrigin)
175
+ violations.push(`${where}: ${url}`);
176
+ };
177
+ // Main-frame navigation guard: page.url() is the main frame's URL,
178
+ // so asserting it on every frame event covers navigations while
179
+ // subresource loads (same URL, no-op) cannot false-positive.
180
+ const mainFrameListener = () => {
181
+ const current = page.url();
182
+ if (current.startsWith('about:') || current.startsWith('data:'))
183
+ return;
184
+ checkUrl(current, 'navigation to foreign origin');
185
+ };
186
+ page.on('framenavigated', mainFrameListener);
187
+ const listener = (response) => {
188
+ // Walk the full redirect chain: the final URL AND every hop must be
189
+ // same-origin — a 303 to a foreign frontend is rejected even though
190
+ // the 303 itself came from the app. Scoped to redirects and document
191
+ // navigations: plain cross-origin SUBRESOURCES (fonts, icons) are
192
+ // not navigations, never become evidence, and must not false-positive.
193
+ const request = response.request();
194
+ const chain = [request.url()];
195
+ let previous = request.redirectedFrom();
196
+ while (previous !== null && typeof previous === 'object' && 'url' in previous) {
197
+ const hop = previous;
198
+ chain.push(hop.url());
199
+ previous = hop.redirectedFrom();
200
+ }
201
+ const involvedRedirect = chain.length > 1;
202
+ let resourceType = '';
203
+ try {
204
+ resourceType = request.resourceType();
205
+ }
206
+ catch {
207
+ resourceType = '';
208
+ }
209
+ if (involvedRedirect || resourceType === 'document') {
210
+ for (const url of chain)
211
+ checkUrl(url, 'redirect chain left the trusted origin');
212
+ }
213
+ let url;
214
+ try {
215
+ url = new URL(response.url());
216
+ }
217
+ catch {
218
+ return;
219
+ }
220
+ if (url.origin !== appOrigin)
221
+ return;
222
+ const chunks = [];
223
+ void response
224
+ .body()
225
+ .then((body) => chunks.push(body))
226
+ .catch(() => undefined)
227
+ .finally(() => {
228
+ captured.push({
229
+ method: response.request().method().toUpperCase(),
230
+ path: canonicalExchangePath(url.pathname),
231
+ status: response.status(),
232
+ body: Buffer.concat(chunks).slice(0, 16384),
233
+ });
234
+ });
235
+ };
236
+ page.on('response', listener);
237
+ // The drive's own error (status mismatch, missing row) is recorded
238
+ // but yields to origin violations: a redirect escape is the stronger
239
+ // security signal and must name itself even when the foreign page
240
+ // ALSO fails a rendered check.
241
+ let driveError = null;
242
+ try {
243
+ await action();
244
+ // Let in-flight response bodies settle (bounded): the mutation's own
245
+ // exchange must be captured before the window closes.
246
+ await page.waitForTimeout(250);
247
+ }
248
+ catch (error) {
249
+ driveError = error;
250
+ }
251
+ finally {
252
+ page.off('response', listener);
253
+ page.off('framenavigated', mainFrameListener);
254
+ }
255
+ // Await the pending body reads (bounded by the step timeout overall).
256
+ await page.waitForTimeout(250);
257
+ // The landing itself must be the trusted origin (backstop for
258
+ // navigations that produced no response event).
259
+ checkUrl(page.url(), 'engine page landed on a foreign origin');
260
+ if (violations.length > 0) {
261
+ throw new EngineBrowserError(`browser action left the trusted application origin '${appOrigin}': ` +
262
+ `${violations.slice(0, 3).join('; ')} — replacement origins and redirects are rejected; ` +
263
+ 'no action record is issued for a foreign frontend');
264
+ }
265
+ if (driveError !== null)
266
+ throw driveError;
267
+ return captured;
268
+ }
269
+ /** Canonicalizes an engine-observed path (lockstep with the witness). */
270
+ function canonicalExchangePath(pathname) {
271
+ let path = pathname.split('?')[0]?.split('#')[0] ?? '/';
272
+ if (!path.startsWith('/'))
273
+ path = `/${path}`;
274
+ if (path.length > 1)
275
+ path = path.replace(/\/+$/, '');
276
+ return path;
277
+ }
278
+ /** Reads one row's cells (trimmed text, DOM order). */
279
+ async function rowCells(row) {
280
+ const cells = row.locator('td');
281
+ const count = await cells.count();
282
+ const out = [];
283
+ for (let i = 0; i < count; i++) {
284
+ out.push(((await cells.nth(i).textContent()) ?? '').trim());
285
+ }
286
+ return out;
287
+ }
288
+ /** Every entity id rendered in the list right now. */
289
+ async function collectIds(page, surface) {
290
+ const rows = page.locator(surface.list.rowSelector);
291
+ const count = await rows.count();
292
+ const ids = new Set();
293
+ for (let i = 0; i < count; i++) {
294
+ const cells = await rowCells(rows.nth(i));
295
+ const id = (cells[surface.list.idCellIndex] ?? '').trim();
296
+ if (id !== '')
297
+ ids.add(id);
298
+ }
299
+ return ids;
300
+ }
301
+ /** The rendered row for one entity (null when the UI exposes none). */
302
+ async function findRow(page, surface, entityId) {
303
+ const rows = page.locator(surface.list.rowSelector);
304
+ const count = await rows.count();
305
+ for (let i = 0; i < count; i++) {
306
+ const row = rows.nth(i);
307
+ const cells = await rowCells(row);
308
+ if ((cells[surface.list.idCellIndex] ?? '').trim() === entityId)
309
+ return row;
310
+ }
311
+ return null;
312
+ }
313
+ /** The rendered field values of one row. */
314
+ async function readRowFields(page, surface, row) {
315
+ void page;
316
+ const cells = await rowCells(row);
317
+ const fields = {};
318
+ for (const [name, index] of Object.entries(surface.list.fieldCellIndexes)) {
319
+ fields[name] = (cells[index] ?? '').trim();
320
+ }
321
+ return fields;
322
+ }
323
+ /** Fills exactly the declared inputs on the current form. */
324
+ async function fillFormFields(page, selectors, fields) {
325
+ for (const [name, selector] of Object.entries(selectors)) {
326
+ const value = fields[name];
327
+ if (value === undefined)
328
+ continue;
329
+ await page.locator(selector).fill(value, { timeout: ENGINE_STEP_TIMEOUT_MS });
330
+ }
331
+ }
332
+ /** Reads the current form's input values back. */
333
+ async function readFormFields(page, selectors) {
334
+ const fields = {};
335
+ for (const [name, selector] of Object.entries(selectors)) {
336
+ fields[name] = await page.locator(selector).inputValue({ timeout: ENGINE_STEP_TIMEOUT_MS });
337
+ }
338
+ return fields;
339
+ }
340
+ /** Navigates to the list and proves it rendered. */
341
+ async function gotoList(page, appBase, surface) {
342
+ await page.goto(`${appBase}${surface.list.path}`, { timeout: ENGINE_STEP_TIMEOUT_MS });
343
+ await page.waitForSelector(surface.list.readySelector, { timeout: ENGINE_STEP_TIMEOUT_MS });
344
+ }
345
+ /** Waits for the post-action landing and proves it rendered. */
346
+ async function waitAfterAction(page, surface) {
347
+ await page.waitForURL((url) => url.pathname === surface.afterAction.path, {
348
+ timeout: ENGINE_STEP_TIMEOUT_MS,
349
+ });
350
+ await page.waitForSelector(surface.list.readySelector, { timeout: ENGINE_STEP_TIMEOUT_MS });
351
+ }
352
+ /**
353
+ * Drives one constrained surface operation on the engine page and
354
+ * observes every step itself.
355
+ *
356
+ * Args:
357
+ * page: the session's engine-owned page.
358
+ * appBase: loopback app base the engine navigates (validated upstream).
359
+ * surface: the validated consumer descriptor (locators only).
360
+ * operation: the constrained operation to perform.
361
+ * input: entered fields (create/update) and/or the target entity id.
362
+ *
363
+ * Returns:
364
+ * Promise<EngineActionObservation>: the engine's own observation —
365
+ * observed entity id, entered + rendered fields, captured exchanges.
366
+ *
367
+ * Throws:
368
+ * EngineBrowserError: fail-closed on every untrusted outcome —
369
+ * missing rows, ambiguous creation, wrong rendered status, no
370
+ * application request, or an application error status.
371
+ */
372
+ export async function driveEngineAction(page, appBase, surface, operation, input) {
373
+ const appOrigin = new URL(appBase).origin;
374
+ try {
375
+ return await driveEngineActionInner(page, appBase, appOrigin, surface, operation, input);
376
+ }
377
+ catch (error) {
378
+ // Every Playwright failure (timeout, navigation, detached frame) is
379
+ // an engine-observed unsuccessful action — never a 500: the test
380
+ // fails and the gate blocks with the precise cause.
381
+ if (error instanceof EngineBrowserError)
382
+ throw error;
383
+ throw new EngineBrowserError(`browser.${operation} failed: ${error.message}`);
384
+ }
385
+ }
386
+ /** The operation dispatch (wrapped by {@link driveEngineAction}). */
387
+ async function driveEngineActionInner(page, appBase, appOrigin, surface, operation, input) {
388
+ switch (operation) {
389
+ case 'create': {
390
+ const fields = declaredSurfaceFields('browser.create', input.fields ?? {}, surface.create.fields);
391
+ let entityId = '';
392
+ let rendered = {};
393
+ const exchanges = await captureExchanges(page, appOrigin, async () => {
394
+ await gotoList(page, appBase, surface);
395
+ const before = await collectIds(page, surface);
396
+ await page.goto(`${appBase}${surface.create.formPath}`, { timeout: ENGINE_STEP_TIMEOUT_MS });
397
+ await page.waitForSelector(surface.create.formReadySelector, { timeout: ENGINE_STEP_TIMEOUT_MS });
398
+ await fillFormFields(page, surface.create.fields, fields);
399
+ await page.locator(surface.create.submitSelector).click({ timeout: ENGINE_STEP_TIMEOUT_MS });
400
+ await waitAfterAction(page, surface);
401
+ const created = [...(await collectIds(page, surface))].filter((id) => !before.has(id));
402
+ if (created.length !== 1) {
403
+ throw new EngineBrowserError(`browser.create observed ${String(created.length)} new entities, expected exactly one — ` +
404
+ 'the rendered outcome is ambiguous, so no action record is issued');
405
+ }
406
+ entityId = created[0];
407
+ const row = await findRow(page, surface, entityId);
408
+ if (row === null) {
409
+ throw new EngineBrowserError(`browser.create: the rendered list exposes no row for the created entity ${entityId}`);
410
+ }
411
+ rendered = await readRowFields(page, surface, row);
412
+ if (surface.status.createdValue !== undefined) {
413
+ const shown = rendered[surface.status.field] ?? '';
414
+ if (shown !== surface.status.createdValue) {
415
+ throw new EngineBrowserError(`browser.create: entity ${entityId} rendered ${surface.status.field} '${shown}', ` +
416
+ `expected '${surface.status.createdValue}' — the application displays an error state, ` +
417
+ 'so the action fails instead of earning proof');
418
+ }
419
+ }
420
+ });
421
+ requireAppRequest(exchanges, 'create');
422
+ return { entityId, enteredFields: fields, renderedFields: rendered, exchanges };
423
+ }
424
+ case 'read': {
425
+ const entityId = input.entityId ?? '';
426
+ if (entityId === '')
427
+ throw new EngineBrowserError('browser.read requires { entityId }');
428
+ let rendered = {};
429
+ const exchanges = await captureExchanges(page, appOrigin, async () => {
430
+ await gotoList(page, appBase, surface);
431
+ const row = await findRow(page, surface, entityId);
432
+ if (row === null) {
433
+ throw new EngineBrowserError(`browser.read: the rendered UI exposes no row for ${entityId}`);
434
+ }
435
+ const edit = row.locator(surface.edit.linkSelector);
436
+ if ((await edit.count()) === 0) {
437
+ throw new EngineBrowserError(`browser.read: the rendered UI exposes no navigation control for ${entityId}`);
438
+ }
439
+ await edit.click({ timeout: ENGINE_STEP_TIMEOUT_MS });
440
+ await page.waitForSelector(renderSurfaceTemplate(surface.edit.formReadySelectorTemplate, entityId), {
441
+ timeout: ENGINE_STEP_TIMEOUT_MS,
442
+ });
443
+ rendered = await readFormFields(page, surface.edit.fields);
444
+ });
445
+ return { entityId, enteredFields: {}, renderedFields: rendered, exchanges };
446
+ }
447
+ case 'update': {
448
+ const entityId = input.entityId ?? '';
449
+ if (entityId === '')
450
+ throw new EngineBrowserError('browser.update requires { entityId }');
451
+ const fields = declaredSurfaceFields('browser.update', input.fields ?? {}, surface.edit.fields);
452
+ let rendered = {};
453
+ const exchanges = await captureExchanges(page, appOrigin, async () => {
454
+ await gotoList(page, appBase, surface);
455
+ const row = await findRow(page, surface, entityId);
456
+ if (row === null) {
457
+ throw new EngineBrowserError(`browser.update: the rendered UI exposes no row for ${entityId}`);
458
+ }
459
+ await row.locator(surface.edit.linkSelector).click({ timeout: ENGINE_STEP_TIMEOUT_MS });
460
+ await page.waitForSelector(renderSurfaceTemplate(surface.edit.formReadySelectorTemplate, entityId), {
461
+ timeout: ENGINE_STEP_TIMEOUT_MS,
462
+ });
463
+ await fillFormFields(page, surface.edit.fields, fields);
464
+ await page
465
+ .locator(renderSurfaceTemplate(surface.edit.saveSelectorTemplate, entityId))
466
+ .first()
467
+ .click({ timeout: ENGINE_STEP_TIMEOUT_MS });
468
+ await waitAfterAction(page, surface);
469
+ const updatedRow = await findRow(page, surface, entityId);
470
+ if (updatedRow === null) {
471
+ throw new EngineBrowserError(`browser.update: entity ${entityId} vanished after update`);
472
+ }
473
+ rendered = await readRowFields(page, surface, updatedRow);
474
+ });
475
+ requireAppRequest(exchanges, 'update');
476
+ return { entityId, enteredFields: fields, renderedFields: rendered, exchanges };
477
+ }
478
+ case 'delete': {
479
+ const entityId = input.entityId ?? '';
480
+ if (entityId === '')
481
+ throw new EngineBrowserError('browser.archive requires { entityId }');
482
+ const deleteFields = { ...surface.deleteFields };
483
+ let rendered = {};
484
+ const exchanges = await captureExchanges(page, appOrigin, async () => {
485
+ await gotoList(page, appBase, surface);
486
+ const row = await findRow(page, surface, entityId);
487
+ if (row === null) {
488
+ throw new EngineBrowserError(`browser.archive: the rendered UI exposes no row for ${entityId}`);
489
+ }
490
+ const control = row.locator(renderSurfaceTemplate(surface.archive.controlSelectorTemplate, entityId));
491
+ if ((await control.count()) === 0) {
492
+ throw new EngineBrowserError(`browser.archive: entity ${entityId} exposes no archive control (already archived?)`);
493
+ }
494
+ await control.click({ timeout: ENGINE_STEP_TIMEOUT_MS });
495
+ await waitAfterAction(page, surface);
496
+ const archivedRow = await findRow(page, surface, entityId);
497
+ if (archivedRow === null) {
498
+ throw new EngineBrowserError(`browser.archive: entity ${entityId} vanished after archive`);
499
+ }
500
+ rendered = await readRowFields(page, surface, archivedRow);
501
+ if (surface.status.archivedValue !== undefined) {
502
+ const shown = rendered[surface.status.field] ?? '';
503
+ if (shown !== surface.status.archivedValue) {
504
+ throw new EngineBrowserError(`browser.archive: entity ${entityId} rendered ${surface.status.field} '${shown}', ` +
505
+ `expected '${surface.status.archivedValue}' — the application displays an error ` +
506
+ 'state, so the action fails instead of earning proof');
507
+ }
508
+ }
509
+ });
510
+ requireAppRequest(exchanges, 'delete');
511
+ return { entityId, enteredFields: deleteFields, renderedFields: rendered, exchanges };
512
+ }
513
+ }
514
+ }
515
+ /**
516
+ * Requires that the action window captured at least one application
517
+ * request that the app did not reject: a rendered click that caused no
518
+ * request (or only error statuses) proves no application behavior.
519
+ *
520
+ * Args:
521
+ * exchanges: the engine-captured app-origin exchanges.
522
+ * operation: the performed operation (diagnostic only).
523
+ *
524
+ * Throws:
525
+ * EngineBrowserError: when no acceptable application request exists.
526
+ */
527
+ function requireAppRequest(exchanges, operation) {
528
+ const mutation = exchanges.filter((entry) => entry.method !== 'GET' && entry.method !== 'HEAD');
529
+ if (mutation.length === 0) {
530
+ throw new EngineBrowserError(`browser.${operation}: the engine captured no application request for the action — ` +
531
+ 'a rendered click that caused no request proves no application behavior');
532
+ }
533
+ const accepted = mutation.find((entry) => entry.status < 400);
534
+ if (accepted === undefined) {
535
+ throw new EngineBrowserError(`browser.${operation}: every captured application request was rejected ` +
536
+ `(${mutation.map((entry) => `${entry.method} ${entry.path} → ${String(entry.status)}`).join(', ')}) — ` +
537
+ 'the application refused the action, so it fails instead of earning proof');
538
+ }
539
+ }
540
+ /**
541
+ * Re-reads the rendered result for one entity on the engine page
542
+ * (the `visible.confirm` counterpart): row read for mutations, form
543
+ * read for reads.
544
+ *
545
+ * Args:
546
+ * page: the session's engine-owned page.
547
+ * appBase: loopback app base.
548
+ * surface: the validated consumer descriptor.
549
+ * operation: the original action (decides row vs form readback).
550
+ * entityId: the engine-observed entity id.
551
+ *
552
+ * Returns:
553
+ * Promise<Record<string, string>>: the rendered fields.
554
+ *
555
+ * Throws:
556
+ * EngineBrowserError: when the UI no longer exposes the entity.
557
+ */
558
+ export async function readEngineVisible(page, appBase, surface, operation, entityId) {
559
+ try {
560
+ await gotoList(page, appBase, surface);
561
+ const row = await findRow(page, surface, entityId);
562
+ if (row === null) {
563
+ throw new EngineBrowserError(`browser.visible: the rendered UI exposes no row for ${entityId}`);
564
+ }
565
+ if (operation === 'read') {
566
+ await row.locator(surface.edit.linkSelector).click({ timeout: ENGINE_STEP_TIMEOUT_MS });
567
+ await page.waitForSelector(renderSurfaceTemplate(surface.edit.formReadySelectorTemplate, entityId), {
568
+ timeout: ENGINE_STEP_TIMEOUT_MS,
569
+ });
570
+ return readFormFields(page, surface.edit.fields);
571
+ }
572
+ return readRowFields(page, surface, row);
573
+ }
574
+ catch (error) {
575
+ if (error instanceof EngineBrowserError)
576
+ throw error;
577
+ throw new EngineBrowserError(`browser.visible failed: ${error.message}`);
578
+ }
579
+ }
580
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/witness/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type Classification } from '@gate-forge/core';
2
+ /** The reporter-visible projection of one resource's classification. */
3
+ export interface ClassificationView {
4
+ primaryKey: string[];
5
+ exposure: string;
6
+ plane: string;
7
+ evidenceAdapter?: string;
8
+ /**
9
+ * Which evidence lane proves user-facing reachability (`'claims'` =
10
+ * the http.endpoint lane; adapter-free). MUST ride along: without it a
11
+ * claims-lane entry (user-facing, no adapter) re-validates downstream
12
+ * as "user-facing resources require an 'evidenceAdapter'" and the
13
+ * reporter grades the claim unclassified.
14
+ */
15
+ evidenceLane?: 'adapter' | 'claims';
16
+ lifecycle: {
17
+ create: boolean;
18
+ read: boolean;
19
+ update: boolean;
20
+ delete: boolean;
21
+ deleteSemantics?: 'hard' | 'archive';
22
+ archiveFields?: Record<string, string | number | boolean>;
23
+ updateableFields?: string[];
24
+ };
25
+ }
26
+ /**
27
+ * Loads the classifications document.
28
+ *
29
+ * Args:
30
+ * path: absolute path to the classifications YAML (or null/'' = none).
31
+ *
32
+ * Returns:
33
+ * Record<string, Classification>: validated per-resource map (empty
34
+ * when no document is configured).
35
+ *
36
+ * Throws:
37
+ * AdapterRegistryError: fail-closed load/validation problems.
38
+ */
39
+ export declare function loadClassifications(path: string | null | undefined): Record<string, Classification>;
40
+ /** Projects a classification for the reporter surface. */
41
+ export declare function toClassificationView(entry: Classification): ClassificationView;
42
+ //# sourceMappingURL=classifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifications.d.ts","sourceRoot":"","sources":["../../src/witness/classifications.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAG1B,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACrC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;QAC1D,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;CACH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAkCnG;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,kBAAkB,CAuB9E"}