@descryy/runtime-graph-correlator 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.
- package/dist/confirm-observed-caller.d.ts +92 -0
- package/dist/confirm-observed-caller.d.ts.map +1 -0
- package/dist/confirm-observed-caller.js +117 -0
- package/dist/confirm-observed-caller.js.map +1 -0
- package/dist/database-table.d.ts +40 -0
- package/dist/database-table.d.ts.map +1 -0
- package/dist/database-table.js +52 -0
- package/dist/database-table.js.map +1 -0
- package/dist/endpoint.d.ts +73 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/endpoint.js +115 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/frontend-caller.d.ts +67 -0
- package/dist/frontend-caller.d.ts.map +1 -0
- package/dist/frontend-caller.js +87 -0
- package/dist/frontend-caller.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/log-endpoint.d.ts +67 -0
- package/dist/log-endpoint.d.ts.map +1 -0
- package/dist/log-endpoint.js +97 -0
- package/dist/log-endpoint.js.map +1 -0
- package/dist/observed-frontend-caller.d.ts +70 -0
- package/dist/observed-frontend-caller.d.ts.map +1 -0
- package/dist/observed-frontend-caller.js +103 -0
- package/dist/observed-frontend-caller.js.map +1 -0
- package/dist/symbol.d.ts +244 -0
- package/dist/symbol.d.ts.map +1 -0
- package/dist/symbol.js +344 -0
- package/dist/symbol.js.map +1 -0
- package/package.json +31 -0
package/dist/symbol.d.ts
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving source-mapped evidence (a stack frame or backend log line naming
|
|
3
|
+
* a file + symbol) to the `FUNCTION`/`CLASS` node it came from.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `endpoint.ts`, this *is* a "wrong repository" risk: `FUNCTION` and
|
|
6
|
+
* `CLASS` are repo-scoped (DEC-054), and a runtime session that merges more
|
|
7
|
+
* than one repository into one store (frontend + backend, to trace across
|
|
8
|
+
* them — DEC-228) can hold two same-named, same-relative-path symbols that
|
|
9
|
+
* belong to different repositories. `repo` is therefore required here, not
|
|
10
|
+
* optional — there is no honest default for it, and guessing one is exactly
|
|
11
|
+
* the failure `resolveOneNode` (descry-core's own MCP lookup) refuses to
|
|
12
|
+
* make. This function inherits that discipline rather than reimplementing
|
|
13
|
+
* it differently: return every match, never pick one by heuristic, refuse
|
|
14
|
+
* ambiguity to the caller instead of resolving it silently.
|
|
15
|
+
*
|
|
16
|
+
* `line`, when the caller has one (a stack frame almost always does), is a
|
|
17
|
+
* second, independent check after name+file+repo resolve to exactly one
|
|
18
|
+
* node: does the evidence's own claimed line actually fall inside that
|
|
19
|
+
* node's range? A source map can point at the right *file* and even the
|
|
20
|
+
* right *function name* while still landing on a stale line — a stripped
|
|
21
|
+
* build, a moved function whose body shifted, a webpack virtual path that
|
|
22
|
+
* resolves near but not into the real range. Name+file+repo agreeing is not
|
|
23
|
+
* the same claim as the line agreeing, so a mismatch is its own outcome
|
|
24
|
+
* (`line-mismatch`) rather than a silent `resolved` that hides a real
|
|
25
|
+
* discrepancy, or a `not-found` that discards a symbol that plainly exists.
|
|
26
|
+
*/
|
|
27
|
+
import type { IRNode } from "@descryy/ir";
|
|
28
|
+
import { type SqlDriver } from "@descryy/core";
|
|
29
|
+
export type SymbolResolution = {
|
|
30
|
+
readonly outcome: "resolved";
|
|
31
|
+
readonly node: IRNode;
|
|
32
|
+
} | {
|
|
33
|
+
readonly outcome: "not-found";
|
|
34
|
+
readonly reason: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly outcome: "ambiguous";
|
|
37
|
+
readonly candidates: readonly IRNode[];
|
|
38
|
+
readonly reason: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly outcome: "line-mismatch";
|
|
41
|
+
readonly node: IRNode;
|
|
42
|
+
readonly reason: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function resolveSymbolNode(driver: SqlDriver, location: {
|
|
45
|
+
readonly file: string;
|
|
46
|
+
readonly symbolName: string;
|
|
47
|
+
readonly line?: number;
|
|
48
|
+
}, repo: string,
|
|
49
|
+
/**
|
|
50
|
+
* `cwd`: the directory the process that produced `location.file` was
|
|
51
|
+
* actually launched in. Pass it whenever the caller knows it and the
|
|
52
|
+
* evidence's runtime is one that echoes its invocation argument verbatim
|
|
53
|
+
* (RT-113: Ruby) -- omitting it is not "safer", it is the passthrough
|
|
54
|
+
* behaviour every other caller already relies on for an already
|
|
55
|
+
* repo-relative path.
|
|
56
|
+
*/
|
|
57
|
+
options?: {
|
|
58
|
+
readonly repoRoot?: string;
|
|
59
|
+
readonly cwd?: string;
|
|
60
|
+
}): SymbolResolution;
|
|
61
|
+
/**
|
|
62
|
+
* `resolveSymbolNode`, tried across every repo the caller knows about,
|
|
63
|
+
* for the evidence shape RT-008 names but `resolveSymbolNode` itself
|
|
64
|
+
* cannot serve: a signal with **no known scope at all** (a raw log line
|
|
65
|
+
* naming a symbol, no service/repo hint), arriving into a session that
|
|
66
|
+
* spans more than one repository. `resolveSymbolNode` already refuses
|
|
67
|
+
* ambiguity *within* one repo by requiring `repo` as a mandatory parameter
|
|
68
|
+
* — this function is the layer above that: trying repos in sequence and
|
|
69
|
+
* keeping the first hit would smuggle a guess back in through the one door
|
|
70
|
+
* `resolveSymbolNode` closed, so a match in more than one repo is refused
|
|
71
|
+
* here too, naming every repo that matched.
|
|
72
|
+
*
|
|
73
|
+
* Negative control #1 (`next_tasks.md` T6): two repos, identically-named
|
|
74
|
+
* symbol at the same relative path, no scope given — must refuse, not pick
|
|
75
|
+
* either.
|
|
76
|
+
*/
|
|
77
|
+
export type CrossRepoSymbolResolution = {
|
|
78
|
+
readonly outcome: "resolved";
|
|
79
|
+
readonly repo: string;
|
|
80
|
+
readonly node: IRNode;
|
|
81
|
+
} | {
|
|
82
|
+
readonly outcome: "not-found";
|
|
83
|
+
readonly reason: string;
|
|
84
|
+
} | {
|
|
85
|
+
readonly outcome: "cross-repo-ambiguous";
|
|
86
|
+
readonly matches: readonly {
|
|
87
|
+
readonly repo: string;
|
|
88
|
+
readonly node: IRNode;
|
|
89
|
+
}[];
|
|
90
|
+
readonly reason: string;
|
|
91
|
+
};
|
|
92
|
+
export declare function resolveSymbolAcrossRepos(driver: SqlDriver, location: {
|
|
93
|
+
readonly file: string;
|
|
94
|
+
readonly symbolName: string;
|
|
95
|
+
readonly line?: number;
|
|
96
|
+
}, knownRepos: readonly string[], options?: {
|
|
97
|
+
readonly repoRoot?: string;
|
|
98
|
+
readonly cwd?: string;
|
|
99
|
+
}): CrossRepoSymbolResolution;
|
|
100
|
+
/**
|
|
101
|
+
* The **coarser** answer: which `MODULE` node is declared in the file this
|
|
102
|
+
* evidence named.
|
|
103
|
+
*
|
|
104
|
+
* §10 asks the runtime to correlate evidence to each graph node type where
|
|
105
|
+
* applicable. Measured across `descry-adapters` rather than assumed, the
|
|
106
|
+
* picture for the file-shaped types is:
|
|
107
|
+
*
|
|
108
|
+
* | type | producers | so |
|
|
109
|
+
* | --- | --- | --- |
|
|
110
|
+
* | `MODULE` | 10 of 15 adapters | correlatable, and this is it |
|
|
111
|
+
* | `FILE` | **zero** | nothing to correlate to, on any repository |
|
|
112
|
+
*
|
|
113
|
+
* **`FILE` is not a gap in this file.** No shipped adapter emits one —
|
|
114
|
+
* `descry-core`'s `capabilities/preconditions.ts` records the same fact and
|
|
115
|
+
* exists because three static checks read `nodesOfType("FILE")` and were
|
|
116
|
+
* dead on every real repository while 48 tests stayed green. A runtime
|
|
117
|
+
* resolver targeting `FILE` would reproduce that exactly: a function that
|
|
118
|
+
* always returns `not-found`, indistinguishable from a clean answer.
|
|
119
|
+
*
|
|
120
|
+
* ## Why this is a separate function, not a fallback inside `resolveSymbolNode`
|
|
121
|
+
*
|
|
122
|
+
* A caller must **ask** for the coarser answer. `resolveSymbolNode` silently
|
|
123
|
+
* degrading to a module when the symbol did not resolve would be the
|
|
124
|
+
* honest-degradation rule broken in the one place it matters most: the
|
|
125
|
+
* refusal would disappear, and a consumer would see a resolution where the
|
|
126
|
+
* truth is "we could not find the function, here is the file it claims to be
|
|
127
|
+
* in." Two outcomes that mean different things must not arrive through the
|
|
128
|
+
* same door.
|
|
129
|
+
*
|
|
130
|
+
* ## The outcome is `module-level`, never `resolved`
|
|
131
|
+
*
|
|
132
|
+
* Following RT-055's `sole-structural-caller`: the vocabulary carries the
|
|
133
|
+
* claim's strength at the type level, so a consumer cannot treat a
|
|
134
|
+
* file-granularity answer as a symbol-granularity one by writing
|
|
135
|
+
* `outcome === "resolved"`. This matters for the resolution cap — a finding
|
|
136
|
+
* resting on a module-level correlation knows *which file* failed and does
|
|
137
|
+
* not know *which function*, and those are different findings.
|
|
138
|
+
*/
|
|
139
|
+
export type ModuleResolution = {
|
|
140
|
+
readonly outcome: "module-level";
|
|
141
|
+
readonly node: IRNode;
|
|
142
|
+
} | {
|
|
143
|
+
readonly outcome: "not-found";
|
|
144
|
+
readonly reason: string;
|
|
145
|
+
} | {
|
|
146
|
+
readonly outcome: "ambiguous";
|
|
147
|
+
readonly candidates: readonly IRNode[];
|
|
148
|
+
readonly reason: string;
|
|
149
|
+
};
|
|
150
|
+
export declare function resolveContainingModule(driver: SqlDriver, file: string, repo: string,
|
|
151
|
+
/** See `resolveSymbolNode`'s `cwd` -- same translation, same opt-in. */
|
|
152
|
+
options?: {
|
|
153
|
+
readonly repoRoot?: string;
|
|
154
|
+
readonly cwd?: string;
|
|
155
|
+
}): ModuleResolution;
|
|
156
|
+
/**
|
|
157
|
+
* Resolving an **observed** test — a `test:pass`/`test:fail` event from a real
|
|
158
|
+
* runner, carrying the test's own name, file and line — to the `TEST_CASE`
|
|
159
|
+
* node an adapter minted for it.
|
|
160
|
+
*
|
|
161
|
+
* This is the join that lets a failing test stop being a parallel silo. Once
|
|
162
|
+
* the observed test is a graph node, the `TESTS` edges already leaving that
|
|
163
|
+
* node answer "what does this test cover" with **no runtime guessing at all**
|
|
164
|
+
* — the subject was resolved statically, by an adapter, at index time. The
|
|
165
|
+
* runtime's job is to identify the node, not to infer the relationship.
|
|
166
|
+
*
|
|
167
|
+
* ## Why the fifth outcome exists, and the measurement behind it
|
|
168
|
+
*
|
|
169
|
+
* Counted across `descry-adapters` rather than assumed, by looking for actual
|
|
170
|
+
* node construction (`type: "TEST_CASE"`) rather than references to the
|
|
171
|
+
* string — six of the ten language adapters mention `TEST_CASE` while
|
|
172
|
+
* constructing none, because they use it for the `TESTS` *edge* and for
|
|
173
|
+
* container checks:
|
|
174
|
+
*
|
|
175
|
+
* | | adapters |
|
|
176
|
+
* | --- | --- |
|
|
177
|
+
* | construct `TEST_CASE` nodes | 4 |
|
|
178
|
+
* | mention it, construct none | 6 |
|
|
179
|
+
*
|
|
180
|
+
* So a four-outcome resolver copied from `resolveSymbolNode` would return
|
|
181
|
+
* `not-found` forever for the six, and `not-found` already means *"this graph
|
|
182
|
+
* has no such node"* — which a consumer reads as "that test isn't indexed."
|
|
183
|
+
* The truth is that nothing was ever going to index it. That is the same
|
|
184
|
+
* always-returns-not-found shape that killed the `FILE` resolver idea one
|
|
185
|
+
* function above, displaced rather than avoided, and it is RT-060's
|
|
186
|
+
* producer-versus-consumer attribution restated: a refusal has to say **whose**
|
|
187
|
+
* gap it is.
|
|
188
|
+
*
|
|
189
|
+
* ## `producer-emitted-none` claims exactly what was measured, and no more
|
|
190
|
+
*
|
|
191
|
+
* The name is not `producer-does-not-emit`, because this function cannot
|
|
192
|
+
* observe an adapter — it observes a store. Zero `TEST_CASE` nodes in a
|
|
193
|
+
* language admits two readings: no adapter for that language emits them, or
|
|
194
|
+
* this store simply holds no tests written in it. **Both are producer-side,
|
|
195
|
+
* and neither is "your test is missing"** — which is the whole distinction a
|
|
196
|
+
* consumer needs. The reason string carries the disjunction instead of the
|
|
197
|
+
* outcome name resolving it by fiat.
|
|
198
|
+
*
|
|
199
|
+
* And when the scan truncates, this outcome is **withheld**: a set-property
|
|
200
|
+
* question answered over a silently truncated set is a fact computed from a
|
|
201
|
+
* sample, which is the warning `nodesOfType` carries in its own doc comment.
|
|
202
|
+
* A truncated scan that found nothing degrades to `not-found` naming the
|
|
203
|
+
* truncation, never to a confident claim about a producer.
|
|
204
|
+
*
|
|
205
|
+
* ## This reads `language`; it does not branch on one
|
|
206
|
+
*
|
|
207
|
+
* `IRNode.language` is provenance and must never be branched on above the IR
|
|
208
|
+
* boundary. Nothing here compares it to a literal — no language name appears
|
|
209
|
+
* in this file. It groups by the value the graph itself supplied, the same way
|
|
210
|
+
* `findNodes` narrows by a `repo` string it was handed. A hardcoded set of
|
|
211
|
+
* "languages whose adapters emit TEST_CASE" would have been the violation, and
|
|
212
|
+
* it would also have gone stale the first time an adapter started emitting.
|
|
213
|
+
*/
|
|
214
|
+
export type TestCaseResolution = {
|
|
215
|
+
readonly outcome: "resolved";
|
|
216
|
+
readonly node: IRNode;
|
|
217
|
+
} | {
|
|
218
|
+
readonly outcome: "not-found";
|
|
219
|
+
readonly reason: string;
|
|
220
|
+
} | {
|
|
221
|
+
readonly outcome: "ambiguous";
|
|
222
|
+
readonly candidates: readonly IRNode[];
|
|
223
|
+
readonly reason: string;
|
|
224
|
+
} | {
|
|
225
|
+
readonly outcome: "line-mismatch";
|
|
226
|
+
readonly node: IRNode;
|
|
227
|
+
readonly reason: string;
|
|
228
|
+
} | {
|
|
229
|
+
readonly outcome: "producer-emitted-none";
|
|
230
|
+
readonly language: string | null;
|
|
231
|
+
readonly reason: string;
|
|
232
|
+
};
|
|
233
|
+
export declare function resolveTestCaseNode(driver: SqlDriver, location: {
|
|
234
|
+
readonly file: string;
|
|
235
|
+
readonly testName: string;
|
|
236
|
+
readonly line?: number;
|
|
237
|
+
}, repo: string,
|
|
238
|
+
/** `cwd`: see `resolveSymbolNode`'s doc -- same translation, same opt-in. */
|
|
239
|
+
options?: {
|
|
240
|
+
readonly repoRoot?: string;
|
|
241
|
+
readonly cwd?: string;
|
|
242
|
+
readonly producerScanLimit?: number;
|
|
243
|
+
}): TestCaseResolution;
|
|
244
|
+
//# sourceMappingURL=symbol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbol.d.ts","sourceRoot":"","sources":["../src/symbol.ts"],"names":[],"mappings":"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"}
|
package/dist/symbol.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving source-mapped evidence (a stack frame or backend log line naming
|
|
3
|
+
* a file + symbol) to the `FUNCTION`/`CLASS` node it came from.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `endpoint.ts`, this *is* a "wrong repository" risk: `FUNCTION` and
|
|
6
|
+
* `CLASS` are repo-scoped (DEC-054), and a runtime session that merges more
|
|
7
|
+
* than one repository into one store (frontend + backend, to trace across
|
|
8
|
+
* them — DEC-228) can hold two same-named, same-relative-path symbols that
|
|
9
|
+
* belong to different repositories. `repo` is therefore required here, not
|
|
10
|
+
* optional — there is no honest default for it, and guessing one is exactly
|
|
11
|
+
* the failure `resolveOneNode` (descry-core's own MCP lookup) refuses to
|
|
12
|
+
* make. This function inherits that discipline rather than reimplementing
|
|
13
|
+
* it differently: return every match, never pick one by heuristic, refuse
|
|
14
|
+
* ambiguity to the caller instead of resolving it silently.
|
|
15
|
+
*
|
|
16
|
+
* `line`, when the caller has one (a stack frame almost always does), is a
|
|
17
|
+
* second, independent check after name+file+repo resolve to exactly one
|
|
18
|
+
* node: does the evidence's own claimed line actually fall inside that
|
|
19
|
+
* node's range? A source map can point at the right *file* and even the
|
|
20
|
+
* right *function name* while still landing on a stale line — a stripped
|
|
21
|
+
* build, a moved function whose body shifted, a webpack virtual path that
|
|
22
|
+
* resolves near but not into the real range. Name+file+repo agreeing is not
|
|
23
|
+
* the same claim as the line agreeing, so a mismatch is its own outcome
|
|
24
|
+
* (`line-mismatch`) rather than a silent `resolved` that hides a real
|
|
25
|
+
* discrepancy, or a `not-found` that discards a symbol that plainly exists.
|
|
26
|
+
*/
|
|
27
|
+
import { isAbsolute, relative, resolve as resolvePath } from "node:path";
|
|
28
|
+
import { findNodes, nodesOfType } from "@descryy/core";
|
|
29
|
+
const SYMBOL_NODE_TYPES = new Set(["FUNCTION", "CLASS"]);
|
|
30
|
+
/**
|
|
31
|
+
* **Runtime evidence and the graph do not speak the same path language, and
|
|
32
|
+
* they should not.** A stack frame names an absolute on-disk path — that is
|
|
33
|
+
* what was actually observed, and rewriting it at capture time would
|
|
34
|
+
* destroy the observation. Graph nodes carry repo-relative paths, because a
|
|
35
|
+
* path-dependent identity churns on every checkout location. Something has
|
|
36
|
+
* to translate, and this is the function whose entire job is mapping
|
|
37
|
+
* runtime evidence onto graph entities, so it translates here.
|
|
38
|
+
*
|
|
39
|
+
* **Found by the continuous-chain test, and only by it.** Every earlier
|
|
40
|
+
* test supplied a path in whichever convention it happened to need — the
|
|
41
|
+
* vertical slice pre-relativised with its own helper, the collector tests
|
|
42
|
+
* never resolved to a node — so the two halves each looked right and the
|
|
43
|
+
* seam between them had never been crossed. The first run that crossed it
|
|
44
|
+
* failed with `not-found` on a symbol that plainly exists.
|
|
45
|
+
*
|
|
46
|
+
* **The old failure was worse than a failure: it was a misleading one.**
|
|
47
|
+
* An absolute path simply matched nothing, and the refusal read `No
|
|
48
|
+
* FUNCTION/CLASS node named "deleteInvoice" in
|
|
49
|
+
* "/home/.../server.mjs"` — which a reader takes as "that symbol is not in
|
|
50
|
+
* the graph" when the truth is "you handed me a path in the other
|
|
51
|
+
* coordinate system." Both refusals below now say which of the two it is.
|
|
52
|
+
*
|
|
53
|
+
* Relativising is exact, never a guess: the path must actually live under
|
|
54
|
+
* `repoRoot`, and a path outside it is a **different repository's file**,
|
|
55
|
+
* reported as such. Matching on basename instead would be RT-031's
|
|
56
|
+
* identity-proxy error — `server.mjs` exists in both fixture repos.
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Absolute observed path → repo-relative graph path, or a refusal saying
|
|
60
|
+
* which of the two coordinate systems went wrong.
|
|
61
|
+
*
|
|
62
|
+
* **Shared rather than copied**, because both resolvers in this file must
|
|
63
|
+
* translate identically. A second copy would hold in one of them; measured
|
|
64
|
+
* elsewhere in this project at a two-week silent drift, and here the drift
|
|
65
|
+
* would be between "we found the symbol" and "we found the module in the
|
|
66
|
+
* same file", which no test comparing only outcomes would notice.
|
|
67
|
+
*
|
|
68
|
+
* **A third coordinate system, alongside absolute and repo-relative:
|
|
69
|
+
* relative-to-whatever-cwd-the-process-was-launched-in.** RT-113 measured it
|
|
70
|
+
* against Ruby — a backtrace prints the path exactly as invoked, never
|
|
71
|
+
* normalized — but nothing about the fact is Ruby-specific: any runtime that
|
|
72
|
+
* echoes its own invocation argument verbatim produces the same shape, and
|
|
73
|
+
* this function cannot tell that class of relative path from an
|
|
74
|
+
* already-repo-relative one by looking at it. It can only be told, by a
|
|
75
|
+
* caller that knows the directory the process actually ran in. `cwd` is that
|
|
76
|
+
* signal: passing it is how a caller opts a relative path into this
|
|
77
|
+
* resolution instead of the passthrough below, so every existing caller that
|
|
78
|
+
* never supplies it keeps exactly its old behaviour (`resolveSymbolNode: a
|
|
79
|
+
* relative path still works unchanged`, `symbol.test.ts`). When given, a
|
|
80
|
+
* relative path is resolved against it into an absolute path and handed to
|
|
81
|
+
* the same repoRoot-relativisation the absolute branch already does below —
|
|
82
|
+
* one coordinate translation, not two.
|
|
83
|
+
*/
|
|
84
|
+
function toRepoRelative(file, repo, repoRoot, cwd) {
|
|
85
|
+
if (!isAbsolute(file)) {
|
|
86
|
+
if (cwd === undefined) {
|
|
87
|
+
// A leading `./` is not a second repository's file and not a missing
|
|
88
|
+
// symbol -- it is `rustc`'s own path language. Compiled with a relative
|
|
89
|
+
// source argument (`rustc -g -o bin self-failing-server.rs`, exactly
|
|
90
|
+
// what a managed spawn does), the panic header embeds
|
|
91
|
+
// `./self-failing-server.rs` verbatim; `discover()` (adapter-common)
|
|
92
|
+
// never produces a `./`-prefixed path, so the two would otherwise agree
|
|
93
|
+
// on everything but this one cosmetic prefix and report `not-found`.
|
|
94
|
+
// Stripped unconditionally: a leading `./` never carries identity,
|
|
95
|
+
// unlike `..` which genuinely means "outside" and is left alone.
|
|
96
|
+
//
|
|
97
|
+
// No `cwd` known means no way to distinguish "already repo-relative"
|
|
98
|
+
// from "relative to some other, unrecorded base" -- passthrough is the
|
|
99
|
+
// existing, deliberately narrow default, not a guess that this path is
|
|
100
|
+
// correct.
|
|
101
|
+
return { ok: true, file: file.startsWith("./") ? file.slice(2) : file };
|
|
102
|
+
}
|
|
103
|
+
file = resolvePath(cwd, file);
|
|
104
|
+
}
|
|
105
|
+
if (repoRoot === undefined) {
|
|
106
|
+
return {
|
|
107
|
+
ok: false,
|
|
108
|
+
reason: `Evidence named the absolute path "${file}", but graph nodes carry repo-relative paths. ` +
|
|
109
|
+
`Pass \`repoRoot\` so this can be translated exactly. Reported rather than searched for a ` +
|
|
110
|
+
`suffix match, which would resolve the wrong repository's identically-named file.`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const relativePath = relative(repoRoot, file);
|
|
114
|
+
if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
|
|
115
|
+
return {
|
|
116
|
+
ok: false,
|
|
117
|
+
reason: `Evidence named "${file}", which is not under repo "${repo}"'s root "${repoRoot}" — ` +
|
|
118
|
+
`it belongs to a different repository, not to a missing symbol in this one.`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return { ok: true, file: relativePath };
|
|
122
|
+
}
|
|
123
|
+
export function resolveSymbolNode(driver, location, repo,
|
|
124
|
+
/**
|
|
125
|
+
* `cwd`: the directory the process that produced `location.file` was
|
|
126
|
+
* actually launched in. Pass it whenever the caller knows it and the
|
|
127
|
+
* evidence's runtime is one that echoes its invocation argument verbatim
|
|
128
|
+
* (RT-113: Ruby) -- omitting it is not "safer", it is the passthrough
|
|
129
|
+
* behaviour every other caller already relies on for an already
|
|
130
|
+
* repo-relative path.
|
|
131
|
+
*/
|
|
132
|
+
options = {}) {
|
|
133
|
+
const translated = toRepoRelative(location.file, repo, options.repoRoot, options.cwd);
|
|
134
|
+
if (!translated.ok)
|
|
135
|
+
return { outcome: "not-found", reason: translated.reason };
|
|
136
|
+
const file = translated.file;
|
|
137
|
+
const matches = findNodes(driver, {
|
|
138
|
+
name: location.symbolName,
|
|
139
|
+
file,
|
|
140
|
+
repo,
|
|
141
|
+
limit: 10,
|
|
142
|
+
}).filter((n) => SYMBOL_NODE_TYPES.has(n.type));
|
|
143
|
+
if (matches.length === 0) {
|
|
144
|
+
return {
|
|
145
|
+
outcome: "not-found",
|
|
146
|
+
reason: `No FUNCTION/CLASS node named "${location.symbolName}" in "${file}" within repo ` +
|
|
147
|
+
`"${repo}". This does not mean it does not exist — it may mean no adapter read it, or the ` +
|
|
148
|
+
"graph predates it.",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (matches.length > 1) {
|
|
152
|
+
return {
|
|
153
|
+
outcome: "ambiguous",
|
|
154
|
+
candidates: matches,
|
|
155
|
+
reason: `${matches.length} nodes named "${location.symbolName}" exist in "${file}" within ` +
|
|
156
|
+
`repo "${repo}" — ${matches.map((n) => n.type).join(", ")}. Picking one by a heuristic would ` +
|
|
157
|
+
"be reasoning confidently about a symbol the evidence did not actually distinguish.",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const node = matches[0];
|
|
161
|
+
// `null` joins `undefined` here deliberately: a frame that carried no
|
|
162
|
+
// line (a JVM `Unknown Source` frame) has nothing to check the range
|
|
163
|
+
// against, and treating "no line" as a mismatch would reject a correct
|
|
164
|
+
// name-and-file match on the strength of information nobody captured.
|
|
165
|
+
if (location.line !== undefined && location.line !== null && node.range !== null) {
|
|
166
|
+
const { startLine, endLine } = node.range;
|
|
167
|
+
if (location.line < startLine || location.line > endLine) {
|
|
168
|
+
return {
|
|
169
|
+
outcome: "line-mismatch",
|
|
170
|
+
node,
|
|
171
|
+
reason: `Evidence claims line ${location.line}, but "${location.symbolName}" spans lines ` +
|
|
172
|
+
`${startLine}-${endLine}. Name and file agree; the line does not — treat the source ` +
|
|
173
|
+
"location as unreliable rather than silently trusting the name match.",
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { outcome: "resolved", node };
|
|
178
|
+
}
|
|
179
|
+
export function resolveSymbolAcrossRepos(driver, location, knownRepos, options = {}) {
|
|
180
|
+
const resolved = [];
|
|
181
|
+
for (const repo of knownRepos) {
|
|
182
|
+
const result = resolveSymbolNode(driver, location, repo, options);
|
|
183
|
+
// Only a clean `resolved` counts as a match here -- `ambiguous` (two
|
|
184
|
+
// symbols within that one repo) and `line-mismatch` are that repo's own
|
|
185
|
+
// refusal, not a hit to compare against the other repos' results, and
|
|
186
|
+
// folding them in would understate the ambiguity rather than report it.
|
|
187
|
+
if (result.outcome === "resolved")
|
|
188
|
+
resolved.push({ repo, node: result.node });
|
|
189
|
+
}
|
|
190
|
+
if (resolved.length === 0) {
|
|
191
|
+
return {
|
|
192
|
+
outcome: "not-found",
|
|
193
|
+
reason: `No FUNCTION/CLASS node named "${location.symbolName}" in "${location.file}" was found in any ` +
|
|
194
|
+
`of the ${knownRepos.length} known repositories (${knownRepos.join(", ") || "none"}).`,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
if (resolved.length > 1) {
|
|
198
|
+
return {
|
|
199
|
+
outcome: "cross-repo-ambiguous",
|
|
200
|
+
matches: resolved,
|
|
201
|
+
reason: `"${location.symbolName}" in "${location.file}" resolved in ${resolved.length} different ` +
|
|
202
|
+
`repositories (${resolved.map((m) => m.repo).join(", ")}), and this evidence carries no repo ` +
|
|
203
|
+
"scope to pick one. Trying repos in sequence and keeping the first hit would be a guess; " +
|
|
204
|
+
"refused instead.",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return { outcome: "resolved", repo: resolved[0].repo, node: resolved[0].node };
|
|
208
|
+
}
|
|
209
|
+
export function resolveContainingModule(driver, file, repo,
|
|
210
|
+
/** See `resolveSymbolNode`'s `cwd` -- same translation, same opt-in. */
|
|
211
|
+
options = {}) {
|
|
212
|
+
const translated = toRepoRelative(file, repo, options.repoRoot, options.cwd);
|
|
213
|
+
if (!translated.ok)
|
|
214
|
+
return { outcome: "not-found", reason: translated.reason };
|
|
215
|
+
const relativeFile = translated.file;
|
|
216
|
+
const matches = findNodes(driver, { file: relativeFile, repo, limit: 10 }).filter((n) => n.type === "MODULE");
|
|
217
|
+
if (matches.length === 0) {
|
|
218
|
+
return {
|
|
219
|
+
outcome: "not-found",
|
|
220
|
+
reason: `No MODULE node is declared in "${relativeFile}" within repo "${repo}". Either no adapter read ` +
|
|
221
|
+
"that file, or the adapter that read it does not emit MODULE — ten of fifteen do, so the " +
|
|
222
|
+
"absence is a producer question, not evidence that the file is uninteresting.",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (matches.length > 1) {
|
|
226
|
+
// Two modules declared in one file is legitimate in several languages
|
|
227
|
+
// (Ruby, C#, Python's nested scopes) — the observed file does not say
|
|
228
|
+
// which one the frame was inside, and neither does a line, since module
|
|
229
|
+
// ranges routinely nest. Refused rather than ranked.
|
|
230
|
+
return {
|
|
231
|
+
outcome: "ambiguous",
|
|
232
|
+
candidates: matches,
|
|
233
|
+
reason: `${matches.length} MODULE nodes are declared in "${relativeFile}" within repo "${repo}" — ` +
|
|
234
|
+
`${matches.map((n) => n.name).join(", ")}. A file-level observation cannot say which, and ` +
|
|
235
|
+
"picking the outermost or the first would be a guess dressed as a coarse answer.",
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return { outcome: "module-level", node: matches[0] };
|
|
239
|
+
}
|
|
240
|
+
/** Cap on the `TEST_CASE` scan backing `producer-emitted-none`. Truncation withholds the claim. */
|
|
241
|
+
const PRODUCER_SCAN_LIMIT = 5000;
|
|
242
|
+
export function resolveTestCaseNode(driver, location, repo,
|
|
243
|
+
/** `cwd`: see `resolveSymbolNode`'s doc -- same translation, same opt-in. */
|
|
244
|
+
options = {}) {
|
|
245
|
+
const translated = toRepoRelative(location.file, repo, options.repoRoot, options.cwd);
|
|
246
|
+
if (!translated.ok)
|
|
247
|
+
return { outcome: "not-found", reason: translated.reason };
|
|
248
|
+
const file = translated.file;
|
|
249
|
+
const matches = findNodes(driver, { name: location.testName, file, repo, limit: 10 }).filter((n) => n.type === "TEST_CASE");
|
|
250
|
+
if (matches.length > 1) {
|
|
251
|
+
// Two tests of the same name in one file is ordinary — `describe` blocks
|
|
252
|
+
// nest, and several runners scope a name to its block rather than to the
|
|
253
|
+
// file. The observed event carries a line, but test ranges nest just as
|
|
254
|
+
// module ranges do, so the innermost is not reliably the right one.
|
|
255
|
+
// Refused rather than ranked, exactly as above.
|
|
256
|
+
return {
|
|
257
|
+
outcome: "ambiguous",
|
|
258
|
+
candidates: matches,
|
|
259
|
+
reason: `${matches.length} TEST_CASE nodes named "${location.testName}" exist in "${file}" within ` +
|
|
260
|
+
`repo "${repo}". Test names repeat across nested blocks, and picking by line would rank ` +
|
|
261
|
+
"nested ranges — a guess dressed as a resolution.",
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (matches.length === 1) {
|
|
265
|
+
const node = matches[0];
|
|
266
|
+
if (location.line !== undefined && location.line !== null && node.range !== null) {
|
|
267
|
+
const { startLine, endLine } = node.range;
|
|
268
|
+
if (location.line < startLine || location.line > endLine) {
|
|
269
|
+
return {
|
|
270
|
+
outcome: "line-mismatch",
|
|
271
|
+
node,
|
|
272
|
+
reason: `The runner reported line ${location.line}, but TEST_CASE "${location.testName}" spans ` +
|
|
273
|
+
`lines ${startLine}-${endLine}. Name and file agree; the line does not — the graph is ` +
|
|
274
|
+
"likely older than the file, so treat the node as identified but the position as stale.",
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return { outcome: "resolved", node };
|
|
279
|
+
}
|
|
280
|
+
return explainMissingTestCase(driver, file, repo, location.testName, options.producerScanLimit);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Why nothing matched — the part that has to distinguish four genuinely
|
|
284
|
+
* different situations that all present as an empty result set.
|
|
285
|
+
*
|
|
286
|
+
* Kept separate from the resolver so the resolver reads as one decision, and
|
|
287
|
+
* so this can be exercised directly: three of the four branches need a store
|
|
288
|
+
* shaped a particular way, and reaching them through the happy path would
|
|
289
|
+
* mean every test also depended on name matching working.
|
|
290
|
+
*/
|
|
291
|
+
function explainMissingTestCase(driver, file, repo, testName, scanLimit) {
|
|
292
|
+
const inFile = findNodes(driver, { file, repo, limit: 200 });
|
|
293
|
+
// (1) Nothing at all from this file. No adapter read it — an excluded path,
|
|
294
|
+
// an unsupported extension, a file newer than the graph. Reporting a
|
|
295
|
+
// producer claim here would be wrong in a specific way: it would blame the
|
|
296
|
+
// language when the file was never opened.
|
|
297
|
+
if (inFile.length === 0) {
|
|
298
|
+
return {
|
|
299
|
+
outcome: "not-found",
|
|
300
|
+
reason: `No node of any type was produced from "${file}" within repo "${repo}", so the file itself ` +
|
|
301
|
+
"was never read — not excluded from test extraction, excluded from parsing. Check the " +
|
|
302
|
+
"adapter's file selection before concluding anything about test support.",
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const language = inFile.find((n) => n.language !== null)?.language ?? null;
|
|
306
|
+
const limit = scanLimit ?? PRODUCER_SCAN_LIMIT;
|
|
307
|
+
const { nodes: testCases, truncated } = nodesOfType(driver, "TEST_CASE", limit);
|
|
308
|
+
const sameLanguage = testCases.filter((n) => n.language === language);
|
|
309
|
+
if (sameLanguage.length === 0) {
|
|
310
|
+
// (2) The scan hit its cap, so "none" was measured over a sample. The
|
|
311
|
+
// producer claim is withheld rather than made cheaply.
|
|
312
|
+
if (truncated) {
|
|
313
|
+
return {
|
|
314
|
+
outcome: "not-found",
|
|
315
|
+
reason: `No TEST_CASE node named "${testName}" in "${file}". A scan for TEST_CASE nodes of the ` +
|
|
316
|
+
`same provenance found none, but the scan truncated at ${limit} rows — that is a sample, ` +
|
|
317
|
+
"not the set, so no claim about the producer is made from it. Raise `producerScanLimit`.",
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// (3) The whole store holds no TEST_CASE node of this provenance. Not a
|
|
321
|
+
// consumer-side miss, and the reason says so without deciding which of
|
|
322
|
+
// the two producer-side readings applies.
|
|
323
|
+
return {
|
|
324
|
+
outcome: "producer-emitted-none",
|
|
325
|
+
language,
|
|
326
|
+
reason: `This store holds no TEST_CASE node of the same provenance as "${file}" — ${testCases.length} ` +
|
|
327
|
+
"TEST_CASE nodes exist in total, none of them from this language. Either no adapter for it " +
|
|
328
|
+
"emits TEST_CASE, or nothing indexed here is written in it. Both are producer-side: the " +
|
|
329
|
+
`runner observed "${testName}" and the graph was never going to contain it, which is not the ` +
|
|
330
|
+
"same as the test being absent from a graph that could have held it.",
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// (4) The producer does emit for this provenance, and this particular test
|
|
334
|
+
// still is not there — a real consumer-side miss, and the only branch where
|
|
335
|
+
// "the graph does not have your test" is the honest sentence.
|
|
336
|
+
return {
|
|
337
|
+
outcome: "not-found",
|
|
338
|
+
reason: `No TEST_CASE node named "${testName}" in "${file}" within repo "${repo}", though ` +
|
|
339
|
+
`${sameLanguage.length} TEST_CASE nodes of the same provenance exist elsewhere in this store — ` +
|
|
340
|
+
"so the producer does emit them and this one genuinely is not indexed. A renamed test, a " +
|
|
341
|
+
"dynamically generated name, or a graph older than the file.",
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=symbol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbol.js","sourceRoot":"","sources":["../src/symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAGzE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAkB,MAAM,eAAe,CAAC;AAQvE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAS,cAAc,CACrB,IAAY,EACZ,IAAY,EACZ,QAA4B,EAC5B,GAAuB;IAEvB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,qEAAqE;YACrE,wEAAwE;YACxE,qEAAqE;YACrE,sDAAsD;YACtD,qEAAqE;YACrE,wEAAwE;YACxE,qEAAqE;YACrE,mEAAmE;YACnE,iEAAiE;YACjE,EAAE;YACF,qEAAqE;YACrE,uEAAuE;YACvE,uEAAuE;YACvE,WAAW;YACX,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1E,CAAC;QACD,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EACJ,qCAAqC,IAAI,gDAAgD;gBACzF,2FAA2F;gBAC3F,kFAAkF;SACrF,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EACJ,mBAAmB,IAAI,+BAA+B,IAAI,aAAa,QAAQ,MAAM;gBACrF,4EAA4E;SAC/E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,QAAwF,EACxF,IAAY;AACZ;;;;;;;GAOG;AACH,UAAiE,EAAE;IAEnE,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACtF,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IAC/E,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IAE7B,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE;QAChC,IAAI,EAAE,QAAQ,CAAC,UAAU;QACzB,IAAI;QACJ,IAAI;QACJ,KAAK,EAAE,EAAE;KACV,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,MAAM,EACJ,iCAAiC,QAAQ,CAAC,UAAU,SAAS,IAAI,gBAAgB;gBACjF,IAAI,IAAI,mFAAmF;gBAC3F,oBAAoB;SACvB,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,OAAO;YACnB,MAAM,EACJ,GAAG,OAAO,CAAC,MAAM,iBAAiB,QAAQ,CAAC,UAAU,eAAe,IAAI,WAAW;gBACnF,SAAS,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,qCAAqC;gBAC9F,oFAAoF;SACvF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;IAEzB,sEAAsE;IACtE,qEAAqE;IACrE,uEAAuE;IACvE,sEAAsE;IACtE,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACjF,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,GAAG,SAAS,IAAI,QAAQ,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;YACzD,OAAO;gBACL,OAAO,EAAE,eAAe;gBACxB,IAAI;gBACJ,MAAM,EACJ,wBAAwB,QAAQ,CAAC,IAAI,UAAU,QAAQ,CAAC,UAAU,gBAAgB;oBAClF,GAAG,SAAS,IAAI,OAAO,8DAA8D;oBACrF,sEAAsE;aACzE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC;AA2BD,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,QAAwF,EACxF,UAA6B,EAC7B,UAAiE,EAAE;IAEnE,MAAM,QAAQ,GAAqC,EAAE,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAClE,qEAAqE;QACrE,wEAAwE;QACxE,sEAAsE;QACtE,wEAAwE;QACxE,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,MAAM,EACJ,iCAAiC,QAAQ,CAAC,UAAU,SAAS,QAAQ,CAAC,IAAI,qBAAqB;gBAC/F,UAAU,UAAU,CAAC,MAAM,wBAAwB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI;SACzF,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,sBAAsB;YAC/B,OAAO,EAAE,QAAQ;YACjB,MAAM,EACJ,IAAI,QAAQ,CAAC,UAAU,SAAS,QAAQ,CAAC,IAAI,iBAAiB,QAAQ,CAAC,MAAM,aAAa;gBAC1F,iBAAiB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC;gBAC9F,0FAA0F;gBAC1F,kBAAkB;SACrB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;AACnF,CAAC;AA8CD,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,IAAY,EACZ,IAAY;AACZ,wEAAwE;AACxE,UAAiE,EAAE;IAEnE,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7E,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IAC/E,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC;IAErC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAE9G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,MAAM,EACJ,kCAAkC,YAAY,kBAAkB,IAAI,4BAA4B;gBAChG,0FAA0F;gBAC1F,8EAA8E;SACjF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,sEAAsE;QACtE,sEAAsE;QACtE,wEAAwE;QACxE,qDAAqD;QACrD,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,OAAO;YACnB,MAAM,EACJ,GAAG,OAAO,CAAC,MAAM,kCAAkC,YAAY,kBAAkB,IAAI,MAAM;gBAC3F,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mDAAmD;gBAC3F,iFAAiF;SACpF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,CAAC;AACxD,CAAC;AAmED,mGAAmG;AACnG,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,QAAsF,EACtF,IAAY;AACZ,6EAA6E;AAC7E,UAAsG,EAAE;IAExG,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACtF,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IAC/E,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IAE7B,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAC1F,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAC9B,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,oEAAoE;QACpE,gDAAgD;QAChD,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,OAAO;YACnB,MAAM,EACJ,GAAG,OAAO,CAAC,MAAM,2BAA2B,QAAQ,CAAC,QAAQ,eAAe,IAAI,WAAW;gBAC3F,SAAS,IAAI,4EAA4E;gBACzF,kDAAkD;SACrD,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QACzB,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACjF,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1C,IAAI,QAAQ,CAAC,IAAI,GAAG,SAAS,IAAI,QAAQ,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACzD,OAAO;oBACL,OAAO,EAAE,eAAe;oBACxB,IAAI;oBACJ,MAAM,EACJ,4BAA4B,QAAQ,CAAC,IAAI,oBAAoB,QAAQ,CAAC,QAAQ,UAAU;wBACxF,SAAS,SAAS,IAAI,OAAO,0DAA0D;wBACvF,wFAAwF;iBAC3F,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,OAAO,sBAAsB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAClG,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAC7B,MAAiB,EACjB,IAAY,EACZ,IAAY,EACZ,QAAgB,EAChB,SAA6B;IAE7B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAE7D,4EAA4E;IAC5E,qEAAqE;IACrE,2EAA2E;IAC3E,2CAA2C;IAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,MAAM,EACJ,0CAA0C,IAAI,kBAAkB,IAAI,wBAAwB;gBAC5F,uFAAuF;gBACvF,yEAAyE;SAC5E,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;IAC3E,MAAM,KAAK,GAAG,SAAS,IAAI,mBAAmB,CAAC;IAC/C,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IAEtE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,sEAAsE;QACtE,uDAAuD;QACvD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,MAAM,EACJ,4BAA4B,QAAQ,SAAS,IAAI,uCAAuC;oBACxF,yDAAyD,KAAK,4BAA4B;oBAC1F,yFAAyF;aAC5F,CAAC;QACJ,CAAC;QACD,wEAAwE;QACxE,uEAAuE;QACvE,0CAA0C;QAC1C,OAAO;YACL,OAAO,EAAE,uBAAuB;YAChC,QAAQ;YACR,MAAM,EACJ,iEAAiE,IAAI,OAAO,SAAS,CAAC,MAAM,GAAG;gBAC/F,4FAA4F;gBAC5F,yFAAyF;gBACzF,oBAAoB,QAAQ,kEAAkE;gBAC9F,qEAAqE;SACxE,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,4EAA4E;IAC5E,8DAA8D;IAC9D,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,MAAM,EACJ,4BAA4B,QAAQ,SAAS,IAAI,kBAAkB,IAAI,YAAY;YACnF,GAAG,YAAY,CAAC,MAAM,0EAA0E;YAChG,0FAA0F;YAC1F,6DAA6D;KAChE,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@descryy/runtime-graph-correlator",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Resolves runtime evidence to descry-core graph nodes and builds the observed graph path between them. Deliverable of the correlation/graph-integration row — depends on @descryy/runtime-contracts, @descryy/core and @descryy/ir; consumes the graph, does not modify it.",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.5"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"registry": "https://registry.npmjs.org",
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -b"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@descryy/runtime-contracts": "*",
|
|
28
|
+
"@descryy/core": "^0.1.0",
|
|
29
|
+
"@descryy/ir": "^0.1.0"
|
|
30
|
+
}
|
|
31
|
+
}
|