@descryy/runtime-external-service-observation 0.1.0 → 0.3.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 ADDED
@@ -0,0 +1,6 @@
1
+ Copyright (c) Descry
2
+
3
+ All rights reserved. This software is proprietary and confidential.
4
+ No license, express or implied, to reproduce, distribute, modify, or
5
+ create derivative works is granted except as explicitly agreed in
6
+ writing.
@@ -1,10 +1,3 @@
1
- /**
2
- * `Evidence.collectorVersion`'s source for every collector in this package:
3
- * this package's own `package.json` "version", read from the artifact
4
- * itself rather than hand-duplicated into a second string that can drift
5
- * from what actually shipped. Same idea as `nodeVersion` elsewhere in this
6
- * repo (`process.version`, always known, never probed) applied to a
7
- * package instead of the Node runtime.
8
- */
1
+ /** `Evidence.collectorVersion` for this package's collectors. Read from `package.json`, not hand-duplicated, so it can't drift from what shipped. */
9
2
  export declare const COLLECTOR_VERSION: string;
10
3
  //# sourceMappingURL=collector-version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector-version.d.ts","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,eAAO,MAAM,iBAAiB,EAAE,MAA6E,CAAC"}
1
+ {"version":3,"file":"collector-version.d.ts","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA,qJAAqJ;AAMrJ,eAAO,MAAM,iBAAiB,EAAE,MAA6E,CAAC"}
@@ -1,11 +1,4 @@
1
- /**
2
- * `Evidence.collectorVersion`'s source for every collector in this package:
3
- * this package's own `package.json` "version", read from the artifact
4
- * itself rather than hand-duplicated into a second string that can drift
5
- * from what actually shipped. Same idea as `nodeVersion` elsewhere in this
6
- * repo (`process.version`, always known, never probed) applied to a
7
- * package instead of the Node runtime.
8
- */
1
+ /** `Evidence.collectorVersion` for this package's collectors. Read from `package.json`, not hand-duplicated, so it can't drift from what shipped. */
9
2
  import { createRequire } from "node:module";
10
3
  const require = createRequire(import.meta.url);
11
4
  export const COLLECTOR_VERSION = require("../package.json").version;
@@ -1 +1 @@
1
- {"version":3,"file":"collector-version.js","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAkC,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"collector-version.js","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA,qJAAqJ;AAErJ,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAkC,CAAC,OAAO,CAAC"}
@@ -1,61 +1,36 @@
1
1
  /**
2
2
  * `--import`-loaded preload: patches `globalThis.fetch` before the target
3
- * application's own code runs, so every real outbound call the application
4
- * issues through the bare global `fetch` is observed — proven directly (a
5
- * probe script, not assumed): Node's global `fetch` is a single, mutable
6
- * binding on `globalThis`, so a `--import` preload reassigning it here and
7
- * an application's completely independent, later call to bare `fetch(...)`
8
- * resolve to the same function. Same singleton-timing argument
9
- * `sqlite-instrumentation.ts` (`@descryy/runtime-database-observation`,
10
- * RT-141) already established for `node:sqlite`'s prototype, applied to a
11
- * different kind of global.
3
+ * application's code runs, so every outbound call through the bare global
4
+ * is observed. Node's global `fetch` is a single mutable binding on
5
+ * `globalThis`, so a preload reassigning it and a later app call resolve to
6
+ * the same function — same singleton-timing argument as
7
+ * `sqlite-instrumentation.ts` (RT-141), applied to a different global.
12
8
  *
13
- * **Read, not write.** The wrapper calls the original `fetch` with the
14
- * exact, untouched arguments it received — nothing about what leaves the
15
- * process changes. Request/response bodies are never read here: `status`
16
- * comes off the resolved `Response` before any body access, and describing
17
- * the outbound request (`method`/`url`/headers) is done via the same
18
- * `Request`/`Headers` normalisation `fetch` itself would do, on a
19
- * side channel, not by touching the body stream passed to the real call.
9
+ * Read, not write: the wrapper calls the original `fetch` with untouched
10
+ * arguments. Bodies are never read — `status` comes off the resolved
11
+ * `Response` before any body access.
20
12
  *
21
- * Deliberately minimal and import-free, like `sqlite-instrumentation.ts` and
22
- * `test-runner`'s own `reporter.ts` — this runs inside the OBSERVED process,
23
- * loaded by absolute path via `node --import`, never through this package's
24
- * normal dependency graph. Interpretation (service identity, correlation
25
- * ids) happens on the collector side, in the observing process, not here —
26
- * this only captures.
13
+ * Deliberately minimal and import-free, like `sqlite-instrumentation.ts` —
14
+ * runs inside the OBSERVED process, loaded by absolute path via
15
+ * `node --import`, never through this package's normal dependency graph.
16
+ * Interpretation happens on the collector side; this only captures.
27
17
  *
28
- * **The call-site stack is captured here and nowhere else.** It is the one
29
- * fact only this process can supply: by the time the marker line reaches a
30
- * collector it is text on a pipe, which is exactly why
31
- * `ExternalRequestCollector` reported `stackTrace: null` for as long as this
32
- * preload captured none. `observe_runtime`'s own header records the
33
- * consequence — a backend-only run "resolves both kinds of node and writes no
34
- * edge", because an edge needs a caller and an endpoint named by ONE
35
- * observation and this one named only the endpoint. Capturing the stack at
36
- * the call site is what makes an outbound call able to name its own caller.
18
+ * The call-site stack is captured here and nowhere else — it's the one
19
+ * fact only this process can supply (by the time the marker reaches a
20
+ * collector it's just text on a pipe). Capturing it here is what makes an
21
+ * outbound call able to name its own caller. Raw text, deliberately
22
+ * unparsed — parsing V8's format belongs in the observing process
23
+ * (`@descryy/runtime-adapter-typescript`).
37
24
  *
38
- * Raw text, deliberately unparsed. Parsing V8's format is
39
- * `@descryy/runtime-adapter-typescript`'s job and belongs in the observing
40
- * process, the same read-here/interpret-there split every marker in this
41
- * repository already uses.
25
+ * Cost: `new Error()` on every outbound call, in a process that opted into
26
+ * observation by loading this preload. `Error.stackTraceLimit` is left as
27
+ * the app set it — raising it would mean writing to the observed process's
28
+ * own config.
42
29
  *
43
- * The cost, stated rather than discovered: `new Error()` on every outbound
44
- * call. That is a stack capture per request in a process that has opted into
45
- * being observed by loading this preload; `Error.stackTraceLimit` is left
46
- * exactly as the application set it, because raising it would be this file
47
- * writing to the observed process's own configuration, which the paragraph
48
- * above forbids.
49
- *
50
- * The marker prefix and the captured shape live in `request-marker.ts`, not
51
- * here: this module has a module-scope effect and nothing that merely needs
52
- * the vocabulary may be made to import it. See that file for the measurement
53
- * behind that rule.
54
- *
55
- * One line of structured JSON per request, prefixed exactly like
56
- * `sqlite-instrumentation.ts`'s own `DESCRY_DB_QUERY {json}` convention,
57
- * itself following the benchmark harness's `BENCH_RESULT {json}` precedent
58
- * (RT-072): scraping prose measures the prose, so nothing here is prose.
30
+ * Marker prefix and shape live in `request-marker.ts`, not here, since this
31
+ * module has a module-scope effect. One line of structured JSON per
32
+ * request, matching `sqlite-instrumentation.ts`'s `DESCRY_DB_QUERY {json}`
33
+ * convention (RT-072): scraping prose measures the prose.
59
34
  */
60
35
  export {};
61
36
  //# sourceMappingURL=fetch-instrumentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-instrumentation.d.ts","sourceRoot":"","sources":["../src/fetch-instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG"}
1
+ {"version":3,"file":"fetch-instrumentation.d.ts","sourceRoot":"","sources":["../src/fetch-instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG"}
@@ -1,75 +1,47 @@
1
1
  /**
2
2
  * `--import`-loaded preload: patches `globalThis.fetch` before the target
3
- * application's own code runs, so every real outbound call the application
4
- * issues through the bare global `fetch` is observed — proven directly (a
5
- * probe script, not assumed): Node's global `fetch` is a single, mutable
6
- * binding on `globalThis`, so a `--import` preload reassigning it here and
7
- * an application's completely independent, later call to bare `fetch(...)`
8
- * resolve to the same function. Same singleton-timing argument
9
- * `sqlite-instrumentation.ts` (`@descryy/runtime-database-observation`,
10
- * RT-141) already established for `node:sqlite`'s prototype, applied to a
11
- * different kind of global.
3
+ * application's code runs, so every outbound call through the bare global
4
+ * is observed. Node's global `fetch` is a single mutable binding on
5
+ * `globalThis`, so a preload reassigning it and a later app call resolve to
6
+ * the same function — same singleton-timing argument as
7
+ * `sqlite-instrumentation.ts` (RT-141), applied to a different global.
12
8
  *
13
- * **Read, not write.** The wrapper calls the original `fetch` with the
14
- * exact, untouched arguments it received — nothing about what leaves the
15
- * process changes. Request/response bodies are never read here: `status`
16
- * comes off the resolved `Response` before any body access, and describing
17
- * the outbound request (`method`/`url`/headers) is done via the same
18
- * `Request`/`Headers` normalisation `fetch` itself would do, on a
19
- * side channel, not by touching the body stream passed to the real call.
9
+ * Read, not write: the wrapper calls the original `fetch` with untouched
10
+ * arguments. Bodies are never read — `status` comes off the resolved
11
+ * `Response` before any body access.
20
12
  *
21
- * Deliberately minimal and import-free, like `sqlite-instrumentation.ts` and
22
- * `test-runner`'s own `reporter.ts` — this runs inside the OBSERVED process,
23
- * loaded by absolute path via `node --import`, never through this package's
24
- * normal dependency graph. Interpretation (service identity, correlation
25
- * ids) happens on the collector side, in the observing process, not here —
26
- * this only captures.
13
+ * Deliberately minimal and import-free, like `sqlite-instrumentation.ts` —
14
+ * runs inside the OBSERVED process, loaded by absolute path via
15
+ * `node --import`, never through this package's normal dependency graph.
16
+ * Interpretation happens on the collector side; this only captures.
27
17
  *
28
- * **The call-site stack is captured here and nowhere else.** It is the one
29
- * fact only this process can supply: by the time the marker line reaches a
30
- * collector it is text on a pipe, which is exactly why
31
- * `ExternalRequestCollector` reported `stackTrace: null` for as long as this
32
- * preload captured none. `observe_runtime`'s own header records the
33
- * consequence — a backend-only run "resolves both kinds of node and writes no
34
- * edge", because an edge needs a caller and an endpoint named by ONE
35
- * observation and this one named only the endpoint. Capturing the stack at
36
- * the call site is what makes an outbound call able to name its own caller.
18
+ * The call-site stack is captured here and nowhere else — it's the one
19
+ * fact only this process can supply (by the time the marker reaches a
20
+ * collector it's just text on a pipe). Capturing it here is what makes an
21
+ * outbound call able to name its own caller. Raw text, deliberately
22
+ * unparsed — parsing V8's format belongs in the observing process
23
+ * (`@descryy/runtime-adapter-typescript`).
37
24
  *
38
- * Raw text, deliberately unparsed. Parsing V8's format is
39
- * `@descryy/runtime-adapter-typescript`'s job and belongs in the observing
40
- * process, the same read-here/interpret-there split every marker in this
41
- * repository already uses.
25
+ * Cost: `new Error()` on every outbound call, in a process that opted into
26
+ * observation by loading this preload. `Error.stackTraceLimit` is left as
27
+ * the app set it — raising it would mean writing to the observed process's
28
+ * own config.
42
29
  *
43
- * The cost, stated rather than discovered: `new Error()` on every outbound
44
- * call. That is a stack capture per request in a process that has opted into
45
- * being observed by loading this preload; `Error.stackTraceLimit` is left
46
- * exactly as the application set it, because raising it would be this file
47
- * writing to the observed process's own configuration, which the paragraph
48
- * above forbids.
49
- *
50
- * The marker prefix and the captured shape live in `request-marker.ts`, not
51
- * here: this module has a module-scope effect and nothing that merely needs
52
- * the vocabulary may be made to import it. See that file for the measurement
53
- * behind that rule.
54
- *
55
- * One line of structured JSON per request, prefixed exactly like
56
- * `sqlite-instrumentation.ts`'s own `DESCRY_DB_QUERY {json}` convention,
57
- * itself following the benchmark harness's `BENCH_RESULT {json}` precedent
58
- * (RT-072): scraping prose measures the prose, so nothing here is prose.
30
+ * Marker prefix and shape live in `request-marker.ts`, not here, since this
31
+ * module has a module-scope effect. One line of structured JSON per
32
+ * request, matching `sqlite-instrumentation.ts`'s `DESCRY_DB_QUERY {json}`
33
+ * convention (RT-072): scraping prose measures the prose.
59
34
  */
60
- import { REQUEST_MARKER } from "./request-marker.js";
61
- /** This module's own location, in both shapes a V8 frame can print it: an ESM frame stringifies a `file://` URL, a CJS one a plain path. */
35
+ import { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER } from "./request-marker.js";
36
+ /** This module's own location, in both shapes a V8 frame prints it: ESM stringifies a `file://` URL, CJS a plain path. */
62
37
  const SELF_URL = import.meta.url;
63
38
  const SELF_PATH = SELF_URL.startsWith("file://") ? SELF_URL.slice("file://".length) : SELF_URL;
64
39
  /**
65
- * Frames belonging to this file are dropped **by file, not by count**.
66
- * `primaryFrameIndex` is 0 for every V8 stack this project parses, so a
67
- * single surviving wrapper frame would make every downstream resolution
68
- * point at the instrumentation instead of at the code under observation --
69
- * a failure that produces confident, well-formed, entirely wrong answers
70
- * rather than an error. Matching on `import.meta.url` also survives this
71
- * module being loaded from `.js` (the compiled preload, how it actually
72
- * runs) or `.ts` (type stripping, how a test may run it).
40
+ * Frames from this file are dropped **by file, not by count** — a
41
+ * surviving wrapper frame would make every downstream resolution point at
42
+ * the instrumentation instead of the observed code (`primaryFrameIndex` is
43
+ * 0 for every V8 stack this project parses). Matching `import.meta.url`
44
+ * survives this being loaded as `.js` (real) or `.ts` (test).
73
45
  */
74
46
  function callSiteStack() {
75
47
  const raw = new Error().stack;
@@ -78,8 +50,8 @@ function callSiteStack() {
78
50
  const lines = raw.split("\n");
79
51
  const header = lines[0] ?? "Error";
80
52
  const frames = lines.slice(1).filter((line) => !line.includes(SELF_URL) && !line.includes(SELF_PATH));
81
- // Nothing but our own frames: no application call site was captured, which
82
- // is `null` rather than a header line pretending to be a stack.
53
+ // Nothing but our own frames: `null` rather than a header line pretending
54
+ // to be a stack.
83
55
  if (frames.length === 0)
84
56
  return null;
85
57
  return [header, ...frames].join("\n");
@@ -93,12 +65,7 @@ function headersToObject(headers) {
93
65
  out[name] = value;
94
66
  return out;
95
67
  }
96
- /**
97
- * `url`/`method`/`requestHeaders` off the call's own arguments, without
98
- * touching the body -- a `Request` object already carries these structured;
99
- * a `(input, init)` pair is normalised the same way `fetch` itself would,
100
- * via the real `Headers` constructor rather than hand-parsed.
101
- */
68
+ /** `url`/`method`/`requestHeaders` off the call's own arguments, without touching the body. Normalised via the real `Headers` constructor, not hand-parsed. */
102
69
  function describeRequest(input, init) {
103
70
  if (input instanceof Request) {
104
71
  return { url: input.url, method: input.method, requestHeaders: headersToObject(input.headers) };
@@ -107,31 +74,38 @@ function describeRequest(input, init) {
107
74
  const method = (init?.method ?? "GET").toUpperCase();
108
75
  return { url, method, requestHeaders: headersToObject(new Headers(init?.headers)) };
109
76
  }
110
- // Guards against double-patching if this module is somehow loaded twice
111
- // (e.g. both `--import` and a transitive re-import) -- the second pass
112
- // would otherwise wrap an already-wrapped fetch and double-emit. Same
113
- // guard shape as sqlite-instrumentation.ts's own PATCHED symbol.
77
+ // Guards against double-patching if loaded twice (double-emit otherwise).
78
+ // Same guard shape as sqlite-instrumentation.ts's PATCHED symbol.
114
79
  const PATCHED = Symbol.for("descry.external-service-observation.fetch-patched");
115
80
  const target = globalThis;
116
81
  if (target[PATCHED] !== true) {
117
82
  target[PATCHED] = true;
118
83
  const original = globalThis.fetch;
119
- globalThis.fetch = async function patchedFetch(input, init) {
120
- const described = describeRequest(input, init);
121
- // Captured BEFORE the call, not in the handlers below: after `await` the
122
- // application's own frames are gone from the stack.
123
- const stack = callSiteStack();
124
- const start = performance.now();
125
- try {
126
- const response = await original(input, init);
127
- emit({ ...described, status: response.status, durationMs: performance.now() - start, success: true, error: null, stack });
128
- return response;
129
- }
130
- catch (error) {
131
- const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
132
- emit({ ...described, status: null, durationMs: performance.now() - start, success: false, error: detail, stack });
133
- throw error;
134
- }
135
- };
84
+ // C-F6: previously unchecked — `original` could be `undefined` (old Node,
85
+ // `--no-experimental-fetch`), and every real call would then throw
86
+ // "original is not a function", indistinguishable from a real network
87
+ // error. Disclosed here instead via a distinct marker line; the wrapper
88
+ // is never installed.
89
+ if (typeof original !== "function") {
90
+ process.stdout.write(`${FETCH_BINDING_FAILURE_MARKER} ${JSON.stringify({ reason: `globalThis.fetch was ${typeof original}, not a function -- no real fetch to instrument` })}\n`);
91
+ }
92
+ else {
93
+ globalThis.fetch = async function patchedFetch(input, init) {
94
+ const described = describeRequest(input, init);
95
+ // Captured BEFORE the call: after `await` the app's frames are gone.
96
+ const stack = callSiteStack();
97
+ const start = performance.now();
98
+ try {
99
+ const response = await original(input, init);
100
+ emit({ ...described, status: response.status, durationMs: performance.now() - start, success: true, error: null, stack });
101
+ return response;
102
+ }
103
+ catch (error) {
104
+ const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
105
+ emit({ ...described, status: null, durationMs: performance.now() - start, success: false, error: detail, stack });
106
+ throw error;
107
+ }
108
+ };
109
+ }
136
110
  }
137
111
  //# sourceMappingURL=fetch-instrumentation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-instrumentation.js","sourceRoot":"","sources":["../src/fetch-instrumentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-instrumentation.js","sourceRoot":"","sources":["../src/fetch-instrumentation.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,11 @@
1
1
  /**
2
- * Correlation-id extraction from real HTTP headers — the same mechanism and
3
- * the same closed set of header names as `extractHeaderCorrelationIds`
4
- * (`@descryhq-wq/runtime-browser`'s `network-correlation.ts`).
2
+ * Correlation-id extraction from real HTTP headers — same mechanism and
3
+ * header names as `@descryy/runtime-browser`'s `network-correlation.ts`.
5
4
  *
6
- * **Duplicated on purpose, not imported.** `browser` depends on Playwright
7
- * to launch and drive a real browser — a real, heavy dependency this
8
- * package has no other reason to carry, for a page-automation concern
9
- * entirely unrelated to instrumenting a backend process's own outbound
10
- * `fetch`. The function itself is small, pure, and reads a closed,
11
- * unlikely-to-change set of conventional header names — the case this
12
- * project's own `symbol.ts` distinguishes from (`toRepoRelative` is
13
- * *shared* because its two callers must translate identically); these two
14
- * copies have no such constraint, and importing across a Playwright
15
- * dependency to avoid ten lines would be the worse coupling.
5
+ * Duplicated on purpose, not imported: `browser` depends on Playwright, a
6
+ * heavy dependency this package has no other reason to carry. The function
7
+ * is small, pure, and reads a closed set of header names — importing across
8
+ * Playwright to avoid ten lines would be the worse coupling.
16
9
  */
17
10
  export interface HeaderCorrelationIds {
18
11
  readonly traceId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"header-correlation.d.ts","sourceRoot":"","sources":["../src/header-correlation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAUD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,oBAAoB,CAS3G"}
1
+ {"version":3,"file":"header-correlation.d.ts","sourceRoot":"","sources":["../src/header-correlation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAUD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,oBAAoB,CAS3G"}
@@ -1,18 +1,11 @@
1
1
  /**
2
- * Correlation-id extraction from real HTTP headers — the same mechanism and
3
- * the same closed set of header names as `extractHeaderCorrelationIds`
4
- * (`@descryhq-wq/runtime-browser`'s `network-correlation.ts`).
2
+ * Correlation-id extraction from real HTTP headers — same mechanism and
3
+ * header names as `@descryy/runtime-browser`'s `network-correlation.ts`.
5
4
  *
6
- * **Duplicated on purpose, not imported.** `browser` depends on Playwright
7
- * to launch and drive a real browser — a real, heavy dependency this
8
- * package has no other reason to carry, for a page-automation concern
9
- * entirely unrelated to instrumenting a backend process's own outbound
10
- * `fetch`. The function itself is small, pure, and reads a closed,
11
- * unlikely-to-change set of conventional header names — the case this
12
- * project's own `symbol.ts` distinguishes from (`toRepoRelative` is
13
- * *shared* because its two callers must translate identically); these two
14
- * copies have no such constraint, and importing across a Playwright
15
- * dependency to avoid ten lines would be the worse coupling.
5
+ * Duplicated on purpose, not imported: `browser` depends on Playwright, a
6
+ * heavy dependency this package has no other reason to carry. The function
7
+ * is small, pure, and reads a closed set of header names — importing across
8
+ * Playwright to avoid ten lines would be the worse coupling.
16
9
  */
17
10
  const TRACEPARENT_PATTERN = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;
18
11
  function firstHeader(headers, names) {
@@ -1 +1 @@
1
- {"version":3,"file":"header-correlation.js","sourceRoot":"","sources":["../src/header-correlation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,mBAAmB,GAAG,8DAA8D,CAAC;AAO3F,SAAS,WAAW,CAAC,OAAyC,EAAE,KAAwB;IACtF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,OAAyC;IACnF,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3G,OAAO;QACL,OAAO,EAAE,eAAe,IAAI,UAAU;QACtC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;KAChE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"header-correlation.js","sourceRoot":"","sources":["../src/header-correlation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,mBAAmB,GAAG,8DAA8D,CAAC;AAO3F,SAAS,WAAW,CAAC,OAAyC,EAAE,KAAwB;IACtF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,OAAyC;IACnF,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3G,OAAO;QACL,OAAO,EAAE,eAAe,IAAI,UAAU;QACtC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;KAChE,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { REQUEST_MARKER, type CapturedRequest } from "./request-marker.ts";
2
- export { parseRequestLine } from "./request-line-parser.ts";
1
+ export { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER, type CapturedRequest } from "./request-marker.ts";
2
+ export { parseRequestLine, parseFetchBindingFailureLine } from "./request-line-parser.ts";
3
3
  export { extractServiceIdentity } from "./service-identity.ts";
4
4
  export { extractHeaderCorrelationIds, type HeaderCorrelationIds } from "./header-correlation.ts";
5
5
  export type { ExternalRequestCollectorOptions } from "./request-collector.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,YAAY,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,YAAY,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,11 +1,9 @@
1
- // Deliberately NOT from `fetch-instrumentation.ts`: that module replaces
2
- // `globalThis.fetch` at module scope, and re-exporting a constant out of it
3
- // put that patch into every consumer of this package -- `query-marker.ts`'s
4
- // measured defect, which this package still had. The preload is loaded by
5
- // absolute path via `node --import`, inside the observed process, never
6
- // through this dependency graph.
7
- export { REQUEST_MARKER } from "./request-marker.js";
8
- export { parseRequestLine } from "./request-line-parser.js";
1
+ // Deliberately NOT from `fetch-instrumentation.ts` — that module patches
2
+ // `globalThis.fetch` at module scope; re-exporting from it would leak the
3
+ // patch into every consumer (`query-marker.ts`'s measured defect). The
4
+ // preload loads by absolute path via `node --import`, never through here.
5
+ export { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER } from "./request-marker.js";
6
+ export { parseRequestLine, parseFetchBindingFailureLine } from "./request-line-parser.js";
9
7
  export { extractServiceIdentity } from "./service-identity.js";
10
8
  export { extractHeaderCorrelationIds } from "./header-correlation.js";
11
9
  export { createExternalRequestCollector, FETCH_PRELOAD_MODULE_PATH } from "./request-collector.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,iCAAiC;AACjC,OAAO,EAAE,cAAc,EAAwB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAA6B,MAAM,yBAAyB,CAAC;AAGjG,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,0EAA0E;AAC1E,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAwB,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAA6B,MAAM,yBAAyB,CAAC;AAGjG,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,57 +1,34 @@
1
1
  /**
2
- * `ExternalRequestCollector` (plan §18 / checklist §18): translates
3
- * `fetch-instrumentation.ts`'s captured requests into `EXTERNAL_REQUEST`
4
- * Evidence. Same shape as `DatabaseQueryCollector`
5
- * (`@descryy/runtime-database-observation`, RT-141) deliberately — a
6
- * `ProcessOutputSource` in, `Evidence` out, streaming-first, a collector
7
- * failure reported as evidence rather than swallowed — but for a different
8
- * marker on the same stream.
2
+ * `ExternalRequestCollector`: translates `fetch-instrumentation.ts`'s
3
+ * captured requests into `EXTERNAL_REQUEST` Evidence. Same shape as
4
+ * `DatabaseQueryCollector` (RT-141) — `ProcessOutputSource` in, `Evidence`
5
+ * out, failures reported as evidence — for a different marker on the same
6
+ * stream.
9
7
  *
10
- * **What this collector does not do, named rather than silently absent:**
11
- * no request/response body capture (the preload never reads either stream —
12
- * see `fetch-instrumentation.ts`'s own "read, not write" note), no
13
- * provider classification beyond a request's own hostname
14
- * (`service-identity.ts`), and `graphNodeId` is always null — no resolver
15
- * from a captured hostname to any graph node exists (nothing in the 15
16
- * canonical node types names an external service). All real §18 rows, left
17
- * open rather than guessed at, matching `DatabaseQueryCollector`'s own
18
- * disclosure of the same shape of gap.
8
+ * Does NOT: capture request/response bodies (preload never reads either
9
+ * stream), classify providers beyond hostname (`service-identity.ts`), or
10
+ * set `graphNodeId` (no resolver from a hostname to any of the 15 canonical
11
+ * node types exists). Disclosed gaps, matching `DatabaseQueryCollector`'s own.
19
12
  *
20
- * ## The call-site stack, and why the parser is injected
21
- *
22
- * `stackTrace` used to be hard-null here, and `observe_runtime`'s own header
23
- * gave the reason: *"it parses a log line the application printed and a
24
- * printed line carries no stack."* The line is this package's own marker and
25
- * the preload that writes it runs inside the calling process, so the stack
26
- * was always available — nobody had captured it. It is captured now
27
- * (`fetch-instrumentation.ts`), and this collector attaches it.
28
- *
29
- * Parsing it is **not** this package's job. V8's `Error.stack` format is one
30
- * language's, and this collector observes the marker protocol, which is not.
31
- * So a `StackTraceParser` is an option, supplied by whoever knows which
32
- * runtime is being observed — `RuntimeAdapter.stackTraceParser` is exactly
33
- * that value, already on the seam. Omitted, this collector behaves exactly as
34
- * it did before the capture existed and **says so** in `capabilities()`:
35
- * `stackCapture: unavailable`, with the reason. A half-wired capability that
36
- * quietly reports nothing is the failure mode this project's honest-
37
- * degradation rule exists to prevent.
13
+ * `stackTrace` is parsed via an injected `StackTraceParser` — parsing V8's
14
+ * format is not this package's job, so the observed runtime's own parser
15
+ * (`RuntimeAdapter.stackTraceParser`) is supplied by the caller. Omitted,
16
+ * `capabilities()` reports `stackCapture: unavailable` with the reason
17
+ * rather than silently reporting nothing.
38
18
  */
39
19
  import type { Collector } from "@descryy/runtime-contracts";
40
20
  import type { ProcessOutputSource, StackTraceParser } from "@descryy/runtime-backend-observation";
41
- /** Absolute path to the compiled preload, for a caller building `node --import <this> <app>`. Never imported directly -- loaded by Node itself, in the observed process, before that process's own code runs. */
21
+ /** Absolute path to the compiled preload, for `node --import <this> <app>`. Never imported directly — loaded by Node in the observed process. */
42
22
  export declare const FETCH_PRELOAD_MODULE_PATH: string;
43
23
  export interface ExternalRequestCollectorOptions {
44
24
  readonly source: ProcessOutputSource;
45
- /** Which owned system this collector's evidence should be attributed to (plan §16.7). Null when not applicable. */
25
+ /** Which owned system this evidence should be attributed to. Null when not applicable. */
46
26
  readonly service?: string;
47
27
  /**
48
- * The observed runtime's own stack parser — `RuntimeAdapter.stackTraceParser`.
49
- * Supplied by a caller that knows which language it launched; this package
50
- * knows no language and must not (the IR boundary rule, one layer down).
51
- *
52
- * Omitted means captured stacks are not parsed and `stackTrace` stays
53
- * `null`, which `capabilities()` reports as `stackCapture: unavailable`
54
- * rather than leaving a reader to infer it from an absence.
28
+ * The observed runtime's own stack parser (`RuntimeAdapter.stackTraceParser`)
29
+ * — this package knows no language and must not (IR boundary rule).
30
+ * Omitted means `stackTrace` stays `null`, reported by `capabilities()`
31
+ * as `stackCapture: unavailable` rather than left to infer.
55
32
  */
56
33
  readonly stackTraceParser?: StackTraceParser;
57
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request-collector.d.ts","sourceRoot":"","sources":["../src/request-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAA+F,MAAM,4BAA4B,CAAC;AACzJ,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAOlG,iNAAiN;AACjN,eAAO,MAAM,yBAAyB,QAAwE,CAAC;AAE/G,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,mHAAmH;IACnH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CAC9C;AAmCD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,+BAA+B,GAAG,SAAS,CA+GlG"}
1
+ {"version":3,"file":"request-collector.d.ts","sourceRoot":"","sources":["../src/request-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAA+F,MAAM,4BAA4B,CAAC;AACzJ,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAOlG,iJAAiJ;AACjJ,eAAO,MAAM,yBAAyB,QAAwE,CAAC;AAE/G,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CAC9C;AAgCD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,+BAA+B,GAAG,SAAS,CAqJlG"}
@@ -1,47 +1,27 @@
1
1
  /**
2
- * `ExternalRequestCollector` (plan §18 / checklist §18): translates
3
- * `fetch-instrumentation.ts`'s captured requests into `EXTERNAL_REQUEST`
4
- * Evidence. Same shape as `DatabaseQueryCollector`
5
- * (`@descryy/runtime-database-observation`, RT-141) deliberately — a
6
- * `ProcessOutputSource` in, `Evidence` out, streaming-first, a collector
7
- * failure reported as evidence rather than swallowed — but for a different
8
- * marker on the same stream.
2
+ * `ExternalRequestCollector`: translates `fetch-instrumentation.ts`'s
3
+ * captured requests into `EXTERNAL_REQUEST` Evidence. Same shape as
4
+ * `DatabaseQueryCollector` (RT-141) — `ProcessOutputSource` in, `Evidence`
5
+ * out, failures reported as evidence — for a different marker on the same
6
+ * stream.
9
7
  *
10
- * **What this collector does not do, named rather than silently absent:**
11
- * no request/response body capture (the preload never reads either stream —
12
- * see `fetch-instrumentation.ts`'s own "read, not write" note), no
13
- * provider classification beyond a request's own hostname
14
- * (`service-identity.ts`), and `graphNodeId` is always null — no resolver
15
- * from a captured hostname to any graph node exists (nothing in the 15
16
- * canonical node types names an external service). All real §18 rows, left
17
- * open rather than guessed at, matching `DatabaseQueryCollector`'s own
18
- * disclosure of the same shape of gap.
8
+ * Does NOT: capture request/response bodies (preload never reads either
9
+ * stream), classify providers beyond hostname (`service-identity.ts`), or
10
+ * set `graphNodeId` (no resolver from a hostname to any of the 15 canonical
11
+ * node types exists). Disclosed gaps, matching `DatabaseQueryCollector`'s own.
19
12
  *
20
- * ## The call-site stack, and why the parser is injected
21
- *
22
- * `stackTrace` used to be hard-null here, and `observe_runtime`'s own header
23
- * gave the reason: *"it parses a log line the application printed and a
24
- * printed line carries no stack."* The line is this package's own marker and
25
- * the preload that writes it runs inside the calling process, so the stack
26
- * was always available — nobody had captured it. It is captured now
27
- * (`fetch-instrumentation.ts`), and this collector attaches it.
28
- *
29
- * Parsing it is **not** this package's job. V8's `Error.stack` format is one
30
- * language's, and this collector observes the marker protocol, which is not.
31
- * So a `StackTraceParser` is an option, supplied by whoever knows which
32
- * runtime is being observed — `RuntimeAdapter.stackTraceParser` is exactly
33
- * that value, already on the seam. Omitted, this collector behaves exactly as
34
- * it did before the capture existed and **says so** in `capabilities()`:
35
- * `stackCapture: unavailable`, with the reason. A half-wired capability that
36
- * quietly reports nothing is the failure mode this project's honest-
37
- * degradation rule exists to prevent.
13
+ * `stackTrace` is parsed via an injected `StackTraceParser` — parsing V8's
14
+ * format is not this package's job, so the observed runtime's own parser
15
+ * (`RuntimeAdapter.stackTraceParser`) is supplied by the caller. Omitted,
16
+ * `capabilities()` reports `stackCapture: unavailable` with the reason
17
+ * rather than silently reporting nothing.
38
18
  */
39
19
  import { fileURLToPath } from "node:url";
40
- import { parseRequestLine } from "./request-line-parser.js";
20
+ import { parseRequestLine, parseFetchBindingFailureLine } from "./request-line-parser.js";
41
21
  import { extractServiceIdentity } from "./service-identity.js";
42
22
  import { extractHeaderCorrelationIds } from "./header-correlation.js";
43
23
  import { COLLECTOR_VERSION } from "./collector-version.js";
44
- /** Absolute path to the compiled preload, for a caller building `node --import <this> <app>`. Never imported directly -- loaded by Node itself, in the observed process, before that process's own code runs. */
24
+ /** Absolute path to the compiled preload, for `node --import <this> <app>`. Never imported directly — loaded by Node in the observed process. */
45
25
  export const FETCH_PRELOAD_MODULE_PATH = fileURLToPath(new URL("./fetch-instrumentation.js", import.meta.url));
46
26
  const EVENT_TYPE = "EXTERNAL_REQUEST";
47
27
  function computeCapabilities(hasStackParser) {
@@ -52,15 +32,12 @@ function computeCapabilities(hasStackParser) {
52
32
  consoleObservation: status,
53
33
  networkObservation: status,
54
34
  backendLogAccess: status,
55
- // Real HTTP headers, structurally read (Headers/Request, not text
56
- // parsed) -- the same mechanism and the same claim strength
57
- // BrowserNetworkCollector already makes for its own captured requests.
35
+ // Real HTTP headers, structurally read (Headers/Request), same claim
36
+ // strength BrowserNetworkCollector makes for its own captured requests.
58
37
  distributedTrace: { availability: "available", reason: null },
59
38
  sourceMapping: status,
60
- // Real: the preload captures the application's own stack at the fetch
61
- // call site, in the observed process, before the call leaves it. Claimed
62
- // only when a parser was actually supplied to turn it into frames --
63
- // capturing text nothing can read is not a capability.
39
+ // Claimed only when a parser was actually supplied — capturing text
40
+ // nothing can read is not a capability.
64
41
  stackCapture: hasStackParser
65
42
  ? { availability: "available", reason: null }
66
43
  : {
@@ -77,12 +54,11 @@ export function createExternalRequestCollector(options) {
77
54
  const capabilities = computeCapabilities(options.stackTraceParser !== undefined);
78
55
  let consumeLoopDone;
79
56
  let consumptionFailure = null;
80
- /**
81
- * `null` for every honest reason it can be: nothing captured, no parser
82
- * supplied, or a parser that refused the text outright. A parser's `null`
83
- * is its own contract ("not recognizable as this parser's format, never a
84
- * best-effort guess") and is passed through rather than softened.
85
- */
57
+ // C-F6: set once FETCH_BINDING_FAILURE_MARKER is seen — the preload found
58
+ // no real `globalThis.fetch`, so no call was ever observed. Before this,
59
+ // capabilities() kept reporting "available" regardless.
60
+ let bindingFailure = null;
61
+ /** `null` for nothing captured, no parser, or a parser that refused the text — passed through rather than softened. */
86
62
  async function parseStack(request) {
87
63
  if (request.stack === null || options.stackTraceParser === undefined)
88
64
  return null;
@@ -94,7 +70,7 @@ export function createExternalRequestCollector(options) {
94
70
  context.emit({
95
71
  timestamp: new Date().toISOString(),
96
72
  source: "backend-process",
97
- service: options.service ?? null,
73
+ service: options.source.serviceName ?? options.service ?? null,
98
74
  process: options.source.processId,
99
75
  eventType: EVENT_TYPE,
100
76
  payload: {
@@ -110,20 +86,47 @@ export function createExternalRequestCollector(options) {
110
86
  traceId,
111
87
  requestId,
112
88
  correlationId: null,
113
- // No resolver from a captured hostname to a graph node exists --
114
- // none of the 15 canonical node types names an external service.
89
+ // No resolver from a hostname to a graph node exists — none of the
90
+ // 15 canonical node types names an external service.
115
91
  graphNodeId: null,
116
92
  sourceLocation: null,
117
93
  stackTrace,
118
- // The observation itself (a real captured call, real timing, real
119
- // status/failure) is not probabilistic.
120
- confidence: 1,
94
+ confidence: 1, // a real captured call, real timing — not probabilistic
95
+ redactionStatus: "pending-redaction",
96
+ collectorVersion: COLLECTOR_VERSION,
97
+ });
98
+ }
99
+ function emitBindingFailure(reason, context) {
100
+ bindingFailure = reason;
101
+ context.emit({
102
+ timestamp: new Date().toISOString(),
103
+ source: "backend-process",
104
+ service: options.source.serviceName ?? options.service ?? null,
105
+ process: options.source.processId,
106
+ eventType: "COLLECTOR_ERROR",
107
+ payload: {
108
+ raw: `external request collector for process "${options.source.processId}": the fetch preload could not bind -- ${reason}. No outbound call in this process can be observed.`,
109
+ collectorId: `external-request-collector:${options.source.processId}`,
110
+ error: reason,
111
+ },
112
+ traceId: null,
113
+ requestId: null,
114
+ correlationId: null,
115
+ graphNodeId: null,
116
+ sourceLocation: null,
117
+ stackTrace: null,
118
+ confidence: 1, // our own failure to bind, not an inference about the app
121
119
  redactionStatus: "pending-redaction",
122
120
  collectorVersion: COLLECTOR_VERSION,
123
121
  });
124
122
  }
125
123
  async function consume(context) {
126
124
  for await (const line of options.source.lines) {
125
+ const binding = parseFetchBindingFailureLine(line.text);
126
+ if (binding !== null) {
127
+ emitBindingFailure(binding.reason, context);
128
+ continue;
129
+ }
127
130
  const request = parseRequestLine(line.text);
128
131
  if (request !== null)
129
132
  await emitCapturedRequest(request, context);
@@ -139,7 +142,7 @@ export function createExternalRequestCollector(options) {
139
142
  context.emit({
140
143
  timestamp: new Date().toISOString(),
141
144
  source: "backend-process",
142
- service: options.service ?? null,
145
+ service: options.source.serviceName ?? options.service ?? null,
143
146
  process: options.source.processId,
144
147
  eventType: "COLLECTOR_ERROR",
145
148
  payload: {
@@ -168,6 +171,17 @@ export function createExternalRequestCollector(options) {
168
171
  await consumeLoopDone;
169
172
  },
170
173
  capabilities() {
174
+ // Binding failure takes priority — externalServiceObservation was
175
+ // never real for this process, worse than "stopped early" below.
176
+ if (bindingFailure !== null) {
177
+ return {
178
+ ...capabilities,
179
+ externalServiceObservation: {
180
+ availability: "unavailable",
181
+ reason: `the fetch preload never bound a real globalThis.fetch (${bindingFailure}) -- no outbound call in this process was observed.`,
182
+ },
183
+ };
184
+ }
171
185
  if (consumptionFailure === null)
172
186
  return capabilities;
173
187
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"request-collector.js","sourceRoot":"","sources":["../src/request-collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request-collector.js","sourceRoot":"","sources":["../src/request-collector.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,25 @@
1
1
  /**
2
- * Reads one process-output line for the `REQUEST_MARKER` prefix.
3
- *
4
- * The marker comes from `request-marker.ts`, never from
5
- * `fetch-instrumentation.ts` — importing the emitter to get a string would
6
- * patch the parsing process's own `globalThis.fetch`. See `request-marker.ts`
7
- * for the measurement. Everything else — the application's own real
8
- * stdout/stderr — is not this parser's concern and is left alone; an
9
- * external-request collector does not also try to be a log collector.
2
+ * Reads one process-output line for the `REQUEST_MARKER` prefix. The
3
+ * marker comes from `request-marker.ts`, never `fetch-instrumentation.ts`
4
+ * — importing the emitter would patch the parsing process's own fetch.
5
+ * Everything else (the app's real stdout/stderr) is left alone.
10
6
  */
11
- import { REQUEST_MARKER, type CapturedRequest } from "./request-marker.ts";
7
+ import { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER, type CapturedRequest } from "./request-marker.ts";
12
8
  /**
13
- * `null` for a non-matching line (ordinary application output) AND for a
14
- * line that starts with the marker but fails to parse as one of this
15
- * package's own captured requests — a malformed marker line is refused,
16
- * never guessed at, the same distinction `parseQueryLine`
17
- * (`@descryy/runtime-database-observation`) makes.
9
+ * `null` for a non-matching line AND for a marker-prefixed line that fails
10
+ * to parse — malformed is refused, never guessed at, same as
11
+ * `parseQueryLine` (`@descryy/runtime-database-observation`).
18
12
  */
19
13
  export declare function parseRequestLine(line: string): CapturedRequest | null;
14
+ /**
15
+ * C-F6: recognises the preload's disclosure that it found no real
16
+ * `globalThis.fetch`. `null` for every other line. A malformed line past
17
+ * the marker prefix still counts as a binding failure (the marker itself is
18
+ * the fact that matters) with a generic reason substituted.
19
+ */
20
+ export declare function parseFetchBindingFailureLine(line: string): {
21
+ readonly reason: string;
22
+ } | null;
20
23
  export type { CapturedRequest };
21
- export { REQUEST_MARKER };
24
+ export { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER };
22
25
  //# sourceMappingURL=request-line-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-line-parser.d.ts","sourceRoot":"","sources":["../src/request-line-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAsB3E;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAcrE;AAED,YAAY,EAAE,eAAe,EAAE,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"request-line-parser.d.ts","sourceRoot":"","sources":["../src/request-line-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAmBzG;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAarE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS7F;AAED,YAAY,EAAE,eAAe,EAAE,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,CAAC"}
@@ -1,14 +1,10 @@
1
1
  /**
2
- * Reads one process-output line for the `REQUEST_MARKER` prefix.
3
- *
4
- * The marker comes from `request-marker.ts`, never from
5
- * `fetch-instrumentation.ts` — importing the emitter to get a string would
6
- * patch the parsing process's own `globalThis.fetch`. See `request-marker.ts`
7
- * for the measurement. Everything else — the application's own real
8
- * stdout/stderr — is not this parser's concern and is left alone; an
9
- * external-request collector does not also try to be a log collector.
2
+ * Reads one process-output line for the `REQUEST_MARKER` prefix. The
3
+ * marker comes from `request-marker.ts`, never `fetch-instrumentation.ts`
4
+ * — importing the emitter would patch the parsing process's own fetch.
5
+ * Everything else (the app's real stdout/stderr) is left alone.
10
6
  */
11
- import { REQUEST_MARKER } from "./request-marker.js";
7
+ import { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER } from "./request-marker.js";
12
8
  function isCapturedRequest(value) {
13
9
  if (typeof value !== "object" || value === null)
14
10
  return false;
@@ -23,22 +19,17 @@ function isCapturedRequest(value) {
23
19
  return false;
24
20
  if (typeof v.requestHeaders !== "object" || v.requestHeaders === null)
25
21
  return false;
26
- // `stack` is the one field allowed to be absent. A marker line written by a
27
- // preload from before call-site capture existed is a well-formed line that
28
- // genuinely carries no stack -- normalised to `null` below, which is what
29
- // "no stack was captured" already means everywhere downstream. Anything
30
- // present but not a string is malformed and refused, same as every other
31
- // field here.
22
+ // `stack` is the one field allowed to be absent (a pre-capture marker
23
+ // line genuinely carries none) — normalised to `null` below. Present but
24
+ // not a string is malformed and refused like every other field.
32
25
  if (v.stack !== undefined && v.stack !== null && typeof v.stack !== "string")
33
26
  return false;
34
27
  return Object.values(v.requestHeaders).every((value) => typeof value === "string");
35
28
  }
36
29
  /**
37
- * `null` for a non-matching line (ordinary application output) AND for a
38
- * line that starts with the marker but fails to parse as one of this
39
- * package's own captured requests — a malformed marker line is refused,
40
- * never guessed at, the same distinction `parseQueryLine`
41
- * (`@descryy/runtime-database-observation`) makes.
30
+ * `null` for a non-matching line AND for a marker-prefixed line that fails
31
+ * to parse — malformed is refused, never guessed at, same as
32
+ * `parseQueryLine` (`@descryy/runtime-database-observation`).
42
33
  */
43
34
  export function parseRequestLine(line) {
44
35
  if (!line.startsWith(`${REQUEST_MARKER} `))
@@ -53,10 +44,27 @@ export function parseRequestLine(line) {
53
44
  }
54
45
  if (!isCapturedRequest(parsed))
55
46
  return null;
56
- // Absent `stack` becomes an explicit `null` so no consumer has to
57
- // distinguish "the field was missing" from "nothing was captured" -- they
58
- // are the same fact and only one of them is representable downstream.
47
+ // Absent `stack` becomes explicit `null` — "missing" and "not captured"
48
+ // are the same fact downstream.
59
49
  return { ...parsed, stack: parsed.stack ?? null };
60
50
  }
61
- export { REQUEST_MARKER };
51
+ /**
52
+ * C-F6: recognises the preload's disclosure that it found no real
53
+ * `globalThis.fetch`. `null` for every other line. A malformed line past
54
+ * the marker prefix still counts as a binding failure (the marker itself is
55
+ * the fact that matters) with a generic reason substituted.
56
+ */
57
+ export function parseFetchBindingFailureLine(line) {
58
+ if (!line.startsWith(`${FETCH_BINDING_FAILURE_MARKER} `))
59
+ return null;
60
+ const json = line.slice(FETCH_BINDING_FAILURE_MARKER.length + 1);
61
+ try {
62
+ const parsed = JSON.parse(json);
63
+ return { reason: typeof parsed.reason === "string" ? parsed.reason : "no real globalThis.fetch was found to instrument" };
64
+ }
65
+ catch {
66
+ return { reason: "no real globalThis.fetch was found to instrument" };
67
+ }
68
+ }
69
+ export { REQUEST_MARKER, FETCH_BINDING_FAILURE_MARKER };
62
70
  //# sourceMappingURL=request-line-parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-line-parser.js","sourceRoot":"","sources":["../src/request-line-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAwB,MAAM,qBAAqB,CAAC;AAI3E,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrF,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpE,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpF,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,wEAAwE;IACxE,yEAAyE;IACzE,cAAc;IACd,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3F,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,cAAyC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AAChH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,kEAAkE;IAClE,0EAA0E;IAC1E,sEAAsE;IACtE,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AACpD,CAAC;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"request-line-parser.js","sourceRoot":"","sources":["../src/request-line-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAwB,MAAM,qBAAqB,CAAC;AAIzG,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrF,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpE,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpF,sEAAsE;IACtE,yEAAyE;IACzE,gEAAgE;IAChE,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3F,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,cAAyC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AAChH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,wEAAwE;IACxE,gCAAgC;IAChC,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAAY;IACvD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,4BAA4B,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAyB,CAAC;QACxD,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,kDAAkD,EAAE,CAAC;IAC5H,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC;IACxE,CAAC;AACH,CAAC;AAGD,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,CAAC"}
@@ -1,50 +1,37 @@
1
1
  /**
2
- * The wire vocabulary shared by the two halves of external-service
3
- * observation: the marker prefix and the shape that follows it.
4
- *
5
- * This module exists to be **free of side effects**, and that is its entire
6
- * job. `fetch-instrumentation.ts` — the other holder of these names until now
7
- * — replaces `globalThis.fetch` at module scope and writes to stdout, which
8
- * is right for a `--import` preload inside an observed process and wrong
9
- * everywhere else. `request-line-parser.ts` needed nothing from it but the
10
- * string `"DESCRY_EXTERNAL_REQUEST"`, and importing a string is still
11
- * importing a module: the patch and the stdout writer came along, through the
12
- * package index, into every consumer.
13
- *
14
- * **This is `query-marker.ts`'s defect, one package over, and it was still
15
- * open.** `@descryy/runtime-database-observation` found the identical shape,
16
- * measured it into `@descryy/mcp`'s JSON-RPC transport — 14,906 marker lines
17
- * in one `analyze` call — and carved the vocabulary out. Nothing did the same
18
- * here, and nothing noticed, because nothing outside this repository imports
19
- * this package yet. `observe_runtime` consuming this collector is precisely
20
- * the change that would have noticed.
21
- *
22
- * So: the emitter imports the vocabulary, the parser imports the vocabulary,
23
- * and neither imports the other. Anything added here must stay a constant or
24
- * a type. A function with a module-scope effect would rebuild the same trap
25
- * one file over.
2
+ * The wire vocabulary shared by both halves of external-service observation:
3
+ * marker prefix + shape. Must stay free of side effects — a function with a
4
+ * module-scope effect (like `fetch-instrumentation.ts`'s fetch patch) would
5
+ * leak into every consumer that only needs the vocabulary. This is
6
+ * `query-marker.ts`'s defect (measured: 14,906 marker lines through
7
+ * `@descryy/mcp`'s JSON-RPC transport in one `analyze` call), carved out
8
+ * here before anything hit it the same way.
26
9
  */
27
10
  export declare const REQUEST_MARKER = "DESCRY_EXTERNAL_REQUEST";
11
+ /**
12
+ * C-F6: written once, by `fetch-instrumentation.ts`, when `globalThis.fetch`
13
+ * wasn't a real function at preload time — a distinct line from
14
+ * `REQUEST_MARKER`, since nothing was actually observed. Without this, a
15
+ * missing real `fetch` would surface as an ordinary failure indistinguishable
16
+ * from a real network error, and `capabilities()` would claim "available"
17
+ * when zero calls were ever seen.
18
+ */
19
+ export declare const FETCH_BINDING_FAILURE_MARKER = "DESCRY_EXTERNAL_REQUEST_FETCH_BINDING_FAILED";
28
20
  export interface CapturedRequest {
29
21
  readonly url: string;
30
22
  readonly method: string;
31
23
  readonly requestHeaders: Readonly<Record<string, string>>;
32
- /** `null` only when `success` is `false` -- the call never resolved to a response at all. */
24
+ /** `null` only when `success` is `false` — the call never resolved to a response. */
33
25
  readonly status: number | null;
34
26
  readonly durationMs: number;
35
- /** `true` iff `fetch` resolved rather than threw. An HTTP error status (4xx/5xx) is still `success: true` -- fetch itself does not reject on one. */
27
+ /** `true` iff `fetch` resolved rather than threw. A 4xx/5xx status is still `success: true` — fetch doesn't reject on one. */
36
28
  readonly success: boolean;
37
29
  readonly error: string | null;
38
30
  /**
39
- * The **application's** own stack at the moment it called `fetch`, raw and
40
- * unparsed, with the preload's own wrapper frames removed. `null` when the
41
- * runtime produced no stack at all, or when nothing but the preload's own
42
- * frames was in it.
43
- *
44
- * Raw text on purpose: parsing V8's format is
45
- * `@descryy/runtime-adapter-typescript`'s job and belongs in the observing
46
- * process, the same read-here/interpret-there split every marker in this
47
- * repository already uses.
31
+ * The application's own stack at the `fetch` call, raw and unparsed, with
32
+ * the preload's wrapper frames removed. `null` if the runtime produced no
33
+ * stack. Raw text on purpose — parsing V8's format belongs in the
34
+ * observing process (`@descryy/runtime-adapter-typescript`), not here.
48
35
  */
49
36
  readonly stack: string | null;
50
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request-marker.d.ts","sourceRoot":"","sources":["../src/request-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,eAAO,MAAM,cAAc,4BAA8C,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qJAAqJ;IACrJ,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B"}
1
+ {"version":3,"file":"request-marker.d.ts","sourceRoot":"","sources":["../src/request-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,eAAO,MAAM,cAAc,4BAA8C,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,iDAAmE,CAAC;AAE7G,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,qFAAqF;IACrF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8HAA8H;IAC9H,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B"}
@@ -1,32 +1,23 @@
1
1
  /**
2
- * The wire vocabulary shared by the two halves of external-service
3
- * observation: the marker prefix and the shape that follows it.
4
- *
5
- * This module exists to be **free of side effects**, and that is its entire
6
- * job. `fetch-instrumentation.ts` — the other holder of these names until now
7
- * — replaces `globalThis.fetch` at module scope and writes to stdout, which
8
- * is right for a `--import` preload inside an observed process and wrong
9
- * everywhere else. `request-line-parser.ts` needed nothing from it but the
10
- * string `"DESCRY_EXTERNAL_REQUEST"`, and importing a string is still
11
- * importing a module: the patch and the stdout writer came along, through the
12
- * package index, into every consumer.
13
- *
14
- * **This is `query-marker.ts`'s defect, one package over, and it was still
15
- * open.** `@descryy/runtime-database-observation` found the identical shape,
16
- * measured it into `@descryy/mcp`'s JSON-RPC transport — 14,906 marker lines
17
- * in one `analyze` call — and carved the vocabulary out. Nothing did the same
18
- * here, and nothing noticed, because nothing outside this repository imports
19
- * this package yet. `observe_runtime` consuming this collector is precisely
20
- * the change that would have noticed.
21
- *
22
- * So: the emitter imports the vocabulary, the parser imports the vocabulary,
23
- * and neither imports the other. Anything added here must stay a constant or
24
- * a type. A function with a module-scope effect would rebuild the same trap
25
- * one file over.
2
+ * The wire vocabulary shared by both halves of external-service observation:
3
+ * marker prefix + shape. Must stay free of side effects — a function with a
4
+ * module-scope effect (like `fetch-instrumentation.ts`'s fetch patch) would
5
+ * leak into every consumer that only needs the vocabulary. This is
6
+ * `query-marker.ts`'s defect (measured: 14,906 marker lines through
7
+ * `@descryy/mcp`'s JSON-RPC transport in one `analyze` call), carved out
8
+ * here before anything hit it the same way.
26
9
  */
27
10
  import { RESERVED_MARKER_PREFIX } from "@descryy/runtime-contracts";
28
- // Derived, not spelled again: `RESERVED_MARKER_PREFIX` is what the
29
- // backend log collector skips on, so a marker that did not use it would
30
- // come back as the application's own log output.
11
+ // Derived from `RESERVED_MARKER_PREFIX`, which the backend log collector
12
+ // skips on — a marker not using it would look like app log output.
31
13
  export const REQUEST_MARKER = `${RESERVED_MARKER_PREFIX}EXTERNAL_REQUEST`;
14
+ /**
15
+ * C-F6: written once, by `fetch-instrumentation.ts`, when `globalThis.fetch`
16
+ * wasn't a real function at preload time — a distinct line from
17
+ * `REQUEST_MARKER`, since nothing was actually observed. Without this, a
18
+ * missing real `fetch` would surface as an ordinary failure indistinguishable
19
+ * from a real network error, and `capabilities()` would claim "available"
20
+ * when zero calls were ever seen.
21
+ */
22
+ export const FETCH_BINDING_FAILURE_MARKER = `${RESERVED_MARKER_PREFIX}EXTERNAL_REQUEST_FETCH_BINDING_FAILED`;
32
23
  //# sourceMappingURL=request-marker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-marker.js","sourceRoot":"","sources":["../src/request-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,mEAAmE;AACnE,wEAAwE;AACxE,iDAAiD;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,sBAAsB,kBAAkB,CAAC"}
1
+ {"version":3,"file":"request-marker.js","sourceRoot":"","sources":["../src/request-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,yEAAyE;AACzE,mEAAmE;AACnE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,sBAAsB,kBAAkB,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,sBAAsB,uCAAuC,CAAC"}
@@ -1,21 +1,9 @@
1
1
  /**
2
- * A captured request's "service identity" — the checklist's §18 own
3
- * `service identity` row — is its URL's hostname, and nothing more.
4
- *
5
- * **Declared, never inferred.** This does not attempt to recognise "this
6
- * hostname is Stripe" or classify a call into `authentication provider` /
7
- * `payment provider` / etc. (§18's own "Potential integrations" list) —
8
- * that would be a lookup table of well-known hosts this project has no
9
- * source of truth for, guessed rather than read off anything the
10
- * application declared. The hostname is a real, observed fact; a provider
11
- * label would not be. If a consumer wants a friendlier name for a known
12
- * host, that is a later, disclosed classification step layered on top of
13
- * this, not something this function silently does.
14
- *
15
- * `null` for a URL that does not parse — refused rather than guessed, the
16
- * same shape `extractTargetTable`
17
- * (`@descryy/runtime-database-observation`) refuses a SQL statement it does
18
- * not recognise.
2
+ * A captured request's "service identity" is its URL's hostname, nothing
3
+ * more. Never classified into "Stripe" / "payment provider" etc — no
4
+ * source of truth for that, and a guessed label isn't an observed fact.
5
+ * `null` for a URL that doesn't parse — refused rather than guessed, same
6
+ * as `extractTargetTable` (`@descryy/runtime-database-observation`).
19
7
  */
20
8
  export declare function extractServiceIdentity(url: string): string | null;
21
9
  //# sourceMappingURL=service-identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-identity.d.ts","sourceRoot":"","sources":["../src/service-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMjE"}
1
+ {"version":3,"file":"service-identity.d.ts","sourceRoot":"","sources":["../src/service-identity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMjE"}
@@ -1,21 +1,9 @@
1
1
  /**
2
- * A captured request's "service identity" — the checklist's §18 own
3
- * `service identity` row — is its URL's hostname, and nothing more.
4
- *
5
- * **Declared, never inferred.** This does not attempt to recognise "this
6
- * hostname is Stripe" or classify a call into `authentication provider` /
7
- * `payment provider` / etc. (§18's own "Potential integrations" list) —
8
- * that would be a lookup table of well-known hosts this project has no
9
- * source of truth for, guessed rather than read off anything the
10
- * application declared. The hostname is a real, observed fact; a provider
11
- * label would not be. If a consumer wants a friendlier name for a known
12
- * host, that is a later, disclosed classification step layered on top of
13
- * this, not something this function silently does.
14
- *
15
- * `null` for a URL that does not parse — refused rather than guessed, the
16
- * same shape `extractTargetTable`
17
- * (`@descryy/runtime-database-observation`) refuses a SQL statement it does
18
- * not recognise.
2
+ * A captured request's "service identity" is its URL's hostname, nothing
3
+ * more. Never classified into "Stripe" / "payment provider" etc — no
4
+ * source of truth for that, and a guessed label isn't an observed fact.
5
+ * `null` for a URL that doesn't parse — refused rather than guessed, same
6
+ * as `extractTargetTable` (`@descryy/runtime-database-observation`).
19
7
  */
20
8
  export function extractServiceIdentity(url) {
21
9
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"service-identity.js","sourceRoot":"","sources":["../src/service-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"service-identity.js","sourceRoot":"","sources":["../src/service-identity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@descryy/runtime-external-service-observation",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
- "description": "External service observation (plan §18, checklist §18): real EXTERNAL_REQUEST capture via client instrumentation, never parsed application logs. Client #1 is the global fetch.",
5
+ "description": "External service observation (plan \u00a718, checklist \u00a718): real EXTERNAL_REQUEST capture via client instrumentation, never parsed application logs. Client #1 is the global fetch.",
6
6
  "license": "UNLICENSED",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/descryhq-wq/descry-runtime.git",
10
+ "directory": "packages/external-service-observation"
11
+ },
7
12
  "engines": {
8
13
  "node": ">=22.5"
9
14
  },
@@ -24,8 +29,8 @@
24
29
  "build": "tsc -b"
25
30
  },
26
31
  "dependencies": {
27
- "@descryy/runtime-contracts": "0.1.0",
28
- "@descryy/runtime-backend-observation": "0.1.0"
32
+ "@descryy/runtime-contracts": "0.3.0",
33
+ "@descryy/runtime-backend-observation": "0.3.0"
29
34
  },
30
35
  "devDependencies": {
31
36
  "@descryy/runtime-controller": "*",