@gate-forge/pack-playwright 0.7.1 → 0.8.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.
- package/README.md +31 -0
- package/dist/constants.d.ts +13 -140
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +13 -148
- package/dist/constants.js.map +1 -1
- package/dist/cypress/plugin.d.ts +53 -0
- package/dist/cypress/plugin.d.ts.map +1 -0
- package/dist/cypress/plugin.js +369 -0
- package/dist/cypress/plugin.js.map +1 -0
- package/dist/cypress/spec-scan.d.ts +39 -0
- package/dist/cypress/spec-scan.d.ts.map +1 -0
- package/dist/cypress/spec-scan.js +301 -0
- package/dist/cypress/spec-scan.js.map +1 -0
- package/dist/diagnosis.d.ts +39 -0
- package/dist/diagnosis.d.ts.map +1 -0
- package/dist/diagnosis.js +63 -0
- package/dist/diagnosis.js.map +1 -0
- package/dist/discovery/adapter-projection.d.ts +13 -0
- package/dist/discovery/adapter-projection.d.ts.map +1 -0
- package/dist/discovery/adapter-projection.js +84 -0
- package/dist/discovery/adapter-projection.js.map +1 -0
- package/dist/discovery/config-locations.d.ts +5 -0
- package/dist/discovery/config-locations.d.ts.map +1 -0
- package/dist/discovery/config-locations.js +19 -0
- package/dist/discovery/config-locations.js.map +1 -0
- package/dist/discovery/cypress-runner-adapter.d.ts +112 -0
- package/dist/discovery/cypress-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/cypress-runner-adapter.js +501 -0
- package/dist/discovery/cypress-runner-adapter.js.map +1 -0
- package/dist/discovery/discover.d.ts +53 -1
- package/dist/discovery/discover.d.ts.map +1 -1
- package/dist/discovery/discover.js +100 -3
- package/dist/discovery/discover.js.map +1 -1
- package/dist/discovery/git-ignore.d.ts +13 -0
- package/dist/discovery/git-ignore.d.ts.map +1 -0
- package/dist/discovery/git-ignore.js +62 -0
- package/dist/discovery/git-ignore.js.map +1 -0
- package/dist/discovery/index.d.ts +9 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +9 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/playwright-runner-adapter.d.ts +108 -0
- package/dist/discovery/playwright-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/playwright-runner-adapter.js +185 -0
- package/dist/discovery/playwright-runner-adapter.js.map +1 -0
- package/dist/discovery/prepare-barrier.d.ts +522 -0
- package/dist/discovery/prepare-barrier.d.ts.map +1 -0
- package/dist/discovery/prepare-barrier.js +739 -0
- package/dist/discovery/prepare-barrier.js.map +1 -0
- package/dist/discovery/pytest-adapter.d.ts.map +1 -1
- package/dist/discovery/pytest-adapter.js +6 -2
- package/dist/discovery/pytest-adapter.js.map +1 -1
- package/dist/discovery/pytest-runner-adapter.d.ts +124 -0
- package/dist/discovery/pytest-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/pytest-runner-adapter.js +454 -0
- package/dist/discovery/pytest-runner-adapter.js.map +1 -0
- package/dist/discovery/reconcile.d.ts +80 -11
- package/dist/discovery/reconcile.d.ts.map +1 -1
- package/dist/discovery/reconcile.js +395 -78
- package/dist/discovery/reconcile.js.map +1 -1
- package/dist/discovery/runner-env.d.ts +88 -2
- package/dist/discovery/runner-env.d.ts.map +1 -1
- package/dist/discovery/runner-env.js +142 -4
- package/dist/discovery/runner-env.js.map +1 -1
- package/dist/discovery/static-discovery.d.ts +38 -3
- package/dist/discovery/static-discovery.d.ts.map +1 -1
- package/dist/discovery/static-discovery.js +454 -15
- package/dist/discovery/static-discovery.js.map +1 -1
- package/dist/discovery/supervised-run.d.ts +199 -10
- package/dist/discovery/supervised-run.d.ts.map +1 -1
- package/dist/discovery/supervised-run.js +350 -39
- package/dist/discovery/supervised-run.js.map +1 -1
- package/dist/discovery/trusted-config.d.ts +180 -6
- package/dist/discovery/trusted-config.d.ts.map +1 -1
- package/dist/discovery/trusted-config.js +279 -10
- package/dist/discovery/trusted-config.js.map +1 -1
- package/dist/discovery/vitest-runner-adapter.d.ts +172 -0
- package/dist/discovery/vitest-runner-adapter.d.ts.map +1 -0
- package/dist/discovery/vitest-runner-adapter.js +607 -0
- package/dist/discovery/vitest-runner-adapter.js.map +1 -0
- package/dist/fixture/consumer-runner.d.ts +4 -0
- package/dist/fixture/consumer-runner.d.ts.map +1 -0
- package/dist/fixture/consumer-runner.js +38 -0
- package/dist/fixture/consumer-runner.js.map +1 -0
- package/dist/fixture/evidence.d.ts +27 -0
- package/dist/fixture/evidence.d.ts.map +1 -1
- package/dist/fixture/evidence.js +12 -0
- package/dist/fixture/evidence.js.map +1 -1
- package/dist/fixture/fixture.d.ts +2 -1
- package/dist/fixture/fixture.d.ts.map +1 -1
- package/dist/fixture/fixture.js +1 -17
- package/dist/fixture/fixture.js.map +1 -1
- package/dist/fixture/witness-client.d.ts +6 -174
- package/dist/fixture/witness-client.d.ts.map +1 -1
- package/dist/fixture/witness-client.js +6 -267
- package/dist/fixture/witness-client.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +6 -12
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +6 -17
- package/dist/json.js.map +1 -1
- package/dist/reporter/project-graph-reporter.d.ts +92 -0
- package/dist/reporter/project-graph-reporter.d.ts.map +1 -0
- package/dist/reporter/project-graph-reporter.js +92 -0
- package/dist/reporter/project-graph-reporter.js.map +1 -0
- package/dist/reporter/reporter.cjs.map +1 -1
- package/dist/reporter/reporter.d.ts +93 -4
- package/dist/reporter/reporter.d.ts.map +1 -1
- package/dist/reporter/reporter.js +174 -18
- package/dist/reporter/reporter.js.map +1 -1
- package/dist/runner-claims.d.ts +13 -0
- package/dist/runner-claims.d.ts.map +1 -0
- package/dist/runner-claims.js +46 -0
- package/dist/runner-claims.js.map +1 -0
- package/dist/runner-resolution.d.ts +3 -0
- package/dist/runner-resolution.d.ts.map +1 -0
- package/dist/runner-resolution.js +14 -0
- package/dist/runner-resolution.js.map +1 -0
- package/dist/supervisor/client.d.ts +23 -1
- package/dist/supervisor/client.d.ts.map +1 -1
- package/dist/supervisor/client.js +49 -0
- package/dist/supervisor/client.js.map +1 -1
- package/dist/supervisor/drain.d.ts +65 -0
- package/dist/supervisor/drain.d.ts.map +1 -1
- package/dist/supervisor/drain.js +353 -9
- package/dist/supervisor/drain.js.map +1 -1
- package/dist/supervisor/index.d.ts +7 -3
- package/dist/supervisor/index.d.ts.map +1 -1
- package/dist/supervisor/index.js +7 -3
- package/dist/supervisor/index.js.map +1 -1
- package/dist/supervisor/spool.d.ts +65 -2
- package/dist/supervisor/spool.d.ts.map +1 -1
- package/dist/supervisor/spool.js +47 -0
- package/dist/supervisor/spool.js.map +1 -1
- package/dist/surface.d.ts +6 -207
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +6 -264
- package/dist/surface.js.map +1 -1
- package/dist/vitest/index.d.ts +23 -0
- package/dist/vitest/index.d.ts.map +1 -0
- package/dist/vitest/index.js +356 -0
- package/dist/vitest/index.js.map +1 -0
- package/dist/vitest/reporter.d.ts +83 -0
- package/dist/vitest/reporter.d.ts.map +1 -0
- package/dist/vitest/reporter.js +211 -0
- package/dist/vitest/reporter.js.map +1 -0
- package/dist/vitest/worker-slot.d.ts +36 -0
- package/dist/vitest/worker-slot.d.ts.map +1 -0
- package/dist/vitest/worker-slot.js +51 -0
- package/dist/vitest/worker-slot.js.map +1 -0
- package/dist/witness/adapter-registry.d.ts +6 -50
- package/dist/witness/adapter-registry.d.ts.map +1 -1
- package/dist/witness/adapter-registry.js +6 -257
- package/dist/witness/adapter-registry.js.map +1 -1
- package/dist/witness/behavior-request.d.ts +6 -76
- package/dist/witness/behavior-request.d.ts.map +1 -1
- package/dist/witness/behavior-request.js +6 -273
- package/dist/witness/behavior-request.js.map +1 -1
- package/dist/witness/behavior.d.ts +6 -48
- package/dist/witness/behavior.d.ts.map +1 -1
- package/dist/witness/behavior.js +6 -114
- package/dist/witness/behavior.js.map +1 -1
- package/dist/witness/bin.d.ts +6 -17
- package/dist/witness/bin.d.ts.map +1 -1
- package/dist/witness/bin.js +6 -168
- package/dist/witness/bin.js.map +1 -1
- package/dist/witness/browser.d.ts +14 -206
- package/dist/witness/browser.d.ts.map +1 -1
- package/dist/witness/browser.js +15 -654
- package/dist/witness/browser.js.map +1 -1
- package/dist/witness/classifications.d.ts +6 -38
- package/dist/witness/classifications.d.ts.map +1 -1
- package/dist/witness/classifications.js +6 -83
- package/dist/witness/classifications.js.map +1 -1
- package/dist/witness/env-attestation.d.ts +6 -94
- package/dist/witness/env-attestation.d.ts.map +1 -1
- package/dist/witness/env-attestation.js +6 -198
- package/dist/witness/env-attestation.js.map +1 -1
- package/dist/witness/fixture-provider.d.ts +6 -82
- package/dist/witness/fixture-provider.d.ts.map +1 -1
- package/dist/witness/fixture-provider.js +6 -105
- package/dist/witness/fixture-provider.js.map +1 -1
- package/dist/witness/loopback-pins.d.ts +6 -75
- package/dist/witness/loopback-pins.d.ts.map +1 -1
- package/dist/witness/loopback-pins.js +6 -240
- package/dist/witness/loopback-pins.js.map +1 -1
- package/dist/witness/server.d.ts +8 -26
- package/dist/witness/server.d.ts.map +1 -1
- package/dist/witness/server.js +24 -3761
- package/dist/witness/server.js.map +1 -1
- package/dist/witness/types.d.ts +6 -882
- package/dist/witness/types.d.ts.map +1 -1
- package/dist/witness/types.js +9 -1
- package/dist/witness/types.js.map +1 -1
- package/examples/overlay-proof.spec.js +75 -0
- package/package.json +8 -2
- package/python/__pycache__/gateforge_persistence_intents.cpython-312.pyc +0 -0
- package/python/__pycache__/gateforge_persistence_intents.cpython-314.pyc +0 -0
- package/python/gateforge_pytest_plugin.py +462 -0
|
@@ -1,277 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* origin with approved actor material. The worker never touches the
|
|
5
|
-
* request — method, path, query, body, and credentials all resolve
|
|
6
|
-
* engine-side from the supervisor-bound case and the trusted lease.
|
|
2
|
+
* Compatibility re-export: `witness/behavior-request` now lives in the runner-neutral
|
|
3
|
+
* `@gate-forge/witness` package (plan 2026-09-25 phase 1).
|
|
7
4
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - `multipart`/`raw` encodings and signature profiles need the
|
|
12
|
-
* Phase 6/8 drivers and block here;
|
|
13
|
-
* - resolved path values cannot smuggle segments (`/` rejected).
|
|
5
|
+
* The move is physical, not behavioural: this module forwards every
|
|
6
|
+
* export unchanged so `@gate-forge/pack-playwright`'s published import
|
|
7
|
+
* paths — which consumers pin — keep resolving to the same values.
|
|
14
8
|
*/
|
|
15
|
-
|
|
16
|
-
import { sha256Canonical } from '@gate-forge/core';
|
|
17
|
-
import { assertLoopback } from './env-attestation.js';
|
|
18
|
-
/** Proof-input bound (request and response bodies alike). */
|
|
19
|
-
export const BEHAVIOR_BODY_LIMIT_BYTES = 256 * 1024;
|
|
20
|
-
/** Typed driver failure (always a blocking diagnostic, never proof). */
|
|
21
|
-
export class BehaviorDriverError extends Error {
|
|
22
|
-
constructor(message) {
|
|
23
|
-
super(message);
|
|
24
|
-
this.name = 'BehaviorDriverError';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/** Unsafe fixture-key segments (no prototype-chain traversal). */
|
|
28
|
-
const FORBIDDEN_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);
|
|
29
|
-
/** Resolves one InputValue against sealed lease subjects. */
|
|
30
|
-
function resolveValue(raw, subjects, what) {
|
|
31
|
-
if (raw.from === 'literal')
|
|
32
|
-
return raw.value ?? null;
|
|
33
|
-
if (raw.from === 'fixture') {
|
|
34
|
-
if (typeof raw.key !== 'string')
|
|
35
|
-
throw new BehaviorDriverError(`${what} fixture reference has no key`);
|
|
36
|
-
const segments = raw.key.split('.');
|
|
37
|
-
if (segments.some((segment) => segment.length === 0 || FORBIDDEN_SEGMENTS.has(segment))) {
|
|
38
|
-
throw new BehaviorDriverError(`${what} fixture key is forbidden`);
|
|
39
|
-
}
|
|
40
|
-
let current = subjects;
|
|
41
|
-
for (const segment of segments) {
|
|
42
|
-
if (typeof current !== 'object' || current === null || Array.isArray(current)) {
|
|
43
|
-
throw new BehaviorDriverError(`${what} fixture key '${raw.key}' does not resolve`);
|
|
44
|
-
}
|
|
45
|
-
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
46
|
-
throw new BehaviorDriverError(`${what} fixture key '${raw.key}' does not resolve`);
|
|
47
|
-
}
|
|
48
|
-
current = current[segment];
|
|
49
|
-
}
|
|
50
|
-
return current ?? null;
|
|
51
|
-
}
|
|
52
|
-
throw new BehaviorDriverError(`${what} uses an unsupported value source '${raw.from}'`);
|
|
53
|
-
}
|
|
54
|
-
/** Reads a bounded body from a fetch response (over-limit aborts). */
|
|
55
|
-
async function readBoundedBody(response, limit) {
|
|
56
|
-
const reader = response.body?.getReader();
|
|
57
|
-
if (reader === undefined || reader === null) {
|
|
58
|
-
const text = await response.text();
|
|
59
|
-
if (text.length > limit)
|
|
60
|
-
throw new BehaviorDriverError('response body exceeds the proof bound');
|
|
61
|
-
return text;
|
|
62
|
-
}
|
|
63
|
-
const chunks = [];
|
|
64
|
-
let total = 0;
|
|
65
|
-
for (;;) {
|
|
66
|
-
const { done, value } = await reader.read();
|
|
67
|
-
if (done)
|
|
68
|
-
break;
|
|
69
|
-
total += value.byteLength;
|
|
70
|
-
if (total > limit) {
|
|
71
|
-
try {
|
|
72
|
-
await response.body?.cancel();
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
// Best-effort cancel; the bound violation below is the verdict.
|
|
76
|
-
}
|
|
77
|
-
throw new BehaviorDriverError('response body exceeds the proof bound');
|
|
78
|
-
}
|
|
79
|
-
chunks.push(value);
|
|
80
|
-
}
|
|
81
|
-
return Buffer.concat(chunks).toString('utf8');
|
|
82
|
-
}
|
|
83
|
-
/** Parses a body as JSON, falling back to raw text. */
|
|
84
|
-
function parseBody(text) {
|
|
85
|
-
const trimmed = text.trim();
|
|
86
|
-
if (trimmed.length === 0)
|
|
87
|
-
return '';
|
|
88
|
-
try {
|
|
89
|
-
return JSON.parse(trimmed);
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
return text;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Drives one approved request and captures the bounded observation.
|
|
97
|
-
*
|
|
98
|
-
* Args:
|
|
99
|
-
* input: action, lease, actor profile, origin, credential resolver,
|
|
100
|
-
* and timeout.
|
|
101
|
-
*
|
|
102
|
-
* Returns:
|
|
103
|
-
* DrivenRequest: method/path/query/body/status/response plus
|
|
104
|
-
* identity digests (headers never leave the driver).
|
|
105
|
-
*
|
|
106
|
-
* Throws:
|
|
107
|
-
* BehaviorDriverError: unsupported encoding, unresolvable value,
|
|
108
|
-
* non-loopback origin, timeout, over-limit body, or transport
|
|
109
|
-
* failure — always a blocking diagnostic, never proof.
|
|
110
|
-
*/
|
|
111
|
-
export async function driveBehaviorRequest(input) {
|
|
112
|
-
const { action, lease } = input;
|
|
113
|
-
if (action.signatureProfile !== undefined && action.signatureProfile !== 'hmac-sha256') {
|
|
114
|
-
throw new BehaviorDriverError(`unsupported signature profile '${action.signatureProfile}'`);
|
|
115
|
-
}
|
|
116
|
-
if (action.body.encoding === 'multipart') {
|
|
117
|
-
throw new BehaviorDriverError(`'multipart' bodies need the Phase 6 file driver`);
|
|
118
|
-
}
|
|
119
|
-
if (action.body.encoding === 'raw' && action.signatureProfile === undefined) {
|
|
120
|
-
throw new BehaviorDriverError(`'raw' bodies require an engine-side signature profile`);
|
|
121
|
-
}
|
|
122
|
-
await assertLoopback(input.origin, 'behavior principal').catch((error) => {
|
|
123
|
-
throw new BehaviorDriverError(error instanceof Error ? error.message : String(error));
|
|
124
|
-
});
|
|
125
|
-
const base = input.origin.replace(/\/+$/, '');
|
|
126
|
-
// Concrete path: every template variable resolves to a segment-safe value.
|
|
127
|
-
const templateSegments = action.pathTemplate.split('/');
|
|
128
|
-
const concreteSegments = [];
|
|
129
|
-
for (const segment of templateSegments) {
|
|
130
|
-
const match = /^\{([A-Za-z0-9_]+)\}$/.exec(segment);
|
|
131
|
-
if (match === null) {
|
|
132
|
-
concreteSegments.push(segment);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
const name = match[1];
|
|
136
|
-
const raw = action.path[name];
|
|
137
|
-
if (raw === undefined)
|
|
138
|
-
throw new BehaviorDriverError(`path parameter '${name}' is not declared`);
|
|
139
|
-
const resolved = resolveValue(raw, lease.subjects, `path parameter '${name}'`);
|
|
140
|
-
if (typeof resolved !== 'string' && typeof resolved !== 'number') {
|
|
141
|
-
throw new BehaviorDriverError(`path parameter '${name}' is not a scalar`);
|
|
142
|
-
}
|
|
143
|
-
const text = String(resolved);
|
|
144
|
-
if (text.length === 0 || text.includes('/')) {
|
|
145
|
-
throw new BehaviorDriverError(`path parameter '${name}' would smuggle path segments`);
|
|
146
|
-
}
|
|
147
|
-
concreteSegments.push(encodeURIComponent(text));
|
|
148
|
-
}
|
|
149
|
-
const path = concreteSegments.join('/').replace(/\/+/g, '/');
|
|
150
|
-
// Declared query, resolved exactly (the driver sends the contract).
|
|
151
|
-
const query = {};
|
|
152
|
-
for (const [name, raw] of Object.entries(action.query)) {
|
|
153
|
-
const resolved = resolveValue(raw, lease.subjects, `query parameter '${name}'`);
|
|
154
|
-
if (typeof resolved !== 'string' && typeof resolved !== 'number' && typeof resolved !== 'boolean') {
|
|
155
|
-
throw new BehaviorDriverError(`query parameter '${name}' is not a scalar`);
|
|
156
|
-
}
|
|
157
|
-
query[name] = resolved;
|
|
158
|
-
}
|
|
159
|
-
const queryText = Object.entries(query)
|
|
160
|
-
.map(([name, value]) => `${encodeURIComponent(name)}=${encodeURIComponent(String(value))}`)
|
|
161
|
-
.join('&');
|
|
162
|
-
// Declared body, resolved exactly. `raw` resolves the fixture-named
|
|
163
|
-
// EXACT bytes from the trusted lease subjects — the signature (when a
|
|
164
|
-
// profile is declared) is computed engine-side over those exact bytes,
|
|
165
|
-
// never over a re-serialization.
|
|
166
|
-
let bodyFields = {};
|
|
167
|
-
let bodyText;
|
|
168
|
-
let contentType;
|
|
169
|
-
if (action.body.encoding === 'raw') {
|
|
170
|
-
const fixtureName = action.body.fixture;
|
|
171
|
-
if (typeof fixtureName !== 'string')
|
|
172
|
-
throw new BehaviorDriverError('raw body has no fixture reference');
|
|
173
|
-
const resolved = resolveValue({ from: 'fixture', key: fixtureName }, lease.subjects, 'raw body fixture');
|
|
174
|
-
if (typeof resolved !== 'string')
|
|
175
|
-
throw new BehaviorDriverError('raw body fixture is not exact bytes (string)');
|
|
176
|
-
bodyText = resolved;
|
|
177
|
-
contentType = 'application/json';
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
for (const [name, raw] of Object.entries(action.body.fields ?? {})) {
|
|
181
|
-
bodyFields[name] = resolveValue(raw, lease.subjects, `body field '${name}'`);
|
|
182
|
-
}
|
|
183
|
-
if (action.body.encoding === 'json') {
|
|
184
|
-
bodyText = JSON.stringify(bodyFields);
|
|
185
|
-
contentType = 'application/json';
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
bodyText = new URLSearchParams(Object.entries(bodyFields).map(([name, value]) => [name, typeof value === 'string' ? value : JSON.stringify(value)])).toString();
|
|
189
|
-
contentType = 'application/x-www-form-urlencoded';
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (bodyText.length > BEHAVIOR_BODY_LIMIT_BYTES) {
|
|
193
|
-
throw new BehaviorDriverError('request body exceeds the proof bound');
|
|
194
|
-
}
|
|
195
|
-
// Actor material resolves privately, engine-side only.
|
|
196
|
-
const headers = { 'content-type': contentType };
|
|
197
|
-
const actor = lease.actors[input.actorProfile];
|
|
198
|
-
if (actor === undefined) {
|
|
199
|
-
throw new BehaviorDriverError(`actor profile '${input.actorProfile}' has no lease`);
|
|
200
|
-
}
|
|
201
|
-
if (input.action.credentialVariant === 'valid' || input.action.credentialVariant === 'corrupted') {
|
|
202
|
-
const material = await input.resolveCredential(actor.credentialRef);
|
|
203
|
-
if (material === null)
|
|
204
|
-
throw new BehaviorDriverError('actor credential reference does not resolve');
|
|
205
|
-
if (input.action.credentialVariant === 'valid') {
|
|
206
|
-
for (const [name, value] of Object.entries(material.headers)) {
|
|
207
|
-
// The signing secret is consumed by the driver (never sent as a
|
|
208
|
-
// header); the signature is computed over the exact raw bytes.
|
|
209
|
-
if (name === 'x-gateforge-signing-secret')
|
|
210
|
-
continue;
|
|
211
|
-
headers[name] = value;
|
|
212
|
-
}
|
|
213
|
-
if (action.signatureProfile === 'hmac-sha256') {
|
|
214
|
-
const secret = material.headers['x-gateforge-signing-secret'];
|
|
215
|
-
if (secret === undefined)
|
|
216
|
-
throw new BehaviorDriverError('signing profile declared but no engine-side secret is bound');
|
|
217
|
-
headers['x-signature'] = createHmac('sha256', secret).update(bodyText, 'utf8').digest('hex');
|
|
218
|
-
headers['x-webhook-timestamp'] = String(Date.now());
|
|
219
|
-
headers['x-webhook-attempt'] = '1';
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
for (const [name, value] of Object.entries(material.headers)) {
|
|
224
|
-
if (name === 'x-gateforge-signing-secret')
|
|
225
|
-
continue;
|
|
226
|
-
headers[name] = value.length > 0 ? `${value.slice(0, -1)}X` : 'X';
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
const engineRequestId = randomUUID();
|
|
231
|
-
const controller = new AbortController();
|
|
232
|
-
const timer = setTimeout(() => controller.abort(), input.timeoutMs);
|
|
233
|
-
let response;
|
|
234
|
-
try {
|
|
235
|
-
response = await fetch(`${base}${path}${queryText.length > 0 ? `?${queryText}` : ''}`, {
|
|
236
|
-
method: action.method.toUpperCase(),
|
|
237
|
-
headers,
|
|
238
|
-
body: action.method.toUpperCase() === 'GET' || action.method.toUpperCase() === 'HEAD' ? undefined : bodyText,
|
|
239
|
-
signal: controller.signal,
|
|
240
|
-
// Never follow redirects: the observed status is the principal's
|
|
241
|
-
// own response (a form POST legitimately answers 303).
|
|
242
|
-
redirect: 'manual',
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
catch (error) {
|
|
246
|
-
throw new BehaviorDriverError(`principal request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
247
|
-
}
|
|
248
|
-
finally {
|
|
249
|
-
clearTimeout(timer);
|
|
250
|
-
}
|
|
251
|
-
const responseText = await readBoundedBody(response, BEHAVIOR_BODY_LIMIT_BYTES);
|
|
252
|
-
const responseBody = parseBody(responseText);
|
|
253
|
-
const bodyValue = action.body.encoding === 'raw'
|
|
254
|
-
? bodyText
|
|
255
|
-
: action.body.encoding === 'json'
|
|
256
|
-
? parseBody(bodyText)
|
|
257
|
-
: Object.fromEntries(new URLSearchParams(bodyText).entries());
|
|
258
|
-
const requestDigest = sha256Canonical({
|
|
259
|
-
method: action.method.toUpperCase(),
|
|
260
|
-
path,
|
|
261
|
-
query,
|
|
262
|
-
body: bodyValue,
|
|
263
|
-
});
|
|
264
|
-
const responseDigest = sha256Canonical({ status: response.status, body: responseBody });
|
|
265
|
-
return {
|
|
266
|
-
engineRequestId,
|
|
267
|
-
method: action.method.toUpperCase(),
|
|
268
|
-
path,
|
|
269
|
-
query,
|
|
270
|
-
body: bodyValue,
|
|
271
|
-
status: response.status,
|
|
272
|
-
responseBody,
|
|
273
|
-
requestDigest,
|
|
274
|
-
responseDigest,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
9
|
+
export * from '@gate-forge/witness/witness/behavior-request';
|
|
277
10
|
//# sourceMappingURL=behavior-request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior-request.js","sourceRoot":"","sources":["../../src/witness/behavior-request.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"behavior-request.js","sourceRoot":"","sources":["../../src/witness/behavior-request.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,8CAA8C,CAAC"}
|
|
@@ -1,52 +1,10 @@
|
|
|
1
|
-
/** What a snapshot was validated against. */
|
|
2
|
-
export interface SnapshotScopeSpec {
|
|
3
|
-
/** Approved snapshot scope key. */
|
|
4
|
-
scope: string;
|
|
5
|
-
/** Fixture namespace the case lease owns. */
|
|
6
|
-
fixtureNamespace: string;
|
|
7
|
-
/** Exact ordered identity columns (tenant included where needed). */
|
|
8
|
-
identityFields: string[];
|
|
9
|
-
/** Nonempty relevant field projection. */
|
|
10
|
-
fields: string[];
|
|
11
|
-
/** Hard entity cap (bounded memory). */
|
|
12
|
-
maxEntities?: number;
|
|
13
|
-
}
|
|
14
|
-
/** Default entity cap when the caller names none. */
|
|
15
|
-
export declare const DEFAULT_MAX_SNAPSHOT_ENTITIES = 10000;
|
|
16
|
-
/** Validated snapshot: entities indexed by canonical identity key. */
|
|
17
|
-
export interface ValidatedSnapshot {
|
|
18
|
-
/** The validated checkpoint. */
|
|
19
|
-
checkpoint: string;
|
|
20
|
-
/** Identity key → entity index (canonical order preserved). */
|
|
21
|
-
index: Map<string, {
|
|
22
|
-
entityId: unknown;
|
|
23
|
-
fields: Record<string, unknown>;
|
|
24
|
-
}>;
|
|
25
|
-
/** Identity keys in snapshot order. */
|
|
26
|
-
order: string[];
|
|
27
|
-
}
|
|
28
|
-
export type SnapshotValidation = {
|
|
29
|
-
ok: true;
|
|
30
|
-
snapshot: ValidatedSnapshot;
|
|
31
|
-
} | {
|
|
32
|
-
ok: false;
|
|
33
|
-
detail: string;
|
|
34
|
-
};
|
|
35
1
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* Missing identity columns are an unknown identity (null return).
|
|
39
|
-
*/
|
|
40
|
-
export declare function identityKeyOf(entityId: unknown, identityFields: string[]): string | null;
|
|
41
|
-
/**
|
|
42
|
-
* Validates one trusted scope snapshot against its declared spec.
|
|
43
|
-
*
|
|
44
|
-
* Args:
|
|
45
|
-
* snapshot: the adapter-produced snapshot (untrusted input).
|
|
46
|
-
* spec: the declared scope, namespace, identity, and projection.
|
|
2
|
+
* Compatibility re-export: `witness/behavior` now lives in the runner-neutral
|
|
3
|
+
* `@gate-forge/witness` package (plan 2026-09-25 phase 1).
|
|
47
4
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
5
|
+
* The move is physical, not behavioural: this module forwards every
|
|
6
|
+
* export unchanged so `@gate-forge/pack-playwright`'s published import
|
|
7
|
+
* paths — which consumers pin — keep resolving to the same values.
|
|
50
8
|
*/
|
|
51
|
-
export
|
|
9
|
+
export * from '@gate-forge/witness/witness/behavior';
|
|
52
10
|
//# sourceMappingURL=behavior.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior.d.ts","sourceRoot":"","sources":["../../src/witness/behavior.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"behavior.d.ts","sourceRoot":"","sources":["../../src/witness/behavior.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,sCAAsC,CAAC"}
|
package/dist/witness/behavior.js
CHANGED
|
@@ -1,118 +1,10 @@
|
|
|
1
|
-
/** Default entity cap when the caller names none. */
|
|
2
|
-
export const DEFAULT_MAX_SNAPSHOT_ENTITIES = 10_000;
|
|
3
|
-
/** True for plain data objects (never arrays, null, or class instances). */
|
|
4
|
-
function isRecord(value) {
|
|
5
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
6
|
-
return false;
|
|
7
|
-
const proto = Object.getPrototypeOf(value);
|
|
8
|
-
return proto === Object.prototype || proto === null;
|
|
9
|
-
}
|
|
10
1
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Missing identity columns are an unknown identity (null return).
|
|
14
|
-
*/
|
|
15
|
-
export function identityKeyOf(entityId, identityFields) {
|
|
16
|
-
if (entityId === null || entityId === undefined)
|
|
17
|
-
return null;
|
|
18
|
-
if (typeof entityId === 'string' || typeof entityId === 'number' || typeof entityId === 'boolean') {
|
|
19
|
-
return `${typeof entityId}:${String(entityId)}`;
|
|
20
|
-
}
|
|
21
|
-
if (!isRecord(entityId))
|
|
22
|
-
return null;
|
|
23
|
-
const parts = [];
|
|
24
|
-
for (const column of [...identityFields].sort()) {
|
|
25
|
-
const value = entityId[column];
|
|
26
|
-
if (value === undefined || value === null)
|
|
27
|
-
return null;
|
|
28
|
-
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean')
|
|
29
|
-
return null;
|
|
30
|
-
parts.push(`${column}=${typeof value}:${String(value)}`);
|
|
31
|
-
}
|
|
32
|
-
if (parts.length === 0)
|
|
33
|
-
return null;
|
|
34
|
-
return `composite:${parts.join('|')}`;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Validates one trusted scope snapshot against its declared spec.
|
|
38
|
-
*
|
|
39
|
-
* Args:
|
|
40
|
-
* snapshot: the adapter-produced snapshot (untrusted input).
|
|
41
|
-
* spec: the declared scope, namespace, identity, and projection.
|
|
2
|
+
* Compatibility re-export: `witness/behavior` now lives in the runner-neutral
|
|
3
|
+
* `@gate-forge/witness` package (plan 2026-09-25 phase 1).
|
|
42
4
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
5
|
+
* The move is physical, not behavioural: this module forwards every
|
|
6
|
+
* export unchanged so `@gate-forge/pack-playwright`'s published import
|
|
7
|
+
* paths — which consumers pin — keep resolving to the same values.
|
|
45
8
|
*/
|
|
46
|
-
export
|
|
47
|
-
const fail = (detail) => ({ ok: false, detail });
|
|
48
|
-
if (!isRecord(snapshot))
|
|
49
|
-
return fail('scope snapshot must be an object');
|
|
50
|
-
if (snapshot['scope'] !== spec.scope) {
|
|
51
|
-
return fail(`scope snapshot scope '${String(snapshot['scope'])}' does not match declared scope '${spec.scope}'`);
|
|
52
|
-
}
|
|
53
|
-
if (snapshot['fixtureNamespace'] !== spec.fixtureNamespace) {
|
|
54
|
-
return fail(`scope snapshot namespace '${String(snapshot['fixtureNamespace'])}' does not match the case lease namespace`);
|
|
55
|
-
}
|
|
56
|
-
if (snapshot['complete'] !== true) {
|
|
57
|
-
return fail(`scope '${spec.scope}' collection is incomplete (complete:false) — no partial credit`);
|
|
58
|
-
}
|
|
59
|
-
const checkpoint = snapshot['checkpoint'];
|
|
60
|
-
if (typeof checkpoint !== 'string' || checkpoint.length === 0) {
|
|
61
|
-
return fail(`scope '${spec.scope}' has no authoritative checkpoint`);
|
|
62
|
-
}
|
|
63
|
-
if (snapshot['exhausted'] !== true) {
|
|
64
|
-
return fail(`scope '${spec.scope}' pagination not exhausted — a one-page snapshot cannot prove the set`);
|
|
65
|
-
}
|
|
66
|
-
const entities = snapshot['entities'];
|
|
67
|
-
if (!Array.isArray(entities))
|
|
68
|
-
return fail(`scope '${spec.scope}' entities must be an array`);
|
|
69
|
-
const max = spec.maxEntities ?? DEFAULT_MAX_SNAPSHOT_ENTITIES;
|
|
70
|
-
if (entities.length > max) {
|
|
71
|
-
return fail(`scope '${spec.scope}' exceeds the entity bound (${String(entities.length)} > ${String(max)})`);
|
|
72
|
-
}
|
|
73
|
-
const totalSize = snapshot['totalSize'];
|
|
74
|
-
if (totalSize !== undefined) {
|
|
75
|
-
if (typeof totalSize !== 'number' || !Number.isInteger(totalSize) || totalSize < 0) {
|
|
76
|
-
return fail(`scope '${spec.scope}' totalSize must be a non-negative integer when present`);
|
|
77
|
-
}
|
|
78
|
-
if (entities.length !== totalSize) {
|
|
79
|
-
return fail(`scope '${spec.scope}' truncated (${String(entities.length)} of ${String(totalSize)}) — never silently sampled`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (spec.fields.length === 0)
|
|
83
|
-
return fail(`scope '${spec.scope}' declares an empty field projection`);
|
|
84
|
-
const index = new Map();
|
|
85
|
-
const order = [];
|
|
86
|
-
let previous = null;
|
|
87
|
-
for (let position = 0; position < entities.length; position += 1) {
|
|
88
|
-
const entity = entities[position];
|
|
89
|
-
if (!isRecord(entity))
|
|
90
|
-
return fail(`scope '${spec.scope}' entity ${String(position)} must be an object`);
|
|
91
|
-
const key = identityKeyOf(entity['entityId'], spec.identityFields);
|
|
92
|
-
if (key === null) {
|
|
93
|
-
return fail(`scope '${spec.scope}' entity ${String(position)} has unknown identity (fail closed)`);
|
|
94
|
-
}
|
|
95
|
-
if (index.has(key)) {
|
|
96
|
-
return fail(`scope '${spec.scope}' has a duplicate identity '${key}' — ambiguous, not proof`);
|
|
97
|
-
}
|
|
98
|
-
if (previous !== null && key <= previous) {
|
|
99
|
-
return fail(`scope '${spec.scope}' is not in canonical identity order ('${key}' after '${previous}')`);
|
|
100
|
-
}
|
|
101
|
-
previous = key;
|
|
102
|
-
const fields = entity['fields'];
|
|
103
|
-
if (!isRecord(fields))
|
|
104
|
-
return fail(`scope '${spec.scope}' entity ${String(position)} fields must be an object`);
|
|
105
|
-
for (const name of spec.fields) {
|
|
106
|
-
if (!(name in fields)) {
|
|
107
|
-
return fail(`scope '${spec.scope}' entity ${String(position)} omits declared field '${name}'`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const projected = {};
|
|
111
|
-
for (const [name, value] of Object.entries(fields))
|
|
112
|
-
projected[name] = value;
|
|
113
|
-
index.set(key, { entityId: entity['entityId'], fields: projected });
|
|
114
|
-
order.push(key);
|
|
115
|
-
}
|
|
116
|
-
return { ok: true, snapshot: { checkpoint, index, order } };
|
|
117
|
-
}
|
|
9
|
+
export * from '@gate-forge/witness/witness/behavior';
|
|
118
10
|
//# sourceMappingURL=behavior.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"behavior.js","sourceRoot":"","sources":["../../src/witness/behavior.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"behavior.js","sourceRoot":"","sources":["../../src/witness/behavior.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,sCAAsC,CAAC"}
|
package/dist/witness/bin.d.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
import type { WitnessHandle } from './types.js';
|
|
2
|
-
/** One-line usage (the header comment above is the long form). */
|
|
3
|
-
export declare const WITNESS_BIN_USAGE: string;
|
|
4
1
|
/**
|
|
5
|
-
*
|
|
2
|
+
* Compatibility re-export: `witness/bin` now lives in the runner-neutral
|
|
3
|
+
* `@gate-forge/witness` package (plan 2026-09-25 phase 1).
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* env: process environment.
|
|
11
|
-
*
|
|
12
|
-
* Returns:
|
|
13
|
-
* WitnessHandle once listening (or a handle with an empty `url` for
|
|
14
|
-
* `--help`; the wrapper skips its URL banner in that case).
|
|
15
|
-
*
|
|
16
|
-
* Throws:
|
|
17
|
-
* WitnessStartupError / AttestationError / AdapterRegistryError:
|
|
18
|
-
* fail-closed startup problems (exit 2 via the wrapper).
|
|
5
|
+
* The move is physical, not behavioural: this module forwards every
|
|
6
|
+
* export unchanged so `@gate-forge/pack-playwright`'s published import
|
|
7
|
+
* paths — which consumers pin — keep resolving to the same values.
|
|
19
8
|
*/
|
|
20
|
-
export
|
|
9
|
+
export * from '@gate-forge/witness/witness/bin';
|
|
21
10
|
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/witness/bin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/witness/bin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,iCAAiC,CAAC"}
|