@nodetool-ai/reliability-harness 0.8.1
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 +34 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/cli.d.ts +73 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +201 -0
- package/dist/cli.js.map +1 -0
- package/dist/compare.d.ts +98 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +267 -0
- package/dist/compare.js.map +1 -0
- package/dist/core/diff.d.ts +39 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/diff.js +114 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/golden.d.ts +50 -0
- package/dist/core/golden.d.ts.map +1 -0
- package/dist/core/golden.js +150 -0
- package/dist/core/golden.js.map +1 -0
- package/dist/core/invariants/index.d.ts +32 -0
- package/dist/core/invariants/index.d.ts.map +1 -0
- package/dist/core/invariants/index.js +44 -0
- package/dist/core/invariants/index.js.map +1 -0
- package/dist/core/invariants/leaks.d.ts +22 -0
- package/dist/core/invariants/leaks.d.ts.map +1 -0
- package/dist/core/invariants/leaks.js +55 -0
- package/dist/core/invariants/leaks.js.map +1 -0
- package/dist/core/invariants/lifecycle.d.ts +19 -0
- package/dist/core/invariants/lifecycle.d.ts.map +1 -0
- package/dist/core/invariants/lifecycle.js +95 -0
- package/dist/core/invariants/lifecycle.js.map +1 -0
- package/dist/core/invariants/protocol-validity.d.ts +4 -0
- package/dist/core/invariants/protocol-validity.d.ts.map +1 -0
- package/dist/core/invariants/protocol-validity.js +131 -0
- package/dist/core/invariants/protocol-validity.js.map +1 -0
- package/dist/core/invariants/state-machine.d.ts +29 -0
- package/dist/core/invariants/state-machine.d.ts.map +1 -0
- package/dist/core/invariants/state-machine.js +79 -0
- package/dist/core/invariants/state-machine.js.map +1 -0
- package/dist/core/invariants/status-sets.d.ts +27 -0
- package/dist/core/invariants/status-sets.d.ts.map +1 -0
- package/dist/core/invariants/status-sets.js +51 -0
- package/dist/core/invariants/status-sets.js.map +1 -0
- package/dist/core/invariants/terminal-uniqueness.d.ts +23 -0
- package/dist/core/invariants/terminal-uniqueness.d.ts.map +1 -0
- package/dist/core/invariants/terminal-uniqueness.js +99 -0
- package/dist/core/invariants/terminal-uniqueness.js.map +1 -0
- package/dist/core/invariants/types.d.ts +25 -0
- package/dist/core/invariants/types.d.ts.map +1 -0
- package/dist/core/invariants/types.js +2 -0
- package/dist/core/invariants/types.js.map +1 -0
- package/dist/core/journey.d.ts +121 -0
- package/dist/core/journey.d.ts.map +1 -0
- package/dist/core/journey.js +166 -0
- package/dist/core/journey.js.map +1 -0
- package/dist/core/normalize.d.ts +86 -0
- package/dist/core/normalize.d.ts.map +1 -0
- package/dist/core/normalize.js +182 -0
- package/dist/core/normalize.js.map +1 -0
- package/dist/core/record.d.ts +160 -0
- package/dist/core/record.d.ts.map +1 -0
- package/dist/core/record.js +74 -0
- package/dist/core/record.js.map +1 -0
- package/dist/core/stable-json.d.ts +13 -0
- package/dist/core/stable-json.d.ts.map +1 -0
- package/dist/core/stable-json.js +28 -0
- package/dist/core/stable-json.js.map +1 -0
- package/dist/drivers/anchors.d.ts +29 -0
- package/dist/drivers/anchors.d.ts.map +1 -0
- package/dist/drivers/anchors.js +48 -0
- package/dist/drivers/anchors.js.map +1 -0
- package/dist/drivers/app-headless.d.ts +39 -0
- package/dist/drivers/app-headless.d.ts.map +1 -0
- package/dist/drivers/app-headless.js +123 -0
- package/dist/drivers/app-headless.js.map +1 -0
- package/dist/drivers/browser.d.ts +34 -0
- package/dist/drivers/browser.d.ts.map +1 -0
- package/dist/drivers/browser.js +176 -0
- package/dist/drivers/browser.js.map +1 -0
- package/dist/drivers/cli.d.ts +13 -0
- package/dist/drivers/cli.d.ts.map +1 -0
- package/dist/drivers/cli.js +82 -0
- package/dist/drivers/cli.js.map +1 -0
- package/dist/drivers/fixture-nodes.d.ts +124 -0
- package/dist/drivers/fixture-nodes.d.ts.map +1 -0
- package/dist/drivers/fixture-nodes.js +189 -0
- package/dist/drivers/fixture-nodes.js.map +1 -0
- package/dist/drivers/index.d.ts +18 -0
- package/dist/drivers/index.d.ts.map +1 -0
- package/dist/drivers/index.js +12 -0
- package/dist/drivers/index.js.map +1 -0
- package/dist/drivers/kernel.d.ts +8 -0
- package/dist/drivers/kernel.d.ts.map +1 -0
- package/dist/drivers/kernel.js +247 -0
- package/dist/drivers/kernel.js.map +1 -0
- package/dist/drivers/packaged.d.ts +28 -0
- package/dist/drivers/packaged.d.ts.map +1 -0
- package/dist/drivers/packaged.js +303 -0
- package/dist/drivers/packaged.js.map +1 -0
- package/dist/drivers/python-bridge.d.ts +22 -0
- package/dist/drivers/python-bridge.d.ts.map +1 -0
- package/dist/drivers/python-bridge.js +48 -0
- package/dist/drivers/python-bridge.js.map +1 -0
- package/dist/drivers/registry.d.ts +11 -0
- package/dist/drivers/registry.d.ts.map +1 -0
- package/dist/drivers/registry.js +18 -0
- package/dist/drivers/registry.js.map +1 -0
- package/dist/drivers/relay-fields.d.ts +70 -0
- package/dist/drivers/relay-fields.d.ts.map +1 -0
- package/dist/drivers/relay-fields.js +104 -0
- package/dist/drivers/relay-fields.js.map +1 -0
- package/dist/drivers/repo-root.d.ts +9 -0
- package/dist/drivers/repo-root.d.ts.map +1 -0
- package/dist/drivers/repo-root.js +39 -0
- package/dist/drivers/repo-root.js.map +1 -0
- package/dist/drivers/spawn-cli.d.ts +8 -0
- package/dist/drivers/spawn-cli.d.ts.map +1 -0
- package/dist/drivers/spawn-cli.js +41 -0
- package/dist/drivers/spawn-cli.js.map +1 -0
- package/dist/drivers/types.d.ts +18 -0
- package/dist/drivers/types.d.ts.map +1 -0
- package/dist/drivers/types.js +2 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/drivers/ws-server.d.ts +8 -0
- package/dist/drivers/ws-server.d.ts.map +1 -0
- package/dist/drivers/ws-server.js +382 -0
- package/dist/drivers/ws-server.js.map +1 -0
- package/dist/faults/bridge-faults.d.ts +7 -0
- package/dist/faults/bridge-faults.d.ts.map +1 -0
- package/dist/faults/bridge-faults.js +90 -0
- package/dist/faults/bridge-faults.js.map +1 -0
- package/dist/faults/host-faults.d.ts +40 -0
- package/dist/faults/host-faults.d.ts.map +1 -0
- package/dist/faults/host-faults.js +70 -0
- package/dist/faults/host-faults.js.map +1 -0
- package/dist/faults/index.d.ts +21 -0
- package/dist/faults/index.d.ts.map +1 -0
- package/dist/faults/index.js +29 -0
- package/dist/faults/index.js.map +1 -0
- package/dist/faults/net-proxy.d.ts +75 -0
- package/dist/faults/net-proxy.d.ts.map +1 -0
- package/dist/faults/net-proxy.js +305 -0
- package/dist/faults/net-proxy.js.map +1 -0
- package/dist/faults/provider-faults.d.ts +12 -0
- package/dist/faults/provider-faults.d.ts.map +1 -0
- package/dist/faults/provider-faults.js +110 -0
- package/dist/faults/provider-faults.js.map +1 -0
- package/dist/faults/registry.d.ts +17 -0
- package/dist/faults/registry.d.ts.map +1 -0
- package/dist/faults/registry.js +15 -0
- package/dist/faults/registry.js.map +1 -0
- package/dist/faults/types.d.ts +42 -0
- package/dist/faults/types.d.ts.map +1 -0
- package/dist/faults/types.js +2 -0
- package/dist/faults/types.js.map +1 -0
- package/dist/faults/ws-faults.d.ts +6 -0
- package/dist/faults/ws-faults.d.ts.map +1 -0
- package/dist/faults/ws-faults.js +48 -0
- package/dist/faults/ws-faults.js.map +1 -0
- package/dist/faults/ws-proxy.d.ts +36 -0
- package/dist/faults/ws-proxy.d.ts.map +1 -0
- package/dist/faults/ws-proxy.js +40 -0
- package/dist/faults/ws-proxy.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo-root resolution shared by every C4 driver that speaks a real entry
|
|
3
|
+
* point instead of touching internals (§12: "drivers speak entry points,
|
|
4
|
+
* never internals — the kernel driver is the only one allowed to touch
|
|
5
|
+
* `ExecutionSession` directly"). Spawning the real `nodetool` CLI (and, for
|
|
6
|
+
* `browser.ts`, the real Playwright harness) is what keeps `cli.ts` and
|
|
7
|
+
* `app-headless.ts` from taking a static import on `@nodetool-ai/cli` — that
|
|
8
|
+
* package's own `reliability` command (C4 item 6) imports *this* package, so
|
|
9
|
+
* a static import the other way would be a circular workspace dependency.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
/** Walks up from this module to the checked-out repo root (the directory
|
|
15
|
+
* whose `packages/cli/src/nodetool.ts` exists) — works from both `src/`
|
|
16
|
+
* (ts-node/tsx dev) and `dist/` (built) locations since it only depends on
|
|
17
|
+
* directory depth, not file extension. */
|
|
18
|
+
export function findRepoRoot() {
|
|
19
|
+
const start = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
let dir = start;
|
|
21
|
+
for (let i = 0; i < 12; i++) {
|
|
22
|
+
if (existsSync(join(dir, "package.json")) &&
|
|
23
|
+
existsSync(join(dir, "packages", "cli", "src", "nodetool.ts"))) {
|
|
24
|
+
return dir;
|
|
25
|
+
}
|
|
26
|
+
const parent = dirname(dir);
|
|
27
|
+
if (parent === dir)
|
|
28
|
+
break;
|
|
29
|
+
dir = parent;
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`could not locate the nodetool repo root above ${start}`);
|
|
32
|
+
}
|
|
33
|
+
/** The workspace-hoisted `tsx` binary, falling back to a bare `tsx` for a
|
|
34
|
+
* shell to resolve if the root install ever changes shape. */
|
|
35
|
+
export function resolveTsxBin(repoRoot) {
|
|
36
|
+
const bin = join(repoRoot, "node_modules", ".bin", process.platform === "win32" ? "tsx.cmd" : "tsx");
|
|
37
|
+
return existsSync(bin) ? bin : "tsx";
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=repo-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-root.js","sourceRoot":"","sources":["../../src/drivers/repo-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;0CAG0C;AAC1C,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IACE,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAC9D,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,KAAK,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED;8DAC8D;AAC9D,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,GAAG,GAAG,IAAI,CACd,QAAQ,EACR,cAAc,EACd,MAAM,EACN,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CACjD,CAAC;IACF,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-cli.d.ts","sourceRoot":"","sources":["../../src/drivers/spawn-cli.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAgCvB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawns the real `nodetool` CLI against the checked-out source, via `tsx` —
|
|
3
|
+
* the same door a user gets (`npm run dev:nodetool -- <args>`), shared by
|
|
4
|
+
* `cli.ts` and `app-headless.ts`. No compiled `dist/` dependency, so it works
|
|
5
|
+
* in the same tree `npm run dev` does.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { findRepoRoot, resolveTsxBin } from "./repo-root.js";
|
|
10
|
+
export async function spawnNodetoolCli(args, timeoutMs) {
|
|
11
|
+
const repoRoot = findRepoRoot();
|
|
12
|
+
const tsxBin = resolveTsxBin(repoRoot);
|
|
13
|
+
const nodetoolEntry = join(repoRoot, "packages", "cli", "src", "nodetool.ts");
|
|
14
|
+
return new Promise((resolvePromise) => {
|
|
15
|
+
const child = spawn(tsxBin, [nodetoolEntry, ...args], {
|
|
16
|
+
cwd: repoRoot,
|
|
17
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
18
|
+
});
|
|
19
|
+
let stdout = "";
|
|
20
|
+
let stderr = "";
|
|
21
|
+
child.stdout.on("data", (buf) => (stdout += buf.toString()));
|
|
22
|
+
child.stderr.on("data", (buf) => (stderr += buf.toString()));
|
|
23
|
+
const timer = setTimeout(() => {
|
|
24
|
+
try {
|
|
25
|
+
child.kill("SIGKILL");
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Already exited.
|
|
29
|
+
}
|
|
30
|
+
}, timeoutMs);
|
|
31
|
+
child.on("exit", (code) => {
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
resolvePromise({ code: code ?? 1, stdout, stderr, repoRoot });
|
|
34
|
+
});
|
|
35
|
+
child.on("error", (err) => {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
resolvePromise({ code: 127, stdout, stderr: stderr + String(err), repoRoot });
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=spawn-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-cli.js","sourceRoot":"","sources":["../../src/drivers/spawn-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAS7D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAc,EACd,SAAiB;IAEjB,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAE9E,OAAO,IAAI,OAAO,CAAe,CAAC,cAAc,EAAE,EAAE;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,EAAE;YACpD,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACrE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAErE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,kBAAkB;YACpB,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The driver contract every execution surface implements (§12).
|
|
3
|
+
*
|
|
4
|
+
* A driver runs one loaded {@link Journey} to completion on its surface and
|
|
5
|
+
* returns a {@link RunRecord} — every frame, both directions, surface-tagged
|
|
6
|
+
* — so the same journey compares cleanly across surfaces via `normalize.ts`
|
|
7
|
+
* + `diff.ts`. C2 ships `kernel` (the oracle) and `ws-server`; C4 adds
|
|
8
|
+
* `cli`/`browser`/`app-headless`/`packaged` behind this same interface.
|
|
9
|
+
*/
|
|
10
|
+
import type { Journey } from "../core/journey.js";
|
|
11
|
+
import type { RunRecord } from "../core/record.js";
|
|
12
|
+
export interface RunDriver {
|
|
13
|
+
/** Matches `JourneySurface` (`core/journey.ts`) — e.g. "kernel", "ws-server". */
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** Runs `journey` to a terminal state on this surface and records every frame. */
|
|
16
|
+
run(journey: Journey): Promise<RunRecord>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/drivers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,SAAS;IACxB,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/drivers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Journey } from "../core/journey.js";
|
|
2
|
+
import { type RunRecord } from "../core/record.js";
|
|
3
|
+
import type { RunDriver } from "./types.js";
|
|
4
|
+
export declare class WsServerDriver implements RunDriver {
|
|
5
|
+
readonly name = "ws-server";
|
|
6
|
+
run(journey: Journey): Promise<RunRecord>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ws-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-server.d.ts","sourceRoot":"","sources":["../../src/drivers/ws-server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,OAAO,EAAsB,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAK3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoE5C,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,eAAe;IAEtB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAgV9C;CACF"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WS-server driver (§12) — starts the hermetic test backend
|
|
3
|
+
* (`createTestUiServer`, the helper `packages/websocket/src/e2e-server.ts`
|
|
4
|
+
* and the websocket test suite both build on) and drives it with a real
|
|
5
|
+
* msgpack `ws` client, exactly the wire protocol a real client speaks. Never
|
|
6
|
+
* constructs `ExecutionSession`/`WorkflowRunner` directly — the kernel
|
|
7
|
+
* driver (`kernel.ts`) is the only place allowed to do that (§12: "kernel
|
|
8
|
+
* surface is the oracle").
|
|
9
|
+
*
|
|
10
|
+
* Records both directions: outbound command envelopes as
|
|
11
|
+
* `client_to_server` frames, every inbound `ProcessingMessage` as
|
|
12
|
+
* `server_to_client` — the ws-server driver is the one surface where that
|
|
13
|
+
* distinction is real (the kernel driver has no wire).
|
|
14
|
+
*/
|
|
15
|
+
import { WebSocket } from "ws";
|
|
16
|
+
import { createTestUiServer, packWebSocketMessage, unpackWebSocketMessage } from "@nodetool-ai/websocket";
|
|
17
|
+
import { NodeRegistry } from "@nodetool-ai/node-sdk";
|
|
18
|
+
import { registerBaseNodes } from "@nodetool-ai/base-nodes";
|
|
19
|
+
import { resolvePythonNodeExecutor } from "@nodetool-ai/runtime";
|
|
20
|
+
import { makeFrame } from "../core/record.js";
|
|
21
|
+
import { AnchorWaiter } from "./anchors.js";
|
|
22
|
+
import { registerFixtureNodes } from "./fixture-nodes.js";
|
|
23
|
+
import { journeyPythonBridgeFactory } from "./python-bridge.js";
|
|
24
|
+
import { isConnectionControlMessage, stripRelayOnlyFields } from "./relay-fields.js";
|
|
25
|
+
import { maybeFrontWithProxy } from "../faults/ws-proxy.js";
|
|
26
|
+
const TERMINAL_JOB_STATUSES = new Set([
|
|
27
|
+
"completed",
|
|
28
|
+
"failed",
|
|
29
|
+
"cancelled",
|
|
30
|
+
"suspended"
|
|
31
|
+
]);
|
|
32
|
+
/** How long to let the server's post-disconnect cleanup settle before
|
|
33
|
+
* recording the slot counters as final. Cleanup is asynchronous (the runner
|
|
34
|
+
* finishes streaming, then frees the slot), so a snapshot taken the instant
|
|
35
|
+
* the socket closes would report a slot that is merely about to be freed. */
|
|
36
|
+
const SLOT_SETTLE_TIMEOUT_MS = 2000;
|
|
37
|
+
const SLOT_SETTLE_POLL_MS = 10;
|
|
38
|
+
/**
|
|
39
|
+
* Post-run WS slot accounting (§6 "Cleanup and leaks"), summed over every
|
|
40
|
+
* connection this run opened. Polls until both counters reach zero or the
|
|
41
|
+
* settle window elapses, then reports whatever it measured — a genuine leak
|
|
42
|
+
* survives the wait and is recorded as non-zero.
|
|
43
|
+
*/
|
|
44
|
+
async function settledSlotCounters(runners) {
|
|
45
|
+
const total = () => runners.reduce((acc, runner) => {
|
|
46
|
+
const slots = runner.jobs.slotCounters;
|
|
47
|
+
return {
|
|
48
|
+
activeJobs: acc.activeJobs + slots.activeJobs,
|
|
49
|
+
startingJobs: acc.startingJobs + slots.startingJobs
|
|
50
|
+
};
|
|
51
|
+
}, { activeJobs: 0, startingJobs: 0 });
|
|
52
|
+
const deadline = Date.now() + SLOT_SETTLE_TIMEOUT_MS;
|
|
53
|
+
let slots = total();
|
|
54
|
+
while ((slots.activeJobs > 0 || slots.startingJobs > 0) && Date.now() < deadline) {
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, SLOT_SETTLE_POLL_MS));
|
|
56
|
+
slots = total();
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
at: "after",
|
|
60
|
+
// Kernel-internal counters belong to the process the ws-server runs the
|
|
61
|
+
// kernel in; this driver reaches the server only over the wire, so it
|
|
62
|
+
// reports the accounting it can actually observe and leaves the rest at
|
|
63
|
+
// zero (the kernel driver is the surface that measures those).
|
|
64
|
+
liveActors: 0,
|
|
65
|
+
pendingControlResponses: 0,
|
|
66
|
+
pendingTimers: 0,
|
|
67
|
+
pythonBridgePendingRequests: 0,
|
|
68
|
+
...slots
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function requireJobId(jobId, journeyName, action) {
|
|
72
|
+
if (!jobId) {
|
|
73
|
+
throw new Error(`journey "${journeyName}": "${action}" interaction fired before a job_id was observed`);
|
|
74
|
+
}
|
|
75
|
+
return jobId;
|
|
76
|
+
}
|
|
77
|
+
export class WsServerDriver {
|
|
78
|
+
name = "ws-server";
|
|
79
|
+
async run(journey) {
|
|
80
|
+
// Task D3: mirror the kernel driver's Python-bridge wiring
|
|
81
|
+
// (`python-bridge.ts`) so journey 7 (`python-node-workflow`) behaves the
|
|
82
|
+
// same on both surfaces. `createTestUiServer`'s default `resolveExecutor`
|
|
83
|
+
// only ever calls `registry.resolve` — unlike `ExecutionSession`, it has
|
|
84
|
+
// no built-in bridge fallback — so this driver builds one itself: a
|
|
85
|
+
// throwaway registry (same real base nodes + harness fixtures the actual
|
|
86
|
+
// server registry ends up with, via `configureRegistry` below) just to
|
|
87
|
+
// answer "can the TS registry resolve this type", exactly the predicate
|
|
88
|
+
// `connectPythonBridgeForGraph` needs. A graph with no unresolved node
|
|
89
|
+
// type (every journey but #7) never spawns anything.
|
|
90
|
+
const bridgeCheckRegistry = new NodeRegistry();
|
|
91
|
+
registerBaseNodes(bridgeCheckRegistry);
|
|
92
|
+
registerFixtureNodes(bridgeCheckRegistry);
|
|
93
|
+
const workflowNodes = (journey.workflow.nodes ??
|
|
94
|
+
[]);
|
|
95
|
+
const bridge = await journeyPythonBridgeFactory(workflowNodes, (t) => bridgeCheckRegistry.has(t));
|
|
96
|
+
let liveRegistry = null;
|
|
97
|
+
// §6 "Cleanup and leaks" needs the server's own WS slot accounting, which
|
|
98
|
+
// lives on the per-connection runner. `createTestUiServer` builds one per
|
|
99
|
+
// upgrade and keeps it private; this hook is the only way to read it.
|
|
100
|
+
const runners = [];
|
|
101
|
+
const srv = createTestUiServer({
|
|
102
|
+
host: "127.0.0.1",
|
|
103
|
+
port: 0,
|
|
104
|
+
onRunnerCreated: (runner) => runners.push(runner),
|
|
105
|
+
configureRegistry: (registry) => {
|
|
106
|
+
registerFixtureNodes(registry);
|
|
107
|
+
liveRegistry = registry;
|
|
108
|
+
},
|
|
109
|
+
resolveExecutor: (node) => {
|
|
110
|
+
const registry = liveRegistry;
|
|
111
|
+
if (registry?.has(node.type))
|
|
112
|
+
return registry.resolve(node);
|
|
113
|
+
const pythonExecutor = resolvePythonNodeExecutor(bridge, node);
|
|
114
|
+
if (pythonExecutor)
|
|
115
|
+
return pythonExecutor;
|
|
116
|
+
// Falls through to the registry's own "Unknown node type" error —
|
|
117
|
+
// same failure shape a bridge-less run would produce.
|
|
118
|
+
return registry.resolve(node);
|
|
119
|
+
},
|
|
120
|
+
// Without this, `Graph.loadFromDict` (node-sdk) silently drops a
|
|
121
|
+
// bridge-only node type (and its edges) during hydration — it never
|
|
122
|
+
// even reaches `resolveExecutor` above, so a bridge CONNECT failure
|
|
123
|
+
// (never-ready/epipe/version-mismatch: `bridge` ends up `null`) would
|
|
124
|
+
// otherwise make the node vanish from the graph entirely instead of
|
|
125
|
+
// failing at execution the way the kernel driver's
|
|
126
|
+
// `hydrateGraphNodeFlags` does (it defaults metadata for ANY
|
|
127
|
+
// class-less node rather than dropping it — see that function's own
|
|
128
|
+
// doc comment). Mirrors that: bridge metadata when connected, a
|
|
129
|
+
// generic pass-through shape when not, so either way the node stays in
|
|
130
|
+
// the graph and the real failure surfaces later, at
|
|
131
|
+
// `resolveExecutor`/`execute()` — the same failure shape on both
|
|
132
|
+
// surfaces, just like the kernel driver.
|
|
133
|
+
resolveUnknownNodeType: async (nodeType) => {
|
|
134
|
+
const meta = bridge?.hasNodeType(nodeType)
|
|
135
|
+
? bridge.getNodeMetadata().find((m) => m.node_type === nodeType)
|
|
136
|
+
: undefined;
|
|
137
|
+
if (meta) {
|
|
138
|
+
return {
|
|
139
|
+
nodeType,
|
|
140
|
+
propertyTypes: Object.fromEntries(meta.properties.map((p) => [p.name, p.type.type])),
|
|
141
|
+
outputs: Object.fromEntries(meta.outputs.map((o) => [o.name, o.type.type])),
|
|
142
|
+
supportsDynamicInputs: false,
|
|
143
|
+
descriptorDefaults: {}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
nodeType,
|
|
148
|
+
propertyTypes: { value: "any" },
|
|
149
|
+
outputs: { out: "any" },
|
|
150
|
+
supportsDynamicInputs: true,
|
|
151
|
+
descriptorDefaults: {}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
await srv.listen();
|
|
156
|
+
const address = srv.server.address();
|
|
157
|
+
const serverPort = typeof address === "object" && address !== null ? address.port : 7777;
|
|
158
|
+
// Task D2: when a ws-* fault (`faults/ws-faults.ts`) is currently active,
|
|
159
|
+
// front the real server with a `WsFaultProxy` and connect this driver's
|
|
160
|
+
// client to the proxy instead — every ws-* fault applies transparently
|
|
161
|
+
// to this one client-connection code path below. `wsFrontEnd` stays
|
|
162
|
+
// `null` (the overwhelming majority of runs) when no ws fault is
|
|
163
|
+
// configured, in which case this is exactly the pre-D2 direct connection.
|
|
164
|
+
const wsFrontEnd = await maybeFrontWithProxy("127.0.0.1", serverPort);
|
|
165
|
+
const port = wsFrontEnd ? wsFrontEnd.port : serverPort;
|
|
166
|
+
const frames = [];
|
|
167
|
+
let counters = null;
|
|
168
|
+
let seq = 0;
|
|
169
|
+
const waiter = new AnchorWaiter();
|
|
170
|
+
let jobId = null;
|
|
171
|
+
let terminalStatus = null;
|
|
172
|
+
let terminalError = null;
|
|
173
|
+
// ws-server relays two `job_update`s per status the kernel driver only
|
|
174
|
+
// ever sees once: an eager "running" ack sent before the kernel's own
|
|
175
|
+
// relayed `job_update running` ("Authoritative SDK runs can use [the
|
|
176
|
+
// kernel's] update and avoid an otherwise duplicate WebSocket frame.
|
|
177
|
+
// Legacy clients keep the eager acknowledgement" —
|
|
178
|
+
// `websocket-client-session.ts`), and, for any non-"completed" terminal
|
|
179
|
+
// status, an "authoritative terminal snapshot" appended after the
|
|
180
|
+
// relayed one because the kernel's own terminal frame never carries a
|
|
181
|
+
// `result` field.
|
|
182
|
+
//
|
|
183
|
+
// Both are recorded, tagged `redundant` (see `RunFrame.redundant`) rather
|
|
184
|
+
// than dropped: dropping every repeat, as this driver used to, also drops
|
|
185
|
+
// the duplicates that would be real bugs, leaving "exactly one terminal
|
|
186
|
+
// job_update" with nothing to detect on the one surface that has a wire.
|
|
187
|
+
// The tag is narrow — a repeat only earns it by matching the documented
|
|
188
|
+
// shape below — so any other duplicate stays visible to the invariants
|
|
189
|
+
// and to the cross-surface diff.
|
|
190
|
+
const jobUpdateStatusCounts = new Map();
|
|
191
|
+
const taggedReasons = new Set();
|
|
192
|
+
let cancelRequested = false;
|
|
193
|
+
/** The reason tag for a repeated `job_update`, or undefined when this
|
|
194
|
+
* surface has no documented reason to have sent it twice. */
|
|
195
|
+
const documentedRedundancy = (status, message) => {
|
|
196
|
+
const claim = (reason) => {
|
|
197
|
+
// One repeat per documented reason. A third frame is not something
|
|
198
|
+
// the protocol documents, so it stays visible.
|
|
199
|
+
if (taggedReasons.has(reason))
|
|
200
|
+
return undefined;
|
|
201
|
+
taggedReasons.add(reason);
|
|
202
|
+
return reason;
|
|
203
|
+
};
|
|
204
|
+
if (status === "running")
|
|
205
|
+
return claim("ws-eager-running-ack");
|
|
206
|
+
if (TERMINAL_JOB_STATUSES.has(status) && "result" in message) {
|
|
207
|
+
return claim("ws-authoritative-terminal-snapshot");
|
|
208
|
+
}
|
|
209
|
+
// `cancel_job` is acknowledged with a `cancelled` job_update right away
|
|
210
|
+
// (`websocket-client-session.ts`'s cancel handler: "the runner's own
|
|
211
|
+
// cleanup can lag"), which the kernel's own relayed terminal then
|
|
212
|
+
// repeats. Only ever allowed for a cancel this driver actually asked
|
|
213
|
+
// for.
|
|
214
|
+
if (status === "cancelled" && cancelRequested) {
|
|
215
|
+
return claim("ws-eager-cancel-ack");
|
|
216
|
+
}
|
|
217
|
+
return undefined;
|
|
218
|
+
};
|
|
219
|
+
let resolveTerminal;
|
|
220
|
+
const terminalPromise = new Promise((resolve) => {
|
|
221
|
+
resolveTerminal = resolve;
|
|
222
|
+
});
|
|
223
|
+
const ws = new WebSocket(`ws://127.0.0.1:${port}/ws`);
|
|
224
|
+
ws.on("message", (data, isBinary) => {
|
|
225
|
+
const raw = (isBinary
|
|
226
|
+
? unpackWebSocketMessage(data)
|
|
227
|
+
: JSON.parse(data.toString("utf8")));
|
|
228
|
+
// This surface runs the same relay as `packaged.ts`, so it receives the
|
|
229
|
+
// same connection-scoped control frames on the same wall-clock timers.
|
|
230
|
+
if (isConnectionControlMessage(raw))
|
|
231
|
+
return;
|
|
232
|
+
const message = stripRelayOnlyFields(raw);
|
|
233
|
+
waiter.notify(message);
|
|
234
|
+
if (typeof message["job_id"] === "string") {
|
|
235
|
+
jobId = message["job_id"];
|
|
236
|
+
}
|
|
237
|
+
// Command acks (`{message: "Job started", ...}` for run_job/cancel_job/
|
|
238
|
+
// stream_input/end_input_stream) carry no `type` at all — they are not
|
|
239
|
+
// `ProcessingMessage`s, just a reply to the command envelope this
|
|
240
|
+
// driver already recorded as its own `client_to_server` frame. Not
|
|
241
|
+
// recording them keeps this surface's `server_to_client` frames
|
|
242
|
+
// apples-to-apples with the kernel driver's raw message stream.
|
|
243
|
+
if (typeof message["type"] !== "string")
|
|
244
|
+
return;
|
|
245
|
+
if (message["type"] === "job_update") {
|
|
246
|
+
const status = String(message["status"]);
|
|
247
|
+
const seenBefore = (jobUpdateStatusCounts.get(status) ?? 0) > 0;
|
|
248
|
+
jobUpdateStatusCounts.set(status, (jobUpdateStatusCounts.get(status) ?? 0) + 1);
|
|
249
|
+
const redundant = seenBefore
|
|
250
|
+
? documentedRedundancy(status, message)
|
|
251
|
+
: undefined;
|
|
252
|
+
const frame = makeFrame(seq++, "ws-server", "server_to_client", message);
|
|
253
|
+
frames.push(redundant === undefined ? frame : { ...frame, redundant });
|
|
254
|
+
if (!seenBefore && TERMINAL_JOB_STATUSES.has(status)) {
|
|
255
|
+
terminalStatus = status;
|
|
256
|
+
terminalError =
|
|
257
|
+
typeof message["error"] === "string" ? message["error"] : null;
|
|
258
|
+
resolveTerminal();
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
frames.push(makeFrame(seq++, "ws-server", "server_to_client", message));
|
|
263
|
+
});
|
|
264
|
+
await new Promise((resolve, reject) => {
|
|
265
|
+
ws.once("open", () => resolve());
|
|
266
|
+
ws.once("error", reject);
|
|
267
|
+
});
|
|
268
|
+
const send = (command, data) => {
|
|
269
|
+
const envelope = { command, data };
|
|
270
|
+
frames.push(makeFrame(seq++, "ws-server", "client_to_server", envelope));
|
|
271
|
+
ws.send(packWebSocketMessage(envelope));
|
|
272
|
+
};
|
|
273
|
+
try {
|
|
274
|
+
const interactions = journey.interactions.length > 0 ? journey.interactions : [{ action: "run" }];
|
|
275
|
+
for (const interaction of interactions) {
|
|
276
|
+
if (interaction.at) {
|
|
277
|
+
// Same race-free ordering rule as the kernel driver (anchors.ts):
|
|
278
|
+
// no `await` happens between a "run"'s `send()` and this wait, so
|
|
279
|
+
// the waiter is registered before the ws `message` handler (which
|
|
280
|
+
// runs on Node's event loop, not inline) can deliver the frame.
|
|
281
|
+
await waiter.wait(interaction.at);
|
|
282
|
+
}
|
|
283
|
+
switch (interaction.action) {
|
|
284
|
+
case "run":
|
|
285
|
+
send("run_job", {
|
|
286
|
+
graph: journey.workflow,
|
|
287
|
+
workflow_id: journey.manifest.name,
|
|
288
|
+
params: journey.manifest.params,
|
|
289
|
+
// Hermetic and driver-symmetric: the kernel driver never
|
|
290
|
+
// touches the jobs DB either, so neither surface depends on
|
|
291
|
+
// persistence to complete a journey. Deliberately NOT
|
|
292
|
+
// `require_terminal_result` — that also renames Output nodes'
|
|
293
|
+
// terminal keys to their public `properties.name`
|
|
294
|
+
// (`rewriteOutputNames`), which the kernel driver doesn't do
|
|
295
|
+
// either; every journey's `Output` nodes already carry an
|
|
296
|
+
// explicit top-level `name` so both surfaces agree without it.
|
|
297
|
+
execution_options: { persistence: "session" }
|
|
298
|
+
});
|
|
299
|
+
break;
|
|
300
|
+
case "cancel":
|
|
301
|
+
cancelRequested = true;
|
|
302
|
+
send("cancel_job", {
|
|
303
|
+
job_id: requireJobId(jobId, journey.manifest.name, "cancel")
|
|
304
|
+
});
|
|
305
|
+
break;
|
|
306
|
+
case "stream_input":
|
|
307
|
+
if (!interaction.nodeId) {
|
|
308
|
+
throw new Error(`journey "${journey.manifest.name}": "stream_input" interaction needs nodeId`);
|
|
309
|
+
}
|
|
310
|
+
send("stream_input", {
|
|
311
|
+
job_id: requireJobId(jobId, journey.manifest.name, "stream_input"),
|
|
312
|
+
input: interaction.nodeId,
|
|
313
|
+
value: interaction.value
|
|
314
|
+
});
|
|
315
|
+
break;
|
|
316
|
+
case "end_input_stream":
|
|
317
|
+
if (!interaction.nodeId) {
|
|
318
|
+
throw new Error(`journey "${journey.manifest.name}": "end_input_stream" interaction needs nodeId`);
|
|
319
|
+
}
|
|
320
|
+
send("end_input_stream", {
|
|
321
|
+
job_id: requireJobId(jobId, journey.manifest.name, "end_input_stream"),
|
|
322
|
+
input: interaction.nodeId
|
|
323
|
+
});
|
|
324
|
+
break;
|
|
325
|
+
case "reconnect":
|
|
326
|
+
throw new Error(`journey "${journey.manifest.name}": ws-server driver does not yet ` +
|
|
327
|
+
`support the "reconnect" interaction (C4)`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Task D2: a black-hole-style ws fault (`ws-drop-no-fin`,
|
|
331
|
+
// `ws-stall-reads`) can leave `terminalPromise` unresolved forever —
|
|
332
|
+
// the whole point of those faults is that no more frames arrive. §9's
|
|
333
|
+
// "no run hangs forever" applies to fault runs too, so race the wait
|
|
334
|
+
// against the journey's own declared timeout instead of adding one
|
|
335
|
+
// only for the happy path.
|
|
336
|
+
let timedOut = false;
|
|
337
|
+
let timeoutTimer;
|
|
338
|
+
await Promise.race([
|
|
339
|
+
terminalPromise,
|
|
340
|
+
new Promise((resolve) => {
|
|
341
|
+
timeoutTimer = setTimeout(() => {
|
|
342
|
+
timedOut = true;
|
|
343
|
+
resolve();
|
|
344
|
+
}, journey.manifest.timeoutMs);
|
|
345
|
+
})
|
|
346
|
+
]);
|
|
347
|
+
clearTimeout(timeoutTimer);
|
|
348
|
+
if (timedOut && terminalStatus === null) {
|
|
349
|
+
terminalStatus = "timeout";
|
|
350
|
+
terminalError =
|
|
351
|
+
`journey "${journey.manifest.name}": ws-server driver timed out after ` +
|
|
352
|
+
`${journey.manifest.timeoutMs}ms waiting for a terminal job_update`;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
finally {
|
|
356
|
+
// Leak accounting is measured after the connection is gone, not at the
|
|
357
|
+
// terminal frame: tearing the socket down is what ends a run whose
|
|
358
|
+
// client stopped hearing from the server at all (the black-hole ws
|
|
359
|
+
// faults), and the server's own cleanup runs on disconnect.
|
|
360
|
+
ws.close();
|
|
361
|
+
await wsFrontEnd?.close();
|
|
362
|
+
counters = await settledSlotCounters(runners);
|
|
363
|
+
await srv.close();
|
|
364
|
+
bridge?.close();
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
journeyId: journey.manifest.name,
|
|
368
|
+
surface: this.name,
|
|
369
|
+
jobId,
|
|
370
|
+
workflowId: journey.manifest.name,
|
|
371
|
+
startedAt: frames.length > 0 ? frames[0].ts : null,
|
|
372
|
+
finishedAt: frames.length > 0 ? frames[frames.length - 1].ts : null,
|
|
373
|
+
durationMs: null,
|
|
374
|
+
status: terminalStatus ?? "unknown",
|
|
375
|
+
error: terminalError,
|
|
376
|
+
params: journey.manifest.params,
|
|
377
|
+
frames,
|
|
378
|
+
resourceCounters: counters ? [counters] : []
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=ws-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-server.js","sourceRoot":"","sources":["../../src/drivers/ws-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FaultModule } from "./types.js";
|
|
2
|
+
export declare const BRIDGE_FAULT_MODULES: readonly FaultModule[];
|
|
3
|
+
/** Registers every bridge-seam fault module. Called once from
|
|
4
|
+
* `faults/index.ts`'s module-load side effect (task D1's "call once, own
|
|
5
|
+
* module state" contract) — safe to call again, last-write-wins. */
|
|
6
|
+
export declare function registerBridgeFaultModules(): void;
|
|
7
|
+
//# sourceMappingURL=bridge-faults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-faults.d.ts","sourceRoot":"","sources":["../../src/faults/bridge-faults.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAgB,WAAW,EAAiB,MAAM,YAAY,CAAC;AAgE3E,eAAO,MAAM,oBAAoB,EAAE,SAAS,WAAW,EAE3B,CAAC;AAE7B;;oEAEoE;AACpE,wBAAgB,0BAA0B,IAAI,IAAI,CAIjD"}
|