@descryy/runtime-contracts 0.0.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.
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Execution contract.
3
+ *
4
+ * Field list and lifecycle states are verbatim from
5
+ * `documents/descry-runtime-plan.md` §4 (Execution model). Also grounded in
6
+ * the architecture doc's §16 (RVE boot sequence — oracle extraction,
7
+ * environment selection, boot, graph-aware seeding, snapshot, ready; §16.4's
8
+ * "SETUP FAILURE surfaced immediately, tagged distinctly from a test
9
+ * failure" is the direct source of FAILED_START as a state separate from
10
+ * FAILED) and §10.3 (environment tiers, referenced via
11
+ * ExecutionConfiguration.environmentTier from capability.ts).
12
+ *
13
+ * An Execution record holds *references* (event/trace/failure/correlation/
14
+ * finding IDs), never inlines the records themselves — mirrors §18.2's
15
+ * storage rule ("referenced by ID, never inlined") so a long-running
16
+ * execution doesn't grow this record unboundedly.
17
+ */
18
+ import type { EnvironmentTier, FidelityLevel } from "./capability.ts";
19
+ export declare const EXECUTION_STATES: readonly ["CREATED", "STARTING", "READY", "RUNNING", "STOPPING", "COMPLETED", "FAILED_START", "FAILED", "TIMED_OUT", "CANCELLED"];
20
+ export type ExecutionState = (typeof EXECUTION_STATES)[number];
21
+ export declare function isValidExecutionTransition(from: ExecutionState, to: ExecutionState): boolean;
22
+ export declare function isTerminalExecutionState(state: ExecutionState): boolean;
23
+ /**
24
+ * One named service from plan §6's `services` map
25
+ * (`name → {command, cwd, port}`). `port` is an **explicit opt-in** to a
26
+ * fixed port — absent (the default, and the recommended default) means the
27
+ * service is spawned on an OS-assigned ephemeral port, the mitigation
28
+ * RT-024 recommends for the readiness liveness-vs-identity gap: nothing
29
+ * else can already be bound to a port nobody requested, so a stale listener
30
+ * from a dead session can't be mistaken for this run's process by
31
+ * construction, not by convention. A collector recovers `cwd` for a given
32
+ * running process by joining `ProcessHandle.serviceName` back to this map
33
+ * (RT-023's browser script-URL → source mapping).
34
+ */
35
+ export interface ServiceConfiguration {
36
+ /**
37
+ * Required unless `attach` is set — exactly one of `command`/`attach`
38
+ * must be present (`validateServicesConfiguration` refuses atomically,
39
+ * before anything spawns, if a service declares neither or both).
40
+ */
41
+ readonly command?: string;
42
+ readonly cwd: string;
43
+ /** Explicit opt-in only. Omit to get an ephemeral port (RT-024's default). Attach-mode services should set this when the caller already knows what port the already-running target bound — nothing here can allocate one on their behalf, since the target is already listening. */
44
+ readonly port?: number;
45
+ /**
46
+ * Services (by key into this same `services` map) that must be spawned
47
+ * and ready before this one starts. **Declared, never inferred** (RT-032)
48
+ * — an orchestrator refuses rather than guesses at start order from env
49
+ * references or any other implicit signal.
50
+ */
51
+ readonly dependsOn?: readonly string[];
52
+ /**
53
+ * Extra environment for this service. A value may contain
54
+ * `${<name>.port}`, substituted with the actual resolved port of the
55
+ * named dependency once it has started — `name` must appear in this
56
+ * service's own `dependsOn`, or an orchestrator refuses rather than spawn
57
+ * with an unresolved placeholder (RT-032).
58
+ */
59
+ readonly env?: Readonly<Record<string, string>>;
60
+ /**
61
+ * Alternative to `command`: attach to a process that is already running
62
+ * instead of spawning a new one. RT-attach-to-running-process-scope.md's
63
+ * candidate (a) — the target's own pid, and a file its stdout/stderr is
64
+ * already redirected to (e.g. `npm run dev > server.log 2>&1 &`). Not
65
+ * generic "attach by base URL" — that remains out of scope, unchanged
66
+ * (see that same decision file).
67
+ *
68
+ * When set, `ExecutionController.run()` calls
69
+ * `attachManagedProcess`/`isProcessAlive` (`@descryy/runtime-controller`)
70
+ * instead of `spawnProcess` for this service. `resourceLimits`/
71
+ * `filesystemPolicy`/`networkPolicy` on `ExecutionConfiguration` are never
72
+ * applied to an attached service — Descry did not spawn it and, per
73
+ * `ATTACH_MODE_SCOPE_DISCLOSURE`, never executes code in or applies
74
+ * changes to a process it merely observes. The resulting `ManagedProcess`'s
75
+ * `kill()` is correspondingly a no-op: cleanup must not terminate a
76
+ * process this runtime does not own.
77
+ */
78
+ readonly attach?: ServiceAttachConfiguration;
79
+ }
80
+ /** See `ServiceConfiguration.attach`. */
81
+ export interface ServiceAttachConfiguration {
82
+ /** pid of the already-running target. Verified alive before attach is attempted, and re-checked on every poll to detect exit (never signalled by this runtime — see `ServiceConfiguration.attach`'s own comment on `kill()`). */
83
+ readonly pid: number;
84
+ /** Path to a file the target is already writing its stdout/stderr to. Read in full on every poll, same growing-buffer contract `ManagedProcess.readOutput()` already has for a spawned process — not a delta. */
85
+ readonly logFilePath: string;
86
+ }
87
+ /**
88
+ * §2's "browser options are constructor args, not configuration" gap
89
+ * (RT-068): before this, `launchBrowserSession`'s `BrowserSessionOptions`
90
+ * was a shape only a direct caller could reach, with no path from a
91
+ * declared `ExecutionConfiguration` at all -- every other launch input on
92
+ * this interface (`services`, ports, env, readiness) had that path and this
93
+ * one didn't. Deliberately just `headless` -- the one option that already
94
+ * existed as a constructor arg. Inventing viewport/locale/userAgent fields
95
+ * nothing reads yet would repeat RT-053's lesson about a declared-but-dead
96
+ * type, one layer up.
97
+ */
98
+ export interface BrowserConfiguration {
99
+ readonly headless?: boolean;
100
+ /**
101
+ * Video evidence (competitive research, `documents/decisions-inbox/`
102
+ * video-evidence proposal): a caller-facing toggle for Playwright's
103
+ * `recordVideo` context option. Deliberately just a boolean, the same
104
+ * restraint this interface's own `headless` comment already explains --
105
+ * `dir` is `browser-session.ts`'s own concern (a session-scoped temp
106
+ * directory, never caller-supplied) and `size` is not exposed because
107
+ * nothing reads a caller-supplied value for it yet. Landed together with
108
+ * its one emitter (`BrowserActionCollector.captureVideo()`), per RT-053's
109
+ * lesson this file already cites: a declared-but-dead option is the
110
+ * mistake, not an option existing at all.
111
+ */
112
+ readonly recordVideo?: boolean;
113
+ }
114
+ /**
115
+ * §21's execution boundary (RT-070). Applies to every service this
116
+ * execution spawns -- enforced by the OS itself via `prlimit` (util-invoke
117
+ * only, never a shell; RT-036 already refused shell metacharacters in
118
+ * commands and reintroducing `sh -c 'ulimit ...'` to get these would undo
119
+ * that). `prlimit` is util-linux, absent on macOS -- a real **capability**,
120
+ * reported `available`/`unavailable` with a reason
121
+ * (`resourceLimitCapability()`, `@descryy/runtime-controller`), never
122
+ * assumed. Requesting a limit on a platform that cannot enforce it is a
123
+ * refusal, not a silent no-op: the one alternative -- spawn unconstrained
124
+ * and stay quiet about it -- is the exact "sandbox that doesn't sandbox"
125
+ * shape §38 already bans one row up.
126
+ *
127
+ * Absent (the default, unchanged from every execution before this) means no
128
+ * limit at all -- this runtime's declared trusted-local boundary (see
129
+ * DECISIONS.md RT-070) does not require one; it is available to a caller
130
+ * that wants a backstop, not imposed on every execution.
131
+ */
132
+ export interface ResourceLimits {
133
+ /** Maps to `prlimit --as` (virtual address space) -- the resource the kernel actually enforces for a process that allocates too much; `RLIMIT_RSS` is not enforced on modern Linux. */
134
+ readonly maxMemoryBytes?: number;
135
+ /** Maps to `prlimit --cpu`, in seconds of consumed CPU time. */
136
+ readonly maxCpuSeconds?: number;
137
+ /** Maps to `prlimit --nproc`. Per-real-uid, not per-process-tree -- a POSIX rlimit property, not a choice made here. A low value on a machine already running many processes under the same user can be exceeded immediately; see `execution-safety.test.ts` for how that risk is tested around rather than through. */
138
+ readonly maxProcesses?: number;
139
+ }
140
+ /**
141
+ * §21's execution boundary, network half. Sits next to `ResourceLimits` for
142
+ * the same reason and is declared the same way, but the two were not
143
+ * symmetric at RT-193: `prlimit` genuinely enforced CPU/memory/process
144
+ * limits on Linux, while no mechanism anywhere in this runtime restricted
145
+ * which hosts a spawned process could reach.
146
+ *
147
+ * **Real on Linux as of the sandbox-isolation lane**, for one shape only:
148
+ * full denial, `{ mode: "allow", hosts: [] }` (read literally under this
149
+ * interface's own semantics -- only the hosts in `hosts` are reachable, and
150
+ * there are none). Enforced with a network namespace holding nothing but a
151
+ * loopback device, private to the sandboxed process tree -- not even the
152
+ * host's own loopback is reachable from inside it (`networkIsolationCapability()`,
153
+ * `applySandbox()`, `@descryy/runtime-controller`). A non-empty `hosts` list
154
+ * -- selective allow- or deny-listing -- would need DNS interception and IP
155
+ * filtering inside the namespace (a veth pair, NAT, iptables/nftables rules)
156
+ * that this iteration does not build; declaring one still refuses the run,
157
+ * atomically, before anything spawns -- the same "declared, refused rather
158
+ * than silently ignored if unenforceable" precedent `applyResourceLimits`
159
+ * already set one field up. macOS and Windows have no enforcement mechanism
160
+ * wired up at all yet (see the sandbox-isolation lane's own decision note),
161
+ * so every shape refuses there, matching RT-193's original behavior
162
+ * unchanged on those platforms.
163
+ */
164
+ export interface NetworkPolicy {
165
+ /** "allow" means only `hosts` are reachable; "deny" means every host in `hosts` is refused, everything else reachable. */
166
+ readonly mode: "allow" | "deny";
167
+ readonly hosts: readonly string[];
168
+ }
169
+ /**
170
+ * §21's execution boundary, filesystem half. Sibling to `NetworkPolicy`:
171
+ * declared the same way, enforced the same way -- real on Linux
172
+ * (`@descryy/runtime-controller`'s `filesystemIsolationCapability`, via a
173
+ * mount namespace built with bubblewrap), refused rather than silently
174
+ * accepted and unenforced everywhere else (macOS, Windows -- no mechanism
175
+ * wired up yet).
176
+ *
177
+ * A path outside `allowedRoots` (plus `cwd`, always included automatically,
178
+ * and the resolved directory of the interpreter binary being spawned -- see
179
+ * `applySandbox`'s own comment) is not merely unreadable inside the
180
+ * sandbox, it is **not present**: `open()` on it fails with `ENOENT`, the
181
+ * same as a path that never existed, because the mount namespace never
182
+ * bound it in. That is a stronger claim than a permission bit, and the one
183
+ * the escape tests in `sandbox.test.ts` exist to prove for real rather than
184
+ * assert from the mechanism's documentation alone.
185
+ */
186
+ export interface FilesystemPolicy {
187
+ /** Absolute paths visible read-write inside the sandbox, in addition to `cwd`. Everything else on the host, including the rest of the user's home directory, is invisible to the spawned process -- not just unwritable, not mounted at all. */
188
+ readonly allowedRoots: readonly string[];
189
+ }
190
+ /**
191
+ * §2's "commit is recorded; environment metadata is not captured" gap
192
+ * (RT-193): `Execution.commit` alone cannot reproduce a run -- the same
193
+ * commit under a different Node version, OS, or toolchain can behave
194
+ * differently, and nothing recorded which one actually ran. Captured once,
195
+ * at the start of `ExecutionController.run()`, from the real host --
196
+ * declared here as the shape, not computed in the contract layer, matching
197
+ * this file's own "field list lives here, capture logic lives in
198
+ * `packages/controller`" split.
199
+ */
200
+ export interface EnvironmentMetadata {
201
+ /** `os.platform()` -- "linux" / "darwin" / "win32" / etc. */
202
+ readonly platform: string;
203
+ /** `process.version` of the Node process running the controller itself -- always known, never probed. */
204
+ readonly nodeVersion: string;
205
+ /**
206
+ * `<command> --version` (or the closest working equivalent), one entry per
207
+ * distinct executable named by `configuration.services[*].command` --
208
+ * reuses `scripts/preflight.mjs`'s `interpreters()` probe shape rather
209
+ * than a second implementation of it. `null` for a command that could not
210
+ * be probed (absent, or refuses every version flag tried) -- recorded,
211
+ * not dropped from the map, matching RT-070's "declared, refused rather
212
+ * than silently ignored" precedent applied to a report instead of an
213
+ * enforcement gate.
214
+ */
215
+ readonly toolchainVersions: Readonly<Record<string, string | null>>;
216
+ }
217
+ /**
218
+ * §2's "test-runner configuration exists, but not (yet) a field" gap: before
219
+ * this, `createTestRunnerCollector`'s `TestRunnerCollectorOptions.configuration`
220
+ * was declared independently in `@descryhq-wq/runtime-test-runner`, with no
221
+ * path from a declared `ExecutionConfiguration` at all -- the same gap
222
+ * `BrowserConfiguration` closed at RT-068, one field over. This is the
223
+ * contracts type; `packages/test-runner` imports and re-exports it rather
224
+ * than keeping a second, driftable copy.
225
+ */
226
+ export interface TestRunnerConfiguration {
227
+ readonly command: string;
228
+ readonly cwd: string;
229
+ }
230
+ export interface ExecutionConfiguration {
231
+ readonly environmentTier: EnvironmentTier;
232
+ readonly fidelityLevel: FidelityLevel;
233
+ readonly timeoutMs: number;
234
+ readonly services: Readonly<Record<string, ServiceConfiguration>>;
235
+ /** Absent means `launchBrowserSession`'s own default (`headless: true`) -- not a second default defined here that could disagree with it. */
236
+ readonly browser?: BrowserConfiguration;
237
+ /** Absent means no test run declared for this execution -- `createTestRunnerCollector` is a direct caller's own concern, not something `ExecutionController.run()` invokes automatically. See `TestRunnerConfiguration`'s own comment. */
238
+ readonly testRunner?: TestRunnerConfiguration;
239
+ /** Absent means unconstrained -- see `ResourceLimits`'s own comment for why that is the correct default, not a gap. */
240
+ readonly resourceLimits?: ResourceLimits;
241
+ /** Absent means no policy declared. See `NetworkPolicy`'s own comment -- full denial is enforced on Linux; every other declared shape, and every shape on macOS/Windows, refuses to start rather than running unconstrained. */
242
+ readonly networkPolicy?: NetworkPolicy;
243
+ /** Absent means unconstrained -- the default, unchanged. See `FilesystemPolicy`'s own comment -- enforced on Linux, refuses to start elsewhere rather than running unconstrained under a declared policy that cannot be applied. */
244
+ readonly filesystemPolicy?: FilesystemPolicy;
245
+ /**
246
+ * Which real mechanism enforces `filesystemPolicy`/`networkPolicy` when
247
+ * either is declared. Absent means `"bwrap"` -- the original Linux
248
+ * mechanism (`@descryy/runtime-controller`'s `sandbox.ts`), completely
249
+ * unchanged in behavior by this field's existence. `"container"` routes
250
+ * the same declared policies through a real Docker container instead
251
+ * (`container-sandbox.ts`) -- the macOS/Windows path, since neither
252
+ * platform has a native bwrap equivalent wired up; also usable on Linux.
253
+ * Declaring `"container"` without a working Docker present refuses to
254
+ * start, the same "refuse rather than silently run unconstrained"
255
+ * precedent `filesystemPolicy`/`networkPolicy` already established.
256
+ */
257
+ readonly sandboxBackend?: "bwrap" | "container";
258
+ }
259
+ export interface ProcessHandle {
260
+ readonly processId: string;
261
+ readonly command: string;
262
+ /** Null once the process has exited and been reaped. */
263
+ readonly pid: number | null;
264
+ readonly startedAt: string;
265
+ readonly exitedAt: string | null;
266
+ /**
267
+ * POSIX only sets an exit code on normal `exit()` — null both before the
268
+ * process has started exiting and after it was killed by a signal, so
269
+ * `exitCode` alone cannot tell "never ran" apart from "crashed." `signal`
270
+ * is what actually distinguishes a clean-but-ambiguous exit from a real
271
+ * crash (RT-032): non-null here means the process was killed by that
272
+ * signal, whatever `exitCode` says.
273
+ */
274
+ readonly exitCode: number | null;
275
+ readonly signal: NodeJS.Signals | null;
276
+ /**
277
+ * Which key of `ExecutionConfiguration.services` this process is running,
278
+ * when known — null for a process that doesn't correspond to a named
279
+ * service (e.g. a one-off test-runner invocation). The join key for
280
+ * recovering `cwd`/`command` from configuration; see `ServiceConfiguration`.
281
+ */
282
+ readonly serviceName: string | null;
283
+ /**
284
+ * The actual port this process is bound to, when it listens on one — the
285
+ * real OS-assigned port for an ephemeral service, not merely a value that
286
+ * was requested. Null for a process that isn't a network service, or
287
+ * before the port is known.
288
+ */
289
+ readonly port: number | null;
290
+ /**
291
+ * True only for a service started via `ServiceConfiguration.attach` —
292
+ * absent (equivalent to `false`) for every process this runtime actually
293
+ * spawned, unchanged from every `ProcessHandle` before this field existed.
294
+ * Exists so evidence and lifecycle consumers downstream (`ProcessCollector`,
295
+ * `runInstrumentedExecution`) can tell "we observed a process we did not
296
+ * spawn" from "we spawned this ourselves" without inferring it from
297
+ * `command`'s text — the same "declared, not guessed" discipline this
298
+ * file already applies everywhere else. See `ATTACH_MODE_SCOPE_DISCLOSURE`
299
+ * (`@descryy/runtime-contracts`'s `collector.ts`) for what attach mode
300
+ * does and does not do to the process this describes.
301
+ */
302
+ readonly attached?: boolean;
303
+ }
304
+ export interface BrowserSessionHandle {
305
+ readonly sessionId: string;
306
+ readonly targetUrl: string;
307
+ readonly startedAt: string;
308
+ readonly endedAt: string | null;
309
+ }
310
+ export interface Execution {
311
+ readonly executionId: string;
312
+ readonly application: string;
313
+ readonly repository: string;
314
+ readonly commit: string;
315
+ /** Null until `run()` captures it (RT-193) -- absent on an `Execution` still in `CREATED`, populated by `STARTING`. See `EnvironmentMetadata`'s own comment for why `commit` alone was not reproducible. */
316
+ readonly environmentMetadata: EnvironmentMetadata | null;
317
+ readonly configuration: ExecutionConfiguration;
318
+ readonly state: ExecutionState;
319
+ readonly startedAt: string | null;
320
+ readonly endedAt: string | null;
321
+ readonly processes: readonly ProcessHandle[];
322
+ readonly browserSessions: readonly BrowserSessionHandle[];
323
+ readonly eventIds: readonly string[];
324
+ readonly traceIds: readonly string[];
325
+ readonly failureIds: readonly string[];
326
+ readonly correlationIds: readonly string[];
327
+ readonly findingIds: readonly string[];
328
+ }
329
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Execution contract.
3
+ *
4
+ * Field list and lifecycle states are verbatim from
5
+ * `documents/descry-runtime-plan.md` §4 (Execution model). Also grounded in
6
+ * the architecture doc's §16 (RVE boot sequence — oracle extraction,
7
+ * environment selection, boot, graph-aware seeding, snapshot, ready; §16.4's
8
+ * "SETUP FAILURE surfaced immediately, tagged distinctly from a test
9
+ * failure" is the direct source of FAILED_START as a state separate from
10
+ * FAILED) and §10.3 (environment tiers, referenced via
11
+ * ExecutionConfiguration.environmentTier from capability.ts).
12
+ *
13
+ * An Execution record holds *references* (event/trace/failure/correlation/
14
+ * finding IDs), never inlines the records themselves — mirrors §18.2's
15
+ * storage rule ("referenced by ID, never inlined") so a long-running
16
+ * execution doesn't grow this record unboundedly.
17
+ */
18
+ export const EXECUTION_STATES = [
19
+ "CREATED",
20
+ "STARTING",
21
+ "READY",
22
+ "RUNNING",
23
+ "STOPPING",
24
+ "COMPLETED",
25
+ "FAILED_START",
26
+ "FAILED",
27
+ "TIMED_OUT",
28
+ "CANCELLED",
29
+ ];
30
+ const TERMINAL_STATES = new Set([
31
+ "COMPLETED",
32
+ "FAILED_START",
33
+ "FAILED",
34
+ "TIMED_OUT",
35
+ "CANCELLED",
36
+ ]);
37
+ const ALLOWED_TRANSITIONS = {
38
+ CREATED: ["STARTING", "CANCELLED"],
39
+ STARTING: ["READY", "FAILED_START", "TIMED_OUT", "CANCELLED"],
40
+ READY: ["RUNNING", "STOPPING", "CANCELLED"],
41
+ RUNNING: ["STOPPING", "FAILED", "TIMED_OUT", "CANCELLED"],
42
+ STOPPING: ["COMPLETED", "FAILED"],
43
+ COMPLETED: [],
44
+ FAILED_START: [],
45
+ FAILED: [],
46
+ TIMED_OUT: [],
47
+ CANCELLED: [],
48
+ };
49
+ export function isValidExecutionTransition(from, to) {
50
+ return ALLOWED_TRANSITIONS[from].includes(to);
51
+ }
52
+ export function isTerminalExecutionState(state) {
53
+ return TERMINAL_STATES.has(state);
54
+ }
55
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,SAAS;IACT,UAAU;IACV,OAAO;IACP,SAAS;IACT,UAAU;IACV,WAAW;IACX,cAAc;IACd,QAAQ;IACR,WAAW;IACX,WAAW;CACH,CAAC;AAGX,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAC3D,WAAW;IACX,cAAc;IACd,QAAQ;IACR,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAgE;IACvF,OAAO,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,CAAC;IAC7D,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC;IAC3C,OAAO,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC;IACzD,QAAQ,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;IACjC,SAAS,EAAE,EAAE;IACb,YAAY,EAAE,EAAE;IAChB,MAAM,EAAE,EAAE;IACV,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,MAAM,UAAU,0BAA0B,CAAC,IAAoB,EAAE,EAAkB;IACjF,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAqB;IAC5D,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type { EnvironmentTier, FidelityLevel, CapabilityAvailability, CapabilityStatus, CollectorCapabilities, ExecutionCapabilities, } from "./capability.ts";
2
+ export { ENVIRONMENT_TIERS, FIDELITY_LEVELS, CAPABILITY_AVAILABILITY, isCapabilityStatusValid } from "./capability.ts";
3
+ export type { ExecutionState, ServiceConfiguration, ServiceAttachConfiguration, BrowserConfiguration, ResourceLimits, NetworkPolicy, FilesystemPolicy, EnvironmentMetadata, TestRunnerConfiguration, ExecutionConfiguration, ProcessHandle, BrowserSessionHandle, Execution, } from "./execution.ts";
4
+ export { EXECUTION_STATES, isValidExecutionTransition, isTerminalExecutionState, } from "./execution.ts";
5
+ export type { ConfiguredServiceRoot, ServiceRootRefusal, ServiceRootLookup } from "./source-root.ts";
6
+ export { SERVICE_ROOT_REFUSALS, resolveServiceRootForOrigin } from "./source-root.ts";
7
+ export type { RuntimeEventType } from "./runtime-event.ts";
8
+ export { RUNTIME_EVENT_TYPES } from "./runtime-event.ts";
9
+ export type { EvidenceSource, RedactionStatus, SourceLocationReliability, SourceLocation, StackFidelity, StackFrame, StackTrace, Evidence, } from "./evidence.ts";
10
+ export { EVIDENCE_SOURCES, REDACTION_STATUSES, SOURCE_LOCATION_RELIABILITIES, STACK_FIDELITIES, primaryFrameLocation, locationNamesNothing, } from "./evidence.ts";
11
+ export type { CorrelationMethod, Correlation } from "./correlation.ts";
12
+ export { CORRELATION_METHODS, CORRELATION_PREFERENCE_ORDER, correlationRank, isStructuralCorrelation, createCorrelation, } from "./correlation.ts";
13
+ export type { EmitFn, SourceRootResolver, CollectorContext, CollectorStartResult, Collector, } from "./collector.ts";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEvH,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEtF,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EACV,cAAc,EACd,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,aAAa,EACb,UAAU,EACV,UAAU,EACV,QAAQ,GACT,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,EAC7B,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,MAAM,EACN,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,GACV,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { ENVIRONMENT_TIERS, FIDELITY_LEVELS, CAPABILITY_AVAILABILITY, isCapabilityStatusValid } from "./capability.js";
2
+ export { EXECUTION_STATES, isValidExecutionTransition, isTerminalExecutionState, } from "./execution.js";
3
+ export { SERVICE_ROOT_REFUSALS, resolveServiceRootForOrigin } from "./source-root.js";
4
+ export { RUNTIME_EVENT_TYPES } from "./runtime-event.js";
5
+ export { EVIDENCE_SOURCES, REDACTION_STATUSES, SOURCE_LOCATION_RELIABILITIES, STACK_FIDELITIES, primaryFrameLocation, locationNamesNothing, } from "./evidence.js";
6
+ export { CORRELATION_METHODS, CORRELATION_PREFERENCE_ORDER, correlationRank, isStructuralCorrelation, createCorrelation, } from "./correlation.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAiBvH,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAGtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAYzD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,EAC7B,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Runtime Event vocabulary.
3
+ *
4
+ * The exact 19 values below are the canonical list from
5
+ * `documents/descry-runtime-plan.md` §14 — reproduced verbatim, not
6
+ * reconstructed. An earlier version of this file was written before that
7
+ * document was available in this repo and guessed at a vocabulary that did
8
+ * not match it; this replaces that guess.
9
+ *
10
+ * This vocabulary is DELIBERATELY INDEPENDENT of the Graph Engine's 15 node
11
+ * types / 15 edge types (descry-core CLAUDE.md, DEC-061) — plan §14 states
12
+ * this explicitly. A runtime event is an observation, not a graph fact, and
13
+ * this list may grow or change on its own schedule. If a runtime need ever
14
+ * looks like it wants a new *graph* node or edge type, that is out of scope
15
+ * here — stop and raise it (plan principle 12). The graph vocabulary is
16
+ * frozen; this one is not.
17
+ */
18
+ export declare const RUNTIME_EVENT_TYPES: readonly ["PROCESS_STARTED", "PROCESS_READY", "PROCESS_EXITED", "PAGE_CREATED", "NAVIGATION", "CLICK", "INPUT", "SCREENSHOT", "VIDEO", "CONSOLE_MESSAGE", "NETWORK_REQUEST", "NETWORK_RESPONSE", "HTTP_ERROR", "BACKEND_LOG", "EXCEPTION", "STACK_TRACE", "TEST_STARTED", "TEST_PASSED", "TEST_FAILED", "TEST_SKIPPED", "DATABASE_QUERY", "EXTERNAL_REQUEST", "COLLECTOR_ERROR", "DEPENDENCY_VERSION_MISMATCH", "ENVIRONMENT_VERSION_MISMATCH", "WEBSOCKET_CLOSED"];
19
+ export type RuntimeEventType = (typeof RUNTIME_EVENT_TYPES)[number];
20
+ //# sourceMappingURL=runtime-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-event.d.ts","sourceRoot":"","sources":["../src/runtime-event.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,mBAAmB,qcAyOtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC"}