@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,244 @@
1
+ /**
2
+ * Loopback egress binding (GF-10 follow-up): approving a hostname is not
3
+ * enough — every later connection must STAY on the approved loopback
4
+ * addresses even if resolution changes mid-run (DNS rebinding). This
5
+ * module pins operator-attested hostnames to their startup-resolved
6
+ * loopback IPs and binds all three strict-flow egresses to the pins:
7
+ *
8
+ * - the engine Chromium launches with `--host-resolver-rules` mapping
9
+ * each attested hostname to its approved IPs (the browser is then
10
+ * incapable of leaving loopback for those names);
11
+ * - witness adapter/probe reads go through `pinnedGet`, which connects
12
+ * to the pinned IP while preserving the original Host header (tenant
13
+ * routing intact) and port; same-hostname redirects are followed on
14
+ * the Location header's actual port with the matching Host header,
15
+ * while cross-host and cross-scheme hops reject (never a silent
16
+ * re-request of a different destination than the one named);
17
+ * - the observation-proxy upstream keeps startup resolve-or-reject only
18
+ * (that topology is unused by the strict spawned flow; documented).
19
+ *
20
+ * Fail-closed throughout: unresolvable/mixed/public resolutions reject
21
+ * at pin time; https reads against a pinned IP fail on certificate
22
+ * mismatch (no insecure override exists here); unpinned hostnames keep
23
+ * the previous plain-fetch behavior.
24
+ */
25
+ import { lookup } from 'node:dns/promises';
26
+ import { request as httpRequest } from 'node:http';
27
+ import { request as httpsRequest } from 'node:https';
28
+ /** Whether one address is loopback (127.0.0.0/8 or ::1). */
29
+ export function isLoopbackAddress(address) {
30
+ return address === '::1' || /^127(\.\d{1,3}){3}$/.test(address);
31
+ }
32
+ /** Hostname → startup-approved loopback IPs (first resolution wins). */
33
+ const pinnedIps = new Map();
34
+ /** Clears all pins (tests only — production paths pin once and bind). */
35
+ export function clearPinnedLoopbackForTests() {
36
+ pinnedIps.clear();
37
+ }
38
+ /**
39
+ * Resolves a hostname and pins ALL-loopback addresses, or rejects.
40
+ * The first successful pinning wins for the process lifetime: later
41
+ * resolutions (including hostile mid-run DNS changes) never replace
42
+ * it — connections bind to the startup-approved set.
43
+ *
44
+ * Args:
45
+ * hostname: the operator-provided hostname to attest.
46
+ * lookupFn: DNS lookup (default: OS resolver, all records).
47
+ *
48
+ * Returns:
49
+ * The pinned loopback IP list (IPv4 first, then IPv6, stable order).
50
+ *
51
+ * Throws:
52
+ * Error: on empty/mixed/public/unresolvable answers.
53
+ */
54
+ export async function pinLoopbackIps(hostname, lookupFn = (host) => lookup(host, { all: true, verbatim: true })) {
55
+ const existing = pinnedIps.get(hostname);
56
+ if (existing !== undefined)
57
+ return [...existing];
58
+ let records;
59
+ try {
60
+ records = await lookupFn(hostname);
61
+ }
62
+ catch {
63
+ throw new Error(`hostname '${hostname}' does not resolve to loopback (lookup failed)`);
64
+ }
65
+ if (records.length === 0 || !records.every((record) => isLoopbackAddress(record.address))) {
66
+ throw new Error(`hostname '${hostname}' does not resolve exclusively to loopback`);
67
+ }
68
+ const v4 = records.filter((record) => record.family === 4).map((record) => record.address);
69
+ const v6 = records.filter((record) => record.family !== 4).map((record) => record.address);
70
+ const pinned = [...new Set([...v4, ...v6])];
71
+ pinnedIps.set(hostname, pinned);
72
+ return [...pinned];
73
+ }
74
+ /**
75
+ * Snapshot copy of current pins (hostname → approved IPs).
76
+ *
77
+ * Returns:
78
+ * A detached copy for launch-arg construction.
79
+ */
80
+ export function pinnedLoopbackIps() {
81
+ return new Map([...pinnedIps].map(([host, ips]) => [host, [...ips]]));
82
+ }
83
+ /**
84
+ * Builds the Chromium `--host-resolver-rules` value binding every
85
+ * pinned hostname to its approved IPs (`MAP host ip`, comma-separated,
86
+ * deterministic order). IP literals are emitted bare (brackets are URL
87
+ * syntax and would break rule parsing).
88
+ *
89
+ * Args:
90
+ * pins: hostname → approved IPs (default: live snapshot).
91
+ *
92
+ * Returns:
93
+ * The rules string, or null when nothing is pinned (no flag then).
94
+ */
95
+ export function hostResolverRules(pins = pinnedLoopbackIps()) {
96
+ const rules = [];
97
+ for (const host of [...pins.keys()].sort()) {
98
+ for (const ip of pins.get(host) ?? []) {
99
+ rules.push(`MAP ${host} ${ip}`);
100
+ }
101
+ }
102
+ return rules.length > 0 ? rules.join(', ') : null;
103
+ }
104
+ /**
105
+ * GET through the startup pins: when the URL's hostname is pinned, the
106
+ * TCP connection goes to the pinned IP while the original Host header
107
+ * (host + non-default port) and path are preserved — tenant routing
108
+ * intact, destination bound. Unpinned hostnames use plain global fetch
109
+ * (previous behavior, unchanged).
110
+ *
111
+ * Args:
112
+ * url: absolute http(s) URL.
113
+ * options: timeout, headers, abort signal, redirect budget.
114
+ *
115
+ * Returns:
116
+ * Status + headers + body readers.
117
+ *
118
+ * Throws:
119
+ * Error: on transport failure, redirect overflow, or (https) the
120
+ * pinned IP failing certificate verification — fail closed, never
121
+ * plaintext fallback.
122
+ */
123
+ export async function pinnedGet(url, options) {
124
+ const pins = pinnedLoopbackIps();
125
+ const parsed = new URL(url);
126
+ const pinned = pins.get(parsed.hostname);
127
+ if (pinned === undefined || pinned.length === 0) {
128
+ const response = await fetch(url, {
129
+ method: 'GET',
130
+ headers: { accept: 'application/json, text/html', ...options.headers },
131
+ signal: options.signal,
132
+ redirect: 'follow',
133
+ });
134
+ return {
135
+ status: response.status,
136
+ headers: response.headers,
137
+ json: () => response.json(),
138
+ text: () => response.text(),
139
+ };
140
+ }
141
+ const ip = preferIpv4(pinned);
142
+ const port = parsed.port !== '' ? parsed.port : parsed.protocol === 'https:' ? '443' : '80';
143
+ const hostHeader = isDefaultPort(parsed.protocol, port) ? parsed.hostname : `${parsed.hostname}:${port}`;
144
+ return requestPinned({
145
+ protocol: parsed.protocol,
146
+ ip,
147
+ port: Number(port),
148
+ path: `${parsed.pathname}${parsed.search}`,
149
+ hostHeader,
150
+ headers: options.headers ?? {},
151
+ timeoutMs: options.timeoutMs,
152
+ signal: options.signal,
153
+ maxRedirects: options.maxRedirects ?? 5,
154
+ });
155
+ }
156
+ /** Prefers an IPv4 loopback pin, else the first approved IP. */
157
+ function preferIpv4(ips) {
158
+ return ips.find((ip) => /^127(\.\d{1,3}){3}$/.test(ip)) ?? ips[0];
159
+ }
160
+ /** Whether the port is the protocol default (Host header omits it then). */
161
+ function isDefaultPort(protocol, port) {
162
+ return (protocol === 'http:' && port === '80') || (protocol === 'https:' && port === '443');
163
+ }
164
+ async function requestPinned(input) {
165
+ if (input.protocol !== 'http:' && input.protocol !== 'https:') {
166
+ throw new Error(`pinned egress supports http(s) only (got '${input.protocol}')`);
167
+ }
168
+ // eslint-disable-next-line no-await-in-loop -- redirect hops are sequential by construction
169
+ for (let redirect = 0; redirect <= input.maxRedirects; redirect += 1) {
170
+ const response = await singleRequest(input);
171
+ const location = response.headers.get('location');
172
+ if (response.status >= 300 && response.status < 400 && location !== null) {
173
+ const next = new URL(location, `${input.protocol}//${input.hostHeader}${input.path}`);
174
+ // Redirects stay on pinned egress: only same-hostname hops are
175
+ // followed through the pins; anything else fails closed (the
176
+ // browser path enforces the same origin rule in captureExchanges).
177
+ if (next.hostname !== input.hostHeader.split(':')[0]) {
178
+ throw new Error(`pinned egress refuses cross-host redirect to '${next.hostname}'`);
179
+ }
180
+ // Same-host hops follow the Location's ACTUAL origin: protocol,
181
+ // port, and Host header all update, and the connection stays bound
182
+ // to the pinned IP. Re-requesting the previous origin (old port)
183
+ // with the new path — or silently trusting the header while
184
+ // keeping the old transport — would read a different destination
185
+ // than the one the service named. A scheme change is rejected
186
+ // outright: https against the pinned loopback IP can never verify
187
+ // a certificate here, so it fails closed with the precise cause.
188
+ if (next.protocol !== input.protocol) {
189
+ throw new Error(`pinned egress refuses cross-scheme redirect (${input.protocol} → ${next.protocol} '${location}')`);
190
+ }
191
+ const port = next.port !== '' ? next.port : next.protocol === 'https:' ? '443' : '80';
192
+ input = {
193
+ ...input,
194
+ port: Number(port),
195
+ path: `${next.pathname}${next.search}`,
196
+ hostHeader: isDefaultPort(next.protocol, port) ? next.hostname : `${next.hostname}:${port}`,
197
+ };
198
+ continue;
199
+ }
200
+ return response;
201
+ }
202
+ throw new Error('pinned egress exceeded redirect budget');
203
+ }
204
+ function singleRequest(input) {
205
+ return new Promise((resolve, reject) => {
206
+ const requestFn = input.protocol === 'https:' ? httpsRequest : httpRequest;
207
+ const request = requestFn({
208
+ hostname: input.ip,
209
+ port: input.port,
210
+ path: input.path,
211
+ method: 'GET',
212
+ headers: { accept: 'application/json, text/html', ...input.headers, host: input.hostHeader },
213
+ timeout: input.timeoutMs,
214
+ }, (response) => {
215
+ const chunks = [];
216
+ response.on('data', (chunk) => chunks.push(chunk));
217
+ response.on('end', () => {
218
+ const body = Buffer.concat(chunks);
219
+ const headers = new Headers();
220
+ for (const [name, value] of Object.entries(response.headersDistinct ?? {})) {
221
+ const values = Array.isArray(value) ? value : [value ?? ''];
222
+ for (const item of values)
223
+ headers.append(name, item);
224
+ }
225
+ resolve({
226
+ status: response.statusCode ?? 0,
227
+ headers,
228
+ json: () => Promise.resolve(JSON.parse(body.toString('utf8'))),
229
+ text: () => Promise.resolve(body.toString('utf8')),
230
+ });
231
+ });
232
+ });
233
+ request.on('timeout', () => request.destroy(new Error('pinned egress timed out')));
234
+ if (input.signal !== undefined) {
235
+ if (input.signal.aborted)
236
+ request.destroy(new Error('pinned egress aborted'));
237
+ else
238
+ input.signal.addEventListener('abort', () => request.destroy(new Error('pinned egress aborted')), { once: true });
239
+ }
240
+ request.on('error', reject);
241
+ request.end();
242
+ });
243
+ }
244
+ //# sourceMappingURL=loopback-pins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback-pins.js","sourceRoot":"","sources":["../../src/witness/loopback-pins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { recordIdOf } from '@gate-forge/core';
2
+ import type { WitnessHandle, WitnessOptions } from './types.js';
3
+ /** Fail-closed witness configuration/startup error. */
4
+ export declare class WitnessStartupError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ /**
8
+ * The service-issued recordId comes from the frozen core primitive
9
+ * (`recordIdOf`, pin #1/#7): sha256 over GF-canonical JSON of the record
10
+ * identity. Sharing one implementation with the engine's provenance
11
+ * verifier guarantees the witness issues exactly what evaluation can
12
+ * recompute — an entry that never passed through the service has no
13
+ * matching hash, so shape-level fabrication (a hex string the service
14
+ * never issued) cannot line up with the ledger the reporter copies.
15
+ */
16
+ export { recordIdOf };
17
+ /**
18
+ * Starts the witness service.
19
+ *
20
+ * Args:
21
+ * options: run identity + token (required), state dir, adapters dir,
22
+ * classifications path, target/attestation config, timeout, clock.
23
+ *
24
+ * Returns:
25
+ * WitnessHandle: {url, stop} once the server listens.
26
+ *
27
+ * Throws:
28
+ * WitnessStartupError / AdapterRegistryError / AttestationError:
29
+ * fail-closed startup problems (GF-10 blocks non-loopback targets
30
+ * HERE, before any adapter request can be constructed).
31
+ */
32
+ export declare function startWitness(options: WitnessOptions): Promise<WitnessHandle>;
33
+ export type { WitnessHandle } from './types.js';
34
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/witness/server.ts"],"names":[],"mappings":"AAoHA,OAAO,EAIL,UAAU,EAIX,MAAM,kBAAkB,CAAC;AA+B1B,OAAO,KAAK,EA0BV,aAAa,EACb,cAAc,EACf,MAAM,YAAY,CAAC;AAgCpB,uDAAuD;AACvD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAuUD;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,CAAC;AA6BtB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAqJlF;AAo3ED,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}