@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.
- package/LICENSE +202 -0
- package/bin/gateforge-witness.js +40 -0
- package/dist/attestation/proxy.d.ts +40 -0
- package/dist/attestation/proxy.d.ts.map +1 -0
- package/dist/attestation/proxy.js +78 -0
- package/dist/attestation/proxy.js.map +1 -0
- package/dist/constants.d.ts +130 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +138 -0
- package/dist/constants.js.map +1 -0
- package/dist/discovery/adapters.d.ts +167 -0
- package/dist/discovery/adapters.d.ts.map +1 -0
- package/dist/discovery/adapters.js +276 -0
- package/dist/discovery/adapters.js.map +1 -0
- package/dist/discovery/discover.d.ts +57 -0
- package/dist/discovery/discover.d.ts.map +1 -0
- package/dist/discovery/discover.js +544 -0
- package/dist/discovery/discover.js.map +1 -0
- package/dist/discovery/index.d.ts +15 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +15 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/inference.d.ts +63 -0
- package/dist/discovery/inference.d.ts.map +1 -0
- package/dist/discovery/inference.js +173 -0
- package/dist/discovery/inference.js.map +1 -0
- package/dist/discovery/pytest-adapter.d.ts +205 -0
- package/dist/discovery/pytest-adapter.d.ts.map +1 -0
- package/dist/discovery/pytest-adapter.js +548 -0
- package/dist/discovery/pytest-adapter.js.map +1 -0
- package/dist/discovery/reconcile.d.ts +106 -0
- package/dist/discovery/reconcile.d.ts.map +1 -0
- package/dist/discovery/reconcile.js +268 -0
- package/dist/discovery/reconcile.js.map +1 -0
- package/dist/discovery/runner-env.d.ts +80 -0
- package/dist/discovery/runner-env.d.ts.map +1 -0
- package/dist/discovery/runner-env.js +139 -0
- package/dist/discovery/runner-env.js.map +1 -0
- package/dist/discovery/static-discovery.d.ts +121 -0
- package/dist/discovery/static-discovery.d.ts.map +1 -0
- package/dist/discovery/static-discovery.js +1028 -0
- package/dist/discovery/static-discovery.js.map +1 -0
- package/dist/discovery/supervised-run.d.ts +110 -0
- package/dist/discovery/supervised-run.d.ts.map +1 -0
- package/dist/discovery/supervised-run.js +328 -0
- package/dist/discovery/supervised-run.js.map +1 -0
- package/dist/discovery/trusted-config.d.ts +103 -0
- package/dist/discovery/trusted-config.d.ts.map +1 -0
- package/dist/discovery/trusted-config.js +117 -0
- package/dist/discovery/trusted-config.js.map +1 -0
- package/dist/fixture/evidence.d.ts +191 -0
- package/dist/fixture/evidence.d.ts.map +1 -0
- package/dist/fixture/evidence.js +366 -0
- package/dist/fixture/evidence.js.map +1 -0
- package/dist/fixture/fixture.d.ts +37 -0
- package/dist/fixture/fixture.d.ts.map +1 -0
- package/dist/fixture/fixture.js +38 -0
- package/dist/fixture/fixture.js.map +1 -0
- package/dist/fixture/witness-client.d.ts +164 -0
- package/dist/fixture/witness-client.d.ts.map +1 -0
- package/dist/fixture/witness-client.js +253 -0
- package/dist/fixture/witness-client.js.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +16 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +21 -0
- package/dist/json.js.map +1 -0
- package/dist/reporter/ledger.d.ts +105 -0
- package/dist/reporter/ledger.d.ts.map +1 -0
- package/dist/reporter/ledger.js +197 -0
- package/dist/reporter/ledger.js.map +1 -0
- package/dist/reporter/reporter.cjs +105 -0
- package/dist/reporter/reporter.cjs.map +1 -0
- package/dist/reporter/reporter.d.cts +35 -0
- package/dist/reporter/reporter.d.cts.map +1 -0
- package/dist/reporter/reporter.d.ts +167 -0
- package/dist/reporter/reporter.d.ts.map +1 -0
- package/dist/reporter/reporter.js +673 -0
- package/dist/reporter/reporter.js.map +1 -0
- package/dist/setup.d.ts +49 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +167 -0
- package/dist/setup.js.map +1 -0
- package/dist/supervisor/client.d.ts +73 -0
- package/dist/supervisor/client.d.ts.map +1 -0
- package/dist/supervisor/client.js +164 -0
- package/dist/supervisor/client.js.map +1 -0
- package/dist/supervisor/drain.d.ts +45 -0
- package/dist/supervisor/drain.d.ts.map +1 -0
- package/dist/supervisor/drain.js +235 -0
- package/dist/supervisor/drain.js.map +1 -0
- package/dist/supervisor/index.d.ts +16 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +13 -0
- package/dist/supervisor/index.js.map +1 -0
- package/dist/supervisor/spool.d.ts +137 -0
- package/dist/supervisor/spool.d.ts.map +1 -0
- package/dist/supervisor/spool.js +263 -0
- package/dist/supervisor/spool.js.map +1 -0
- package/dist/surface.d.ts +134 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +139 -0
- package/dist/surface.js.map +1 -0
- package/dist/witness/adapter-registry.d.ts +38 -0
- package/dist/witness/adapter-registry.d.ts.map +1 -0
- package/dist/witness/adapter-registry.js +158 -0
- package/dist/witness/adapter-registry.js.map +1 -0
- package/dist/witness/bin.d.ts +21 -0
- package/dist/witness/bin.d.ts.map +1 -0
- package/dist/witness/bin.js +172 -0
- package/dist/witness/bin.js.map +1 -0
- package/dist/witness/browser.d.ts +173 -0
- package/dist/witness/browser.d.ts.map +1 -0
- package/dist/witness/browser.js +580 -0
- package/dist/witness/browser.js.map +1 -0
- package/dist/witness/classifications.d.ts +42 -0
- package/dist/witness/classifications.d.ts.map +1 -0
- package/dist/witness/classifications.js +87 -0
- package/dist/witness/classifications.js.map +1 -0
- package/dist/witness/env-attestation.d.ts +98 -0
- package/dist/witness/env-attestation.d.ts.map +1 -0
- package/dist/witness/env-attestation.js +202 -0
- package/dist/witness/env-attestation.js.map +1 -0
- package/dist/witness/loopback-pins.d.ts +79 -0
- package/dist/witness/loopback-pins.d.ts.map +1 -0
- package/dist/witness/loopback-pins.js +244 -0
- package/dist/witness/loopback-pins.js.map +1 -0
- package/dist/witness/server.d.ts +34 -0
- package/dist/witness/server.d.ts.map +1 -0
- package/dist/witness/server.js +2539 -0
- package/dist/witness/server.js.map +1 -0
- package/dist/witness/types.d.ts +643 -0
- package/dist/witness/types.d.ts.map +1 -0
- package/dist/witness/types.js +2 -0
- package/dist/witness/types.js.map +1 -0
- package/package.json +64 -0
- package/python/gateforge_persistence_intents.py +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-config.d.ts","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAMH,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AAEnE,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,GAAE,MAAwB,GAAG,MAAM,CAKjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,sBAAsB,CAAC;CACzC,CAyCA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trusted Playwright config synthesis (execution-authority fix): the
|
|
3
|
+
* supervised runner NEVER loads the consumer's `playwright.config.*`.
|
|
4
|
+
* That file is arbitrary code running in the runner MAIN process — the
|
|
5
|
+
* same process as the gateforge reporter — so a hostile config can
|
|
6
|
+
* write fabricated lifecycle spool events and a fabricated outcomes
|
|
7
|
+
* document, then exit 0 before any spec executes (the confirmed
|
|
8
|
+
* execution bypass). Instead the supervisor synthesizes a minimal
|
|
9
|
+
* trusted config into the excluded run-state dir and runs the runner
|
|
10
|
+
* with `--config <trusted>`:
|
|
11
|
+
*
|
|
12
|
+
* - test files: the exact repo-relative files the supervisor selected
|
|
13
|
+
* (from the planned expected set), or the runner default when the
|
|
14
|
+
* caller selected nothing;
|
|
15
|
+
* - projects: bare names carried as data (identity only — per-project
|
|
16
|
+
* code options are NOT honored);
|
|
17
|
+
* - reporter: the engine's own reporter entry forced by absolute path
|
|
18
|
+
* with run-state paths as CONSTRUCTOR OPTIONS (never env — worker
|
|
19
|
+
* processes must not learn the spool/outcomes locations);
|
|
20
|
+
* - workers: 1, fullyParallel: false (serial — one open session at a
|
|
21
|
+
* time, so a worker can never reach another test's open session);
|
|
22
|
+
* - retries: 0, forbidOnly: true (required retries are zero; `.only`
|
|
23
|
+
* in a required run is a runner-level error);
|
|
24
|
+
* - no globalSetup/globalTeardown, no webServer, no consumer reporters.
|
|
25
|
+
*
|
|
26
|
+
* Authority boundary after this fix:
|
|
27
|
+
* - TRUSTED: the CLI process, the witness process, and the runner MAIN
|
|
28
|
+
* process (Playwright native + synthesized config + engine reporter).
|
|
29
|
+
* - UNTRUSTED: worker processes (test files, helpers, page objects,
|
|
30
|
+
* and any code they import). Workers keep ONLY the witness URL + run
|
|
31
|
+
* token + app base in env — enough for the fixture, never enough to
|
|
32
|
+
* locate the spool or outcomes files.
|
|
33
|
+
* - Worker forgery of another test's lifecycle always collides with the
|
|
34
|
+
* genuine reporter events for that test; the drain records the
|
|
35
|
+
* collision and supervision fails the run closed.
|
|
36
|
+
*
|
|
37
|
+
* Compatibility limits (honest, not transparent):
|
|
38
|
+
* - consumer `globalSetup`/`globalTeardown` are NOT executed;
|
|
39
|
+
* - consumer reporters, `webServer`, per-project `use` options,
|
|
40
|
+
* `testDir`/`testIgnore` scoping, and sharding are NOT honored;
|
|
41
|
+
* - tests must be self-contained (app provided externally via the
|
|
42
|
+
* app-base env, as the fixture already requires).
|
|
43
|
+
*/
|
|
44
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
45
|
+
import { join } from 'node:path';
|
|
46
|
+
import { fileURLToPath } from 'node:url';
|
|
47
|
+
/** File name of the synthesized trusted config inside the run-state dir. */
|
|
48
|
+
export const TRUSTED_CONFIG_FILE = 'trusted.playwright.config.mjs';
|
|
49
|
+
/** File name of the forced reporter options (diagnostic mirror of argv). */
|
|
50
|
+
export const TRUSTED_REPORTER_OPTIONS_FILE = 'trusted-reporter-options.json';
|
|
51
|
+
/**
|
|
52
|
+
* Resolves the engine reporter entry the trusted config forces: the
|
|
53
|
+
* pack's own BUILT reporter (the same class the consumer config would
|
|
54
|
+
* reference by package name). Never a repo-relative path — the entry
|
|
55
|
+
* must be engine-owned, never candidate-controlled.
|
|
56
|
+
*
|
|
57
|
+
* Args:
|
|
58
|
+
* fromModule: module URL to resolve the pack from (default: this file).
|
|
59
|
+
*
|
|
60
|
+
* Returns:
|
|
61
|
+
* string: absolute `<pack>/dist/reporter/reporter.js` path.
|
|
62
|
+
*/
|
|
63
|
+
export function trustedReporterEntry(fromModule = import.meta.url) {
|
|
64
|
+
// Package-root relative (works for both src/ and dist/ layouts — the
|
|
65
|
+
// package.json subpath is not in `exports`, so no self-name resolve).
|
|
66
|
+
const pkgPath = fileURLToPath(new URL('../../package.json', fromModule));
|
|
67
|
+
return join(pkgPath.slice(0, -'package.json'.length), 'dist', 'reporter', 'reporter.js');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Synthesizes the trusted Playwright config into the run-state dir.
|
|
71
|
+
*
|
|
72
|
+
* Args:
|
|
73
|
+
* input: repo root, run state, reporter entry, file/project selection.
|
|
74
|
+
*
|
|
75
|
+
* Returns:
|
|
76
|
+
* { configPath, reporterOptions }: absolute config path for
|
|
77
|
+
* `--config`, plus the reporter options embedded in it.
|
|
78
|
+
*/
|
|
79
|
+
export function synthesizeTrustedConfig(input) {
|
|
80
|
+
const reporterOptions = {
|
|
81
|
+
stateDir: input.stateDir,
|
|
82
|
+
runId: input.runId,
|
|
83
|
+
outcomesPath: join(input.stateDir, 'runner-outcomes.json'),
|
|
84
|
+
obligationsPath: join(input.stateDir, 'obligations.json'),
|
|
85
|
+
};
|
|
86
|
+
const testFiles = [...new Set(input.testFiles ?? [])].sort();
|
|
87
|
+
const projects = [...new Set(input.projects ?? [])].sort();
|
|
88
|
+
const lines = [
|
|
89
|
+
'// GENERATED by gateforge trusted supervision — do not edit. The',
|
|
90
|
+
'// consumer config file is NEVER loaded for supervised runs: it is',
|
|
91
|
+
'// arbitrary main-process code that could fabricate the lifecycle',
|
|
92
|
+
'// spool and outcomes document this reporter writes.',
|
|
93
|
+
'export default {',
|
|
94
|
+
` testDir: ${JSON.stringify(input.cwd)},`,
|
|
95
|
+
...(testFiles.length > 0 ? [` testMatch: ${JSON.stringify(testFiles)},`] : []),
|
|
96
|
+
...(projects.length > 0 ? [` projects: ${JSON.stringify(projects.map((name) => ({ name })))},`] : []),
|
|
97
|
+
' workers: 1,',
|
|
98
|
+
' fullyParallel: false,',
|
|
99
|
+
' retries: 0,',
|
|
100
|
+
' forbidOnly: true,',
|
|
101
|
+
` timeout: ${String(input.testTimeoutMs ?? 60_000)},`,
|
|
102
|
+
' reporter: [',
|
|
103
|
+
" ['list'],",
|
|
104
|
+
` [${JSON.stringify(input.reporterEntry)}, ${JSON.stringify(reporterOptions)}],`,
|
|
105
|
+
' ],',
|
|
106
|
+
' use: { headless: true, trace: "off" },',
|
|
107
|
+
` outputDir: ${JSON.stringify(join(input.stateDir, 'playwright-artifacts'))},`,
|
|
108
|
+
'};',
|
|
109
|
+
'',
|
|
110
|
+
];
|
|
111
|
+
mkdirSync(input.stateDir, { recursive: true });
|
|
112
|
+
const configPath = join(input.stateDir, TRUSTED_CONFIG_FILE);
|
|
113
|
+
writeFileSync(configPath, `${lines.join('\n')}`, 'utf8');
|
|
114
|
+
writeFileSync(join(input.stateDir, TRUSTED_REPORTER_OPTIONS_FILE), `${JSON.stringify({ configPath, reporterEntry: input.reporterEntry, reporterOptions, testFiles, projects }, null, 2)}\n`, 'utf8');
|
|
115
|
+
return { configPath, reporterOptions };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=trusted-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-config.js","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trusted evidence primitives (plan §5.3, invariant 6, GF-22; engine-
|
|
3
|
+
* browser rewrite per plan Phase 1 item 4).
|
|
4
|
+
*
|
|
5
|
+
* The fixture exposes EXACTLY five surfaces — `ui`, `visible`,
|
|
6
|
+
* `persistence`, `http`, `finalize` — on a frozen object with a
|
|
7
|
+
* closure-private record list. It is APPLICATION-INDEPENDENT: the pack
|
|
8
|
+
* carries no Accounts strings, no product selectors, and no route
|
|
9
|
+
* knowledge. The CONSUMER supplies a declarative {@link SurfaceDescriptor}
|
|
10
|
+
* (list page, row/field selectors, form templates, archive control,
|
|
11
|
+
* status values) — the Accounts description lives in the example tree
|
|
12
|
+
* (`example/e2e/accounts-surface.js`), not here.
|
|
13
|
+
*
|
|
14
|
+
* ENGINE-OWNED BROWSER (plan Phase 1 item 4): the `ui.*` primitives no
|
|
15
|
+
* longer drive a worker-side page. They register the consumer surface
|
|
16
|
+
* with the witness and ask the ENGINE to perform each constrained
|
|
17
|
+
* operation on its own page (`POST /browser/action`), then to re-read
|
|
18
|
+
* the rendered result (`POST /browser/visible`). Test code supplies
|
|
19
|
+
* INTENT (fields, entity id, claims) only — it never touches the engine
|
|
20
|
+
* page, so it cannot manufacture DOM state, intercept the application
|
|
21
|
+
* response, or substitute script/API effects and receive browser
|
|
22
|
+
* credit. Every `ui.action` / `ui.visible-result` record the gate
|
|
23
|
+
* grades is issued engine-side with origin `engine-observed`;
|
|
24
|
+
* suite-submitted UI records never satisfy browser contracts.
|
|
25
|
+
*
|
|
26
|
+
* For create/update the action record's `fields` are the ENTERED input
|
|
27
|
+
* the engine typed (plan §3.6 exact-value echo): the engine
|
|
28
|
+
* echo-checks them against the independently fetched persisted fields,
|
|
29
|
+
* and a mismatch fails the obligation with `EVIDENCE_VALUE_MISMATCH`
|
|
30
|
+
* even when the status was 2xx.
|
|
31
|
+
*
|
|
32
|
+
* Receipts returned by UI primitives are frozen and branded with a
|
|
33
|
+
* per-instance symbol — `visible.confirm`/`persistence.verify` reject
|
|
34
|
+
* anything without the own-property brand (GF-22: hand-rolled or
|
|
35
|
+
* `Object.create`-branded forgeries fail closed).
|
|
36
|
+
*
|
|
37
|
+
* Every engine call runs under the SUPERVISOR-ISSUED test session. The
|
|
38
|
+
* trusted reporter opens one session per started test (`runId,
|
|
39
|
+
* sessionId, testId, worker`) and the fixture resolves it by the exact
|
|
40
|
+
* (workerIndex, testId) pair; a suite-supplied testId or annotation
|
|
41
|
+
* alone cannot mint records for an arbitrary session, because the
|
|
42
|
+
* witness rejects submissions without a valid OPEN session and forces
|
|
43
|
+
* the record's testId onto the session's supervisor-registered value.
|
|
44
|
+
* Sealing (test end) rejects all late submissions and closes the
|
|
45
|
+
* session's engine browser context.
|
|
46
|
+
*/
|
|
47
|
+
import type { Page, TestInfo } from 'playwright/test';
|
|
48
|
+
import { SURFACE_DESCRIPTOR_VERSION, type SurfaceDescriptor } from '../surface.js';
|
|
49
|
+
import type { SessionCredential } from '../witness/types.js';
|
|
50
|
+
import { WitnessClient } from './witness-client.js';
|
|
51
|
+
export { SURFACE_DESCRIPTOR_VERSION, type SurfaceDescriptor };
|
|
52
|
+
/** A UI-action receipt: the ONLY token `visible`/`persistence` accept. */
|
|
53
|
+
export interface Receipt {
|
|
54
|
+
readonly kind: 'ui';
|
|
55
|
+
readonly operation: 'create' | 'read' | 'update' | 'delete';
|
|
56
|
+
readonly resourceId: string;
|
|
57
|
+
readonly entityId: string;
|
|
58
|
+
readonly fields: Record<string, string>;
|
|
59
|
+
readonly mode: 'row' | 'form';
|
|
60
|
+
/**
|
|
61
|
+
* Create/update only: the engine-side pre-observation taken BEFORE the
|
|
62
|
+
* UI action, bound into the persistence record so the engine can
|
|
63
|
+
* verify the before/after delta (create postcondition, audit round 4).
|
|
64
|
+
*/
|
|
65
|
+
readonly preObservationId?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Outcome of `persistence.verify` (verdict-relevant, witness-issued). */
|
|
68
|
+
export interface PersistenceOutcome {
|
|
69
|
+
recordId: string;
|
|
70
|
+
runId: string;
|
|
71
|
+
verdictRelevant: {
|
|
72
|
+
found: boolean;
|
|
73
|
+
fieldsMatch: boolean;
|
|
74
|
+
mismatches?: string[];
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** The frozen, no-escape-hatch evidence surface. */
|
|
78
|
+
export interface EvidenceApi {
|
|
79
|
+
readonly ui: Readonly<{
|
|
80
|
+
/**
|
|
81
|
+
* The ENGINE drives the rendered create form with the DECLARED input
|
|
82
|
+
* fields (plan §3.6: the journey's entered values are what the
|
|
83
|
+
* engine echo-checks against the persisted state).
|
|
84
|
+
*/
|
|
85
|
+
create(input: {
|
|
86
|
+
fields: Record<string, string>;
|
|
87
|
+
}): Promise<Receipt>;
|
|
88
|
+
read(input: {
|
|
89
|
+
entityId: string;
|
|
90
|
+
}): Promise<Receipt>;
|
|
91
|
+
update(input: {
|
|
92
|
+
entityId: string;
|
|
93
|
+
fields: Record<string, string>;
|
|
94
|
+
}): Promise<Receipt>;
|
|
95
|
+
archive(input: {
|
|
96
|
+
entityId: string;
|
|
97
|
+
}): Promise<Receipt>;
|
|
98
|
+
}>;
|
|
99
|
+
readonly visible: Readonly<{
|
|
100
|
+
confirm(receipt: Receipt): Promise<{
|
|
101
|
+
entityId: string;
|
|
102
|
+
fields: Record<string, string>;
|
|
103
|
+
}>;
|
|
104
|
+
}>;
|
|
105
|
+
readonly persistence: Readonly<{
|
|
106
|
+
verify(receipt: Receipt): Promise<PersistenceOutcome>;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* ADR 0004 D7 (plan §8 / D1): consumes one witness-observed HTTP
|
|
110
|
+
* exchange for an http:* claim. Only an exchange the ENGINE captured
|
|
111
|
+
* during its own action interval can be consumed — a request supplied
|
|
112
|
+
* by another test/worker (or by setup traffic outside every interval)
|
|
113
|
+
* is never credited. Pass an explicit `obligationId` when the test
|
|
114
|
+
* declares more than one claim — omitted selection with several
|
|
115
|
+
* candidates throws instead of silently binding the first claim.
|
|
116
|
+
*/
|
|
117
|
+
http: Readonly<{
|
|
118
|
+
observe(request: {
|
|
119
|
+
method: string;
|
|
120
|
+
path: string;
|
|
121
|
+
expectedStatus?: number;
|
|
122
|
+
obligationId?: string;
|
|
123
|
+
}): Promise<{
|
|
124
|
+
status: number;
|
|
125
|
+
recordId: string;
|
|
126
|
+
recordIds: string[];
|
|
127
|
+
}>;
|
|
128
|
+
}>;
|
|
129
|
+
finalize(): Promise<{
|
|
130
|
+
claims: string[];
|
|
131
|
+
records: WitnessRecord[];
|
|
132
|
+
}>;
|
|
133
|
+
}
|
|
134
|
+
/** One witness-issued record as the finalize ledger reports it. */
|
|
135
|
+
export interface WitnessRecord {
|
|
136
|
+
recordId: string;
|
|
137
|
+
runId: string;
|
|
138
|
+
obligationId: string;
|
|
139
|
+
kind: string;
|
|
140
|
+
payload: unknown;
|
|
141
|
+
}
|
|
142
|
+
/** Claims from the test annotations (`{type: 'gateforge', description}`). */
|
|
143
|
+
export declare function claimsFromAnnotations(annotations: readonly {
|
|
144
|
+
type: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
}[]): string[];
|
|
147
|
+
/** Splits `<resourceId>:<contract>` at the first colon. */
|
|
148
|
+
export declare function resourceIdOfClaim(claim: string): string;
|
|
149
|
+
/**
|
|
150
|
+
* Creates the evidence API for one test.
|
|
151
|
+
*
|
|
152
|
+
* Args:
|
|
153
|
+
* page: IGNORED for evidence (kept for call-shape compatibility) —
|
|
154
|
+
* the engine drives its own page; the worker page is never an
|
|
155
|
+
* evidence channel.
|
|
156
|
+
* testInfo: the running test's info (annotations, testId, workerIndex).
|
|
157
|
+
* surface: REQUIRED consumer-declared {@link SurfaceDescriptor} — the
|
|
158
|
+
* pack carries no application-specific selectors (plan Phase 1
|
|
159
|
+
* item 7). Registered with the witness; the ENGINE drives it
|
|
160
|
+
* against the provisioned attested subject (fake-frontend fix:
|
|
161
|
+
* the driven origin comes from trusted witness configuration,
|
|
162
|
+
* never from suite input — there is no app-base parameter here
|
|
163
|
+
* by design).
|
|
164
|
+
* client: witness transport override (tests inject their own).
|
|
165
|
+
* session: pre-resolved session credential (harnesses that opened the
|
|
166
|
+
* session themselves); default resolves it from the supervisor
|
|
167
|
+
* channel. A credential whose testId differs from this test's is
|
|
168
|
+
* refused.
|
|
169
|
+
* sessionResolveTimeoutMs: bounded wait for the supervisor's session
|
|
170
|
+
* open (harness tuning; default 5s).
|
|
171
|
+
*
|
|
172
|
+
* Returns:
|
|
173
|
+
* Promise<EvidenceApi>: the frozen primitive surface.
|
|
174
|
+
*
|
|
175
|
+
* Throws:
|
|
176
|
+
* Error: on a missing/outdated surface descriptor (migration error
|
|
177
|
+
* naming the new required `surface` parameter), when the test
|
|
178
|
+
* declares no gateforge claim and its session carries no
|
|
179
|
+
* supervisor-registered (mapped) claims, when no app base or witness
|
|
180
|
+
* or OPEN session is wired, or when an action/verification fails
|
|
181
|
+
* fail-closed.
|
|
182
|
+
*/
|
|
183
|
+
export declare function createEvidence({ page, testInfo, surface, client, session, sessionResolveTimeoutMs, }: {
|
|
184
|
+
page?: Page;
|
|
185
|
+
testInfo: TestInfo;
|
|
186
|
+
surface?: SurfaceDescriptor;
|
|
187
|
+
client?: WitnessClient;
|
|
188
|
+
session?: SessionCredential;
|
|
189
|
+
sessionResolveTimeoutMs?: number;
|
|
190
|
+
}): Promise<EvidenceApi>;
|
|
191
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/fixture/evidence.ts"],"names":[],"mappings":"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"}
|