@descryy/ir 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/capabilities.d.ts +83 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +91 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/conformance/bind.d.ts +82 -0
- package/dist/conformance/bind.d.ts.map +1 -0
- package/dist/conformance/bind.js +157 -0
- package/dist/conformance/bind.js.map +1 -0
- package/dist/conformance/cli.d.ts +25 -0
- package/dist/conformance/cli.d.ts.map +1 -0
- package/dist/conformance/cli.js +137 -0
- package/dist/conformance/cli.js.map +1 -0
- package/dist/conformance/compare.d.ts +74 -0
- package/dist/conformance/compare.d.ts.map +1 -0
- package/dist/conformance/compare.js +140 -0
- package/dist/conformance/compare.js.map +1 -0
- package/dist/conformance/compose.d.ts +79 -0
- package/dist/conformance/compose.d.ts.map +1 -0
- package/dist/conformance/compose.js +167 -0
- package/dist/conformance/compose.js.map +1 -0
- package/dist/conformance/golden.d.ts +110 -0
- package/dist/conformance/golden.d.ts.map +1 -0
- package/dist/conformance/golden.js +252 -0
- package/dist/conformance/golden.js.map +1 -0
- package/dist/conformance/index.d.ts +26 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +18 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/conformance/manifest-check.d.ts +78 -0
- package/dist/conformance/manifest-check.d.ts.map +1 -0
- package/dist/conformance/manifest-check.js +149 -0
- package/dist/conformance/manifest-check.js.map +1 -0
- package/dist/conformance/manifest.d.ts +83 -0
- package/dist/conformance/manifest.d.ts.map +1 -0
- package/dist/conformance/manifest.js +158 -0
- package/dist/conformance/manifest.js.map +1 -0
- package/dist/conformance/report.d.ts +14 -0
- package/dist/conformance/report.d.ts.map +1 -0
- package/dist/conformance/report.js +87 -0
- package/dist/conformance/report.js.map +1 -0
- package/dist/conformance/run.d.ts +172 -0
- package/dist/conformance/run.d.ts.map +1 -0
- package/dist/conformance/run.js +626 -0
- package/dist/conformance/run.js.map +1 -0
- package/dist/contracts.d.ts +198 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +10 -0
- package/dist/contracts.js.map +1 -0
- package/dist/contradiction.d.ts +112 -0
- package/dist/contradiction.d.ts.map +1 -0
- package/dist/contradiction.js +97 -0
- package/dist/contradiction.js.map +1 -0
- package/dist/finding.d.ts +567 -0
- package/dist/finding.d.ts.map +1 -0
- package/dist/finding.js +491 -0
- package/dist/finding.js.map +1 -0
- package/dist/hypothesis.d.ts +130 -0
- package/dist/hypothesis.d.ts.map +1 -0
- package/dist/hypothesis.js +116 -0
- package/dist/hypothesis.js.map +1 -0
- package/dist/identity.d.ts +295 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +404 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/ir.d.ts +360 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +76 -0
- package/dist/ir.js.map +1 -0
- package/dist/model-tables.d.ts +111 -0
- package/dist/model-tables.d.ts.map +1 -0
- package/dist/model-tables.js +103 -0
- package/dist/model-tables.js.map +1 -0
- package/dist/normalise.d.ts +114 -0
- package/dist/normalise.d.ts.map +1 -0
- package/dist/normalise.js +603 -0
- package/dist/normalise.js.map +1 -0
- package/dist/reliability.d.ts +89 -0
- package/dist/reliability.d.ts.map +1 -0
- package/dist/reliability.js +181 -0
- package/dist/reliability.js.map +1 -0
- package/dist/tool-surface.d.ts +131 -0
- package/dist/tool-surface.d.ts.map +1 -0
- package/dist/tool-surface.js +133 -0
- package/dist/tool-surface.js.map +1 -0
- package/dist/vocabulary.d.ts +73 -0
- package/dist/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary.js +150 -0
- package/dist/vocabulary.js.map +1 -0
- package/package.json +27 -0
package/dist/ir.d.ts
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Canonical IR — the boundary every language reaches the graph through.
|
|
3
|
+
*
|
|
4
|
+
* Nothing above this boundary may name a language (architecture principle 7).
|
|
5
|
+
* `language` is carried as provenance so findings can be reported honestly; it is
|
|
6
|
+
* never branched on. The boundary lint enforces that mechanically.
|
|
7
|
+
*/
|
|
8
|
+
import type { EdgeType, NodeType } from "./vocabulary.ts";
|
|
9
|
+
/**
|
|
10
|
+
* How well the code behind a node or edge was actually understood.
|
|
11
|
+
*
|
|
12
|
+
* R0 tree-sitter only · R1 + module resolution · R2 + LSP references/definitions
|
|
13
|
+
* · R3 + type checker (shapes) · R4 observed firing at runtime.
|
|
14
|
+
*
|
|
15
|
+
* This is the third confidence axis, alongside reliability class and environment
|
|
16
|
+
* level. It caps the reliability class of any finding resting on it, which is
|
|
17
|
+
* what stops multi-language support meaning multi-language guessing.
|
|
18
|
+
*
|
|
19
|
+
* Includes 4. See DEC-005 — R4 was defined in the architecture's prose but the
|
|
20
|
+
* IR type still read `0 | 1 | 2 | 3`, leaving the stated core moat nowhere to be
|
|
21
|
+
* stored.
|
|
22
|
+
*/
|
|
23
|
+
export type ResolutionLevel = 0 | 1 | 2 | 3 | 4;
|
|
24
|
+
export declare const RESOLUTION_LEVELS: readonly [0, 1, 2, 3, 4];
|
|
25
|
+
/** Inclusive line range within a file. */
|
|
26
|
+
export interface Range {
|
|
27
|
+
readonly startLine: number;
|
|
28
|
+
readonly endLine: number;
|
|
29
|
+
}
|
|
30
|
+
export interface IRNode {
|
|
31
|
+
/**
|
|
32
|
+
* Stable across runs AND across file moves: `n2:` + hash(scope, language, kind,
|
|
33
|
+
* qualified symbol path). Deliberately excludes file path — see DEC-004,
|
|
34
|
+
* DEC-011 and DEC-054.
|
|
35
|
+
*/
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly type: NodeType;
|
|
38
|
+
readonly name: string;
|
|
39
|
+
/** Repo-relative. Null for fileless node types — see DEC-014. */
|
|
40
|
+
readonly file: string | null;
|
|
41
|
+
/** Null wherever `file` is null. */
|
|
42
|
+
readonly range: Range | null;
|
|
43
|
+
/**
|
|
44
|
+
* Provenance only. NEVER branched on above the IR boundary.
|
|
45
|
+
* Null on `API_ENDPOINT`, which belongs to no single language — the Normaliser
|
|
46
|
+
* sets this and rejects any adapter that claims otherwise.
|
|
47
|
+
*/
|
|
48
|
+
readonly language: string | null;
|
|
49
|
+
/** `adapterId@version`. Drives graph invalidation on adapter upgrade. */
|
|
50
|
+
readonly producedBy: string;
|
|
51
|
+
readonly resolution: ResolutionLevel;
|
|
52
|
+
/**
|
|
53
|
+
* Language- and framework-specific detail, opaque above the boundary. This is
|
|
54
|
+
* the pressure valve that keeps the type list at 15: a Django model and a
|
|
55
|
+
* Prisma model are both `MODEL`, and what differs lives here.
|
|
56
|
+
*
|
|
57
|
+
* Never part of node identity.
|
|
58
|
+
*/
|
|
59
|
+
readonly attrs: Readonly<Record<string, unknown>>;
|
|
60
|
+
}
|
|
61
|
+
export interface IREdge {
|
|
62
|
+
readonly from: string;
|
|
63
|
+
readonly to: string;
|
|
64
|
+
readonly type: EdgeType;
|
|
65
|
+
readonly resolution: ResolutionLevel;
|
|
66
|
+
/** 0–1. Feeds the impact score. Clamped down by resolution, never up. */
|
|
67
|
+
readonly confidence: number;
|
|
68
|
+
readonly producedBy: string;
|
|
69
|
+
/**
|
|
70
|
+
* The run that witnessed this edge actually firing. Required when
|
|
71
|
+
* `resolution === 4`; meaningless otherwise. Drives R4 expiry.
|
|
72
|
+
*/
|
|
73
|
+
readonly observedByRun?: string;
|
|
74
|
+
readonly attrs?: Readonly<Record<string, unknown>>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A reference an adapter saw but could not resolve to a real node.
|
|
78
|
+
*
|
|
79
|
+
* These are NOT written as edges. A name-matched guess is a false claim, and one
|
|
80
|
+
* wrong edge corrupts every layer above the graph — so it is dropped. But dropped
|
|
81
|
+
* silently there is no denominator for recall and nothing to report under "not
|
|
82
|
+
* analysable", so it is recorded here instead.
|
|
83
|
+
*
|
|
84
|
+
* Measured on real prior-art graphs, this is 52–60% of everything an adapter
|
|
85
|
+
* emits. See DEC-016.
|
|
86
|
+
*/
|
|
87
|
+
export interface UnresolvedRef {
|
|
88
|
+
readonly fromNodeId: string;
|
|
89
|
+
readonly edgeType: EdgeType;
|
|
90
|
+
/** The raw text the adapter could not resolve, e.g. `append`. */
|
|
91
|
+
readonly rawTarget: string;
|
|
92
|
+
readonly file: string | null;
|
|
93
|
+
readonly line: number | null;
|
|
94
|
+
readonly producedBy: string;
|
|
95
|
+
readonly reason: string;
|
|
96
|
+
/**
|
|
97
|
+
* Producer-supplied detail, opaque above this boundary — the same contract
|
|
98
|
+
* as `IRNode.attrs`/`IREdge.attrs`. Two keys are named here:
|
|
99
|
+
*
|
|
100
|
+
* `blockedBy` — the literal source text of the specific expression that
|
|
101
|
+
* stopped resolution, e.g. `env.BACKEND_API_BASE_URL`,
|
|
102
|
+
* `import.meta.env.VITE_BACKEND_API_URL`. NOT the callee (`rawTarget`
|
|
103
|
+
* already carries that — `fetch`, `api.get`) and NOT a restatement of
|
|
104
|
+
* `reason` (prose for a person; `blockedBy` is the exact string a later
|
|
105
|
+
* human-confirmed answer is matched against, byte for byte, scoped to one
|
|
106
|
+
* repo — DEC-223 §3). `null` or absent means the row's cause is not "one
|
|
107
|
+
* unresolved expression" — a genuinely dynamic call has nothing singular
|
|
108
|
+
* to name.
|
|
109
|
+
*
|
|
110
|
+
* `refusalClass` — one of `UNRESOLVED_REF_CLASSES`, the producer's own
|
|
111
|
+
* answer to "can a human sentence ever resolve this row?" A `blockedBy`
|
|
112
|
+
* string alone cannot say that: naming the blocking expression does not
|
|
113
|
+
* mean a person can supply its value — see `UnresolvedRefClass`'s own doc
|
|
114
|
+
* for why this is a second, independent field rather than folded into the
|
|
115
|
+
* first. Never inferred from `reason`'s prose by a consumer (rule 3 — a
|
|
116
|
+
* text/name heuristic is not evidence); a producer sets it only when it
|
|
117
|
+
* knows structurally which bucket a row is in.
|
|
118
|
+
*
|
|
119
|
+
* **Assigned after config resolution, not before.** A producer must first
|
|
120
|
+
* check whatever local config sources it already reads (`.env` files,
|
|
121
|
+
* `wrangler.toml`'s `[vars]`, framework config) for the blocked
|
|
122
|
+
* expression's value — CLAUDE.md's own rule, "if the framework will tell
|
|
123
|
+
* you, never infer it." Only a value genuinely absent from every config
|
|
124
|
+
* source this reader can see is `"value-unknown"`; a value already sitting
|
|
125
|
+
* in a config file the repo contains must never reach this field as
|
|
126
|
+
* unresolved, and must never be classified in a way that could route it to
|
|
127
|
+
* a human. This ordering is a producer-side contract this field cannot
|
|
128
|
+
* enforce structurally — stated here because a shape that assumed
|
|
129
|
+
* classification runs first would license exactly that mistake.
|
|
130
|
+
*
|
|
131
|
+
* Both keys are optional and unenforced: most producers do not set them
|
|
132
|
+
* yet, and absence is a disclosed gap, never a rejection — see the
|
|
133
|
+
* reconciliation test in `normalise.test.ts` and DEC-223. Absent
|
|
134
|
+
* `refusalClass` means **unclassified**, and an unclassified row must never
|
|
135
|
+
* be defaulted to askable by a consumer — see the type's own doc.
|
|
136
|
+
*/
|
|
137
|
+
readonly attrs?: Readonly<Record<string, unknown>>;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The closed set `attrs.refusalClass` may hold on an `UnresolvedRef`.
|
|
141
|
+
*
|
|
142
|
+
* Producer-declared, never inferred from `reason`'s prose — a text/name
|
|
143
|
+
* heuristic over a free-text field is exactly the guess rule 3 bans, and
|
|
144
|
+
* `reason` is reworded by producers without the underlying question changing
|
|
145
|
+
* (`packages/core/src/query/unresolved.ts`'s own header is the measured
|
|
146
|
+
* account of that failure). Assigned only after the producer's own
|
|
147
|
+
* config-resolution pass has had a chance to answer the row from a source
|
|
148
|
+
* the repo already contains — see `UnresolvedRef.attrs`'s doc.
|
|
149
|
+
*
|
|
150
|
+
* - `"value-unknown"` — the row names something whose *value* the reader does
|
|
151
|
+
* not statically know AND does not find in any config source it reads (an
|
|
152
|
+
* env var with no matching `.env`/deploy-config entry). One human sentence
|
|
153
|
+
* can resolve it, and — because matching is exact-string on
|
|
154
|
+
* `(repo, blockedBy)` — the same sentence resolves every row in that repo
|
|
155
|
+
* sharing the identical `attrs.blockedBy` (DEC-223 §3). This is the class
|
|
156
|
+
* `blockedBy` was built for, and the only one a question queue may surface.
|
|
157
|
+
* - `"capability-gap"` — the reader cannot parse or resolve this shape at
|
|
158
|
+
* all: an enum-dispatched verb, a path pattern it does not trace, a
|
|
159
|
+
* language construct with no extractor yet. No sentence answers this —
|
|
160
|
+
* only code does — and it must never reach a question queue. Measured: 92
|
|
161
|
+
* of 95 censused C#/Java refusal rows are this class, not `value-unknown`.
|
|
162
|
+
* - `"out-of-scope"` — the reference resolved correctly to something outside
|
|
163
|
+
* this workspace (a third-party host, another team's service) and was
|
|
164
|
+
* filed as a refusal anyway. Correct information sitting in the wrong
|
|
165
|
+
* ledger, not a gap and not askable either.
|
|
166
|
+
* - `"varies-per-call"` — the blocked value is not fixed anywhere to ask
|
|
167
|
+
* about: a caller-supplied prop, a function parameter, a request-scoped
|
|
168
|
+
* value that is, by design, different on every call (`FileViewerModal`'s
|
|
169
|
+
* `url` prop; an upload helper's destination argument). Distinct from
|
|
170
|
+
* `"value-unknown"` on purpose — that class means *a* fixed value exists
|
|
171
|
+
* and nobody has stated it yet; this class means no single value exists to
|
|
172
|
+
* state. Asking a human "what is `url`?" here is a category error, not an
|
|
173
|
+
* unanswered question, and folding this into `"value-unknown"` behind a
|
|
174
|
+
* flag would let a consumer that forgets to check the flag put an
|
|
175
|
+
* unanswerable row in front of someone anyway — the same failure a missing
|
|
176
|
+
* class was already found to cause once (see the measured C#/Java case
|
|
177
|
+
* below). A dedicated class makes the omission a type error instead.
|
|
178
|
+
*
|
|
179
|
+
* **Absent means unclassified, not `"value-unknown"`.** A consumer building a
|
|
180
|
+
* question queue from this ledger must treat an unset `refusalClass` as
|
|
181
|
+
* not-askable — defaulting unset to askable is exactly how an unaudited row
|
|
182
|
+
* would reach a user as a question nobody vetted.
|
|
183
|
+
*
|
|
184
|
+
* This split is proposed from measured censuses across two cycles, not
|
|
185
|
+
* settled — whether `"out-of-scope"` belongs in this ledger at all, rather
|
|
186
|
+
* than being a class within it, is an open question for whoever reviews this
|
|
187
|
+
* contract next, not decided here.
|
|
188
|
+
*/
|
|
189
|
+
export declare const UNRESOLVED_REF_CLASSES: readonly ["value-unknown", "capability-gap", "out-of-scope", "varies-per-call"];
|
|
190
|
+
export type UnresolvedRefClass = (typeof UNRESOLVED_REF_CLASSES)[number];
|
|
191
|
+
/**
|
|
192
|
+
* DEC-223's answer half — a person's confirmed value for a `"value-unknown"`
|
|
193
|
+
* refusal-ledger row.
|
|
194
|
+
*
|
|
195
|
+
* Keyed on **exact string equality on `(repo, blockedBy)`, never fuzzy and
|
|
196
|
+
* never inferred across repositories** (rule 3 — "an answer is a declaration
|
|
197
|
+
* about the case it answers, never an inference about a second one"). `env.
|
|
198
|
+
* BACKEND_URL` and `env.BACKEND_API_BASE_URL` are different questions even
|
|
199
|
+
* when they plausibly resolve the same way; the same repository's identically
|
|
200
|
+
* spelled variable in a second application is a different case entirely.
|
|
201
|
+
* `blockedBy` here matches `UnresolvedRef.attrs.blockedBy` byte for byte —
|
|
202
|
+
* the field is named identically on both sides deliberately, so a reader (and
|
|
203
|
+
* a linter) can see the two are the same value without tracing a rename. A
|
|
204
|
+
* row with no `blockedBy` has nothing to key an answer on and cannot be
|
|
205
|
+
* answered by this mechanism at all, only by a code change.
|
|
206
|
+
*
|
|
207
|
+
* One fact legitimately answers every ledger row in `repo` sharing the
|
|
208
|
+
* identical `blockedBy` value, because they are, by construction, blocked by
|
|
209
|
+
* the same runtime binding — DEC-223's own measured case is exactly this: one
|
|
210
|
+
* `BACKEND_API_BASE_URL` value would join 18 rows in `sherpa-cf-worker`, one
|
|
211
|
+
* `VITE_BACKEND_API_URL` value already joins 50 in `sherpa-frontend`.
|
|
212
|
+
*
|
|
213
|
+
* This type says nothing about what an edge built from it may be classified
|
|
214
|
+
* as — that is `reliabilityCap`'s `humanAsserted` parameter, a second and
|
|
215
|
+
* independent guard, deliberately not encoded here so that a consumer cannot
|
|
216
|
+
* satisfy the obligation by constructing a `ConfirmedFact` correctly and then
|
|
217
|
+
* forgetting to pass the flag three functions later.
|
|
218
|
+
*/
|
|
219
|
+
export interface ConfirmedFact {
|
|
220
|
+
/** Scope — matches `RepoRoot.repo`. Never inferred across repositories. */
|
|
221
|
+
readonly repo: string;
|
|
222
|
+
/** Must equal some row's `attrs.blockedBy`, exact string match. */
|
|
223
|
+
readonly blockedBy: string;
|
|
224
|
+
/** The human-supplied literal. */
|
|
225
|
+
readonly value: string;
|
|
226
|
+
/**
|
|
227
|
+
* Optional, and unscoped is a legal, common answer — not a placeholder for
|
|
228
|
+
* one not yet given. A real answer arrived for `VITE_BACKEND_API_URL` in
|
|
229
|
+
* `sherpa-frontend` naming no environment at all, and forcing one would
|
|
230
|
+
* have meant guessing rather than recording what was actually said.
|
|
231
|
+
*
|
|
232
|
+
* Two facts for the same `(repo, blockedBy)` are the same answer only when
|
|
233
|
+
* their `environment` also matches (`undefined` is its own value, not a
|
|
234
|
+
* wildcard) — recording `"staging"` after recording an unscoped answer adds
|
|
235
|
+
* a second fact rather than overwriting the first, because a repository can
|
|
236
|
+
* genuinely need three different values for one expression: one per
|
|
237
|
+
* environment, or none at all when the repository does not distinguish
|
|
238
|
+
* them. `applyConfirmedFacts` surfaces every matching fact rather than
|
|
239
|
+
* picking one, so a caller sees the split rather than an arbitrarily
|
|
240
|
+
* chosen value.
|
|
241
|
+
*
|
|
242
|
+
* **Human-supplied only, never inferred.** Nothing above this type may
|
|
243
|
+
* read `"staging"` out of a hostname or a file path and assign it here —
|
|
244
|
+
* the same discipline `blockedBy` matching already applies to `expression`
|
|
245
|
+
* text, extended to this field: a guess dressed as a declaration is worse
|
|
246
|
+
* than an honest `undefined`.
|
|
247
|
+
*/
|
|
248
|
+
readonly environment?: string;
|
|
249
|
+
/** Free text — who or what asserted this. Not validated; recorded as given. */
|
|
250
|
+
readonly confirmedBy: string;
|
|
251
|
+
/** ISO timestamp. */
|
|
252
|
+
readonly confirmedAt: string;
|
|
253
|
+
/**
|
|
254
|
+
* The repo's `commitSha` (see `IRBatch.commitSha`) at the moment this fact
|
|
255
|
+
* was confirmed — "against what", to `confirmedAt`'s "when". Optional: a
|
|
256
|
+
* fact confirmed before this field existed carries none, and that absence
|
|
257
|
+
* is itself meaningful (staleness cannot be checked, not "assumed fresh") —
|
|
258
|
+
* never backfilled with a guess.
|
|
259
|
+
*
|
|
260
|
+
* This is the disclosure floor, not a re-verification mechanism: nothing
|
|
261
|
+
* reads this field to re-check a fact against a live source (there is no
|
|
262
|
+
* live source yet — `descry-runtime` does not exist). It exists so a
|
|
263
|
+
* consumer minting an edge from this fact *today* can say whether today's
|
|
264
|
+
* commit matches the one the human answer was given against, and disclose
|
|
265
|
+
* the mismatch rather than presenting an old answer as current.
|
|
266
|
+
*/
|
|
267
|
+
readonly confirmedAtCommit?: string;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* A node this batch offers as a target for a **declared cross-language
|
|
271
|
+
* namespace peer** — see `CapabilityMatrix.crossLanguageNamespace`, DEC-161.
|
|
272
|
+
*
|
|
273
|
+
* `qualifiedName` is what the REFERENCING side's own source would spell to
|
|
274
|
+
* name this node — a Java `import`'s fully-qualified name, for a Kotlin
|
|
275
|
+
* declaration reached from Java. It is opaque above this point: the resolver
|
|
276
|
+
* that consumes it does string equality only, never parses it, and nothing
|
|
277
|
+
* above the IR may know what syntax produced it. This is the field
|
|
278
|
+
* `IRNode.id`'s hash cannot serve in its place — an id is stable and
|
|
279
|
+
* unreadable by design, and a cross-language match needs a string a *different
|
|
280
|
+
* adapter* could independently compute.
|
|
281
|
+
*
|
|
282
|
+
* Not identity. `nodeId` is the real, existing node id; this is an additional,
|
|
283
|
+
* adapter-declared fact about how to *reach* it from outside its own language.
|
|
284
|
+
*/
|
|
285
|
+
export interface CrossLanguageDeclaration {
|
|
286
|
+
readonly qualifiedName: string;
|
|
287
|
+
readonly nodeId: string;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Why a file this batch's adapter attempted contributed no nodes or edges.
|
|
291
|
+
*
|
|
292
|
+
* Distinct from `UnresolvedRef` — that ledger is a reference the adapter *saw*
|
|
293
|
+
* and could not resolve to a node; this is a file the adapter could not read
|
|
294
|
+
* or parse at all, so it never got the chance to see anything in it. Mirrors
|
|
295
|
+
* `ParseFailure` (`@descryhq-wq/adapter-treesitter`) rather than inventing new
|
|
296
|
+
* vocabulary, since that shape is already what most producers compute — this
|
|
297
|
+
* field just gives it somewhere to go instead of dead-ending on `session`.
|
|
298
|
+
*/
|
|
299
|
+
export declare const SKIP_REASONS: readonly ["too-large", "unreadable", "grammar-error", "other"];
|
|
300
|
+
export type SkipReason = (typeof SKIP_REASONS)[number];
|
|
301
|
+
export interface SkippedFile {
|
|
302
|
+
readonly file: string;
|
|
303
|
+
readonly reason: SkipReason;
|
|
304
|
+
/** Producer-supplied, human-readable — the underlying error message, not a restatement of `reason`. */
|
|
305
|
+
readonly detail: string;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* The unit of ingest, and the unit of invalidation.
|
|
309
|
+
*
|
|
310
|
+
* `IREdge` carries no file, so stale edges from a changed file cannot be deleted
|
|
311
|
+
* from the edge alone — and derived edges (`PROPAGATES_TO`, `CHANGES_WITH`) have
|
|
312
|
+
* no owning file at all. Rather than patch `IREdge`, which the architecture pins,
|
|
313
|
+
* invalidation lives here: the writer deletes everything previously written by
|
|
314
|
+
* `producedBy` for `sourceFiles`, then inserts, in one transaction.
|
|
315
|
+
*
|
|
316
|
+
* See DEC-015, amended by the `skippedFiles` decision below.
|
|
317
|
+
*/
|
|
318
|
+
export interface IRBatch {
|
|
319
|
+
readonly repo: string;
|
|
320
|
+
/**
|
|
321
|
+
* The identity scope for workspace-scoped node types (DEC-054). Absent means
|
|
322
|
+
* "this repository alone". Carried on the batch and not only on the context so
|
|
323
|
+
* that a stored batch records the scope its ids were computed under — an id
|
|
324
|
+
* cannot be re-derived from the node alone once the config has moved on.
|
|
325
|
+
*/
|
|
326
|
+
readonly workspace?: string | undefined;
|
|
327
|
+
readonly commitSha: string;
|
|
328
|
+
/** `adapterId@version` — must match every node and edge in the batch. */
|
|
329
|
+
readonly producedBy: string;
|
|
330
|
+
/**
|
|
331
|
+
* Repo-relative paths this batch's nodes and edges were actually derived
|
|
332
|
+
* from — files the adapter successfully analysed. **Not** every file it
|
|
333
|
+
* attempted; a file that failed belongs in `skippedFiles` instead, never
|
|
334
|
+
* here. This is the invalidation key: a file sitting in this list falsely
|
|
335
|
+
* (because it actually failed) makes the writer treat it as re-covered and
|
|
336
|
+
* silently evict its last-known-good rows instead of disclosing the
|
|
337
|
+
* regression via `evictedFiles` — see DEC-022.
|
|
338
|
+
*/
|
|
339
|
+
readonly sourceFiles: readonly string[];
|
|
340
|
+
/**
|
|
341
|
+
* Files this batch's adapter attempted but that contributed no nodes or
|
|
342
|
+
* edges, with why. Never overlaps `sourceFiles` — a file is either analysed
|
|
343
|
+
* (named there) or skipped (named here), never both. Not yet persisted
|
|
344
|
+
* durably by the writer; surfaced as an in-request disclosure only.
|
|
345
|
+
*/
|
|
346
|
+
readonly skippedFiles: readonly SkippedFile[];
|
|
347
|
+
/** The level `prepare()` actually reached, not the level hoped for. */
|
|
348
|
+
readonly reachedResolution: ResolutionLevel;
|
|
349
|
+
readonly nodes: readonly IRNode[];
|
|
350
|
+
readonly edges: readonly IREdge[];
|
|
351
|
+
readonly unresolved: readonly UnresolvedRef[];
|
|
352
|
+
/**
|
|
353
|
+
* Nodes in this batch reachable from a declared cross-language namespace
|
|
354
|
+
* peer, keyed by what that peer's own source would spell to name them.
|
|
355
|
+
* Empty or absent unless this batch's adapter declares
|
|
356
|
+
* `CapabilityMatrix.crossLanguageNamespace`. See DEC-161.
|
|
357
|
+
*/
|
|
358
|
+
readonly crossLanguageDeclarations?: readonly CrossLanguageDeclaration[];
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=ir.d.ts.map
|
package/dist/ir.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"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"}
|
package/dist/ir.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Canonical IR — the boundary every language reaches the graph through.
|
|
3
|
+
*
|
|
4
|
+
* Nothing above this boundary may name a language (architecture principle 7).
|
|
5
|
+
* `language` is carried as provenance so findings can be reported honestly; it is
|
|
6
|
+
* never branched on. The boundary lint enforces that mechanically.
|
|
7
|
+
*/
|
|
8
|
+
export const RESOLUTION_LEVELS = [0, 1, 2, 3, 4];
|
|
9
|
+
/**
|
|
10
|
+
* The closed set `attrs.refusalClass` may hold on an `UnresolvedRef`.
|
|
11
|
+
*
|
|
12
|
+
* Producer-declared, never inferred from `reason`'s prose — a text/name
|
|
13
|
+
* heuristic over a free-text field is exactly the guess rule 3 bans, and
|
|
14
|
+
* `reason` is reworded by producers without the underlying question changing
|
|
15
|
+
* (`packages/core/src/query/unresolved.ts`'s own header is the measured
|
|
16
|
+
* account of that failure). Assigned only after the producer's own
|
|
17
|
+
* config-resolution pass has had a chance to answer the row from a source
|
|
18
|
+
* the repo already contains — see `UnresolvedRef.attrs`'s doc.
|
|
19
|
+
*
|
|
20
|
+
* - `"value-unknown"` — the row names something whose *value* the reader does
|
|
21
|
+
* not statically know AND does not find in any config source it reads (an
|
|
22
|
+
* env var with no matching `.env`/deploy-config entry). One human sentence
|
|
23
|
+
* can resolve it, and — because matching is exact-string on
|
|
24
|
+
* `(repo, blockedBy)` — the same sentence resolves every row in that repo
|
|
25
|
+
* sharing the identical `attrs.blockedBy` (DEC-223 §3). This is the class
|
|
26
|
+
* `blockedBy` was built for, and the only one a question queue may surface.
|
|
27
|
+
* - `"capability-gap"` — the reader cannot parse or resolve this shape at
|
|
28
|
+
* all: an enum-dispatched verb, a path pattern it does not trace, a
|
|
29
|
+
* language construct with no extractor yet. No sentence answers this —
|
|
30
|
+
* only code does — and it must never reach a question queue. Measured: 92
|
|
31
|
+
* of 95 censused C#/Java refusal rows are this class, not `value-unknown`.
|
|
32
|
+
* - `"out-of-scope"` — the reference resolved correctly to something outside
|
|
33
|
+
* this workspace (a third-party host, another team's service) and was
|
|
34
|
+
* filed as a refusal anyway. Correct information sitting in the wrong
|
|
35
|
+
* ledger, not a gap and not askable either.
|
|
36
|
+
* - `"varies-per-call"` — the blocked value is not fixed anywhere to ask
|
|
37
|
+
* about: a caller-supplied prop, a function parameter, a request-scoped
|
|
38
|
+
* value that is, by design, different on every call (`FileViewerModal`'s
|
|
39
|
+
* `url` prop; an upload helper's destination argument). Distinct from
|
|
40
|
+
* `"value-unknown"` on purpose — that class means *a* fixed value exists
|
|
41
|
+
* and nobody has stated it yet; this class means no single value exists to
|
|
42
|
+
* state. Asking a human "what is `url`?" here is a category error, not an
|
|
43
|
+
* unanswered question, and folding this into `"value-unknown"` behind a
|
|
44
|
+
* flag would let a consumer that forgets to check the flag put an
|
|
45
|
+
* unanswerable row in front of someone anyway — the same failure a missing
|
|
46
|
+
* class was already found to cause once (see the measured C#/Java case
|
|
47
|
+
* below). A dedicated class makes the omission a type error instead.
|
|
48
|
+
*
|
|
49
|
+
* **Absent means unclassified, not `"value-unknown"`.** A consumer building a
|
|
50
|
+
* question queue from this ledger must treat an unset `refusalClass` as
|
|
51
|
+
* not-askable — defaulting unset to askable is exactly how an unaudited row
|
|
52
|
+
* would reach a user as a question nobody vetted.
|
|
53
|
+
*
|
|
54
|
+
* This split is proposed from measured censuses across two cycles, not
|
|
55
|
+
* settled — whether `"out-of-scope"` belongs in this ledger at all, rather
|
|
56
|
+
* than being a class within it, is an open question for whoever reviews this
|
|
57
|
+
* contract next, not decided here.
|
|
58
|
+
*/
|
|
59
|
+
export const UNRESOLVED_REF_CLASSES = [
|
|
60
|
+
"value-unknown",
|
|
61
|
+
"capability-gap",
|
|
62
|
+
"out-of-scope",
|
|
63
|
+
"varies-per-call",
|
|
64
|
+
];
|
|
65
|
+
/**
|
|
66
|
+
* Why a file this batch's adapter attempted contributed no nodes or edges.
|
|
67
|
+
*
|
|
68
|
+
* Distinct from `UnresolvedRef` — that ledger is a reference the adapter *saw*
|
|
69
|
+
* and could not resolve to a node; this is a file the adapter could not read
|
|
70
|
+
* or parse at all, so it never got the chance to see anything in it. Mirrors
|
|
71
|
+
* `ParseFailure` (`@descryhq-wq/adapter-treesitter`) rather than inventing new
|
|
72
|
+
* vocabulary, since that shape is already what most producers compute — this
|
|
73
|
+
* field just gives it somewhere to go instead of dead-ending on `session`.
|
|
74
|
+
*/
|
|
75
|
+
export const SKIP_REASONS = ["too-large", "unreadable", "grammar-error", "other"];
|
|
76
|
+
//# sourceMappingURL=ir.js.map
|
package/dist/ir.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.js","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU,CAAC;AA2H1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,iBAAiB;CACT,CAAC;AAuGX;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,OAAO,CAAU,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DATABASE_TABLE`/`DATABASE_COLUMN` from a `MODEL`'s own mapped shape —
|
|
3
|
+
* DEC-240's Option 2.
|
|
4
|
+
*
|
|
5
|
+
* `adapter-sql` is the only producer of these two types until now, reading
|
|
6
|
+
* `*.sql` DDL. A Python (or, later, Java/C#) stack that maps its tables
|
|
7
|
+
* through an ORM and never checks in a migration file has no producer at
|
|
8
|
+
* all — 17 real tables on the stack this was measured against, zero
|
|
9
|
+
* `DATABASE_TABLE` nodes. DEC-240 ruled that the fix is not "teach
|
|
10
|
+
* `adapter-python`'s `orm.ts` to mint these too": a language adapter that did
|
|
11
|
+
* would also have to decide Django's/JPA's/EF Core's own implicit
|
|
12
|
+
* table-naming convention (app label + lowercased model name, a class name,
|
|
13
|
+
* a pluralisation rule) to cover the common case where no explicit table
|
|
14
|
+
* name is written — three adapters each independently inventing, or
|
|
15
|
+
* independently refusing, the same class of naming inference is three
|
|
16
|
+
* chances to disagree on the one byte that has to be identical for a join to
|
|
17
|
+
* happen at all. So the naming judgement — explicit name or refuse, never
|
|
18
|
+
* infer — lives here instead, once, and every adapter calls this function
|
|
19
|
+
* at its own emit time rather than re-deriving the rule.
|
|
20
|
+
*
|
|
21
|
+
* ## The part DEC-240's own ruling did not check, and the fix could not
|
|
22
|
+
* ship correctly without
|
|
23
|
+
*
|
|
24
|
+
* `nodeId` hashes `[scope, language, kind, qualifiedSymbolPath]` for every
|
|
25
|
+
* node type **except** the three in `FILELESS_NODE_TYPES` — and
|
|
26
|
+
* `DATABASE_TABLE`/`DATABASE_COLUMN` are not in that list. `adapter-sql`
|
|
27
|
+
* already hashes its own nodes with `language: "sql"`. A second producer
|
|
28
|
+
* hashing with its own language — `"python"`, later `"java"`, `"csharp"` —
|
|
29
|
+
* would mint a *different* id for the same real table than every other
|
|
30
|
+
* producer, and DEC-054's whole point (a Python `DATABASE_COLUMN` and a
|
|
31
|
+
* TypeScript `COMPONENT` meeting through one `API_ENDPOINT`) fails silently
|
|
32
|
+
* the identical way DEC-055 already found once: everything resolves,
|
|
33
|
+
* nothing errors, and the join returns nothing. So this function — and, to
|
|
34
|
+
* match it, `adapter-sql`'s own two call sites — hash with `language: null`
|
|
35
|
+
* unconditionally.
|
|
36
|
+
*
|
|
37
|
+
* **The emitted node's own `language` field is `null` too, not the real
|
|
38
|
+
* per-producer language.** The first cut of this function kept the real
|
|
39
|
+
* language there ("only the identity hash has to be language-blind, not the
|
|
40
|
+
* metadata") and that was wrong: the graph builder's collision detector
|
|
41
|
+
* (`identityFingerprint`, `packages/core/src/graph/merge.ts`) compares
|
|
42
|
+
* `[type, language]` for any two nodes that land on one id, precisely to
|
|
43
|
+
* catch two *different* things sharing an id by accident (DEC-024). A real
|
|
44
|
+
* per-producer language on this field means two genuine producers of the
|
|
45
|
+
* *same* table — a Python ORM and the `*.sql` DDL for it, this function's own
|
|
46
|
+
* motivating case — always disagree on `language` and always trip that
|
|
47
|
+
* detector, discarding one side's `DATABASE_COLUMN`s outright. `origin.language`
|
|
48
|
+
* is kept on {@link ModelTableOrigin} only as caller-supplied provenance for
|
|
49
|
+
* future use (e.g. `attrs`); it is not echoed onto the node. Per-producer
|
|
50
|
+
* provenance is still recoverable after a real merge through the node's
|
|
51
|
+
* `attrs.corroboratedBy`, the same mechanism every other cross-producer merge
|
|
52
|
+
* in this project already uses instead of a scalar field.
|
|
53
|
+
*
|
|
54
|
+
* `schema` defaults to `"public"` when a shape names none, matching
|
|
55
|
+
* `adapter-sql`'s own `DEFAULT_SCHEMA` — duplicated as a literal because
|
|
56
|
+
* `@descry/ir` cannot depend on an adapter package to import the constant.
|
|
57
|
+
* A model that maps to a non-default schema and never says so joins nothing
|
|
58
|
+
* either, the same silent-refusal shape `tableOf()` already accepts for an
|
|
59
|
+
* implicit table name.
|
|
60
|
+
*/
|
|
61
|
+
import { type IdentityScope } from "./identity.ts";
|
|
62
|
+
import type { IRNode, ResolutionLevel } from "./ir.ts";
|
|
63
|
+
/** Matches `adapter-sql`'s own `DEFAULT_SCHEMA` (`packages/adapter-sql` in `descry-adapters`). */
|
|
64
|
+
export declare const DEFAULT_MODEL_SCHEMA = "public";
|
|
65
|
+
export interface ModelFieldShape {
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly nullable: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* The database column's own name, where the mapping states one explicitly
|
|
70
|
+
* and it differs from `name` — TypeORM's `@Column({ name: "..." })` is the
|
|
71
|
+
* first producer of this, mapping a camelCase property to a snake_case
|
|
72
|
+
* column the way real TypeScript ORM code commonly does. Defaults to
|
|
73
|
+
* `name` when absent, the same "explicit or refuse, never guess" rule
|
|
74
|
+
* this file's header already holds table names to: read, never derived by
|
|
75
|
+
* a naming-convention rule this function does not own.
|
|
76
|
+
*/
|
|
77
|
+
readonly columnName?: string | undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The mapped shape a `MODEL`'s own extractor already produced — `orm.ts`'s
|
|
81
|
+
* `OrmShape` and its future JPA/EF Core siblings all carry exactly this:
|
|
82
|
+
* a table name where the source wrote one explicitly, `null` where it did
|
|
83
|
+
* not, and the fields that shape maps.
|
|
84
|
+
*/
|
|
85
|
+
export interface ModelTableShape {
|
|
86
|
+
/** `null` when the source names no explicit table. Refused below, never guessed. */
|
|
87
|
+
readonly table: string | null;
|
|
88
|
+
readonly fields: readonly ModelFieldShape[];
|
|
89
|
+
/** Explicit schema, where the source states one. Defaults to `DEFAULT_MODEL_SCHEMA`. */
|
|
90
|
+
readonly schema?: string | undefined;
|
|
91
|
+
}
|
|
92
|
+
export interface ModelTableOrigin {
|
|
93
|
+
readonly file: string;
|
|
94
|
+
readonly line: number;
|
|
95
|
+
readonly producedBy: string;
|
|
96
|
+
readonly resolution: ResolutionLevel;
|
|
97
|
+
/**
|
|
98
|
+
* The emitting adapter's own language. Carried on neither the node nor the
|
|
99
|
+
* id — see this file's header for why the node's `language` field is `null`
|
|
100
|
+
* too, not just the hash. Kept on this type as caller-supplied provenance
|
|
101
|
+
* for possible future use.
|
|
102
|
+
*/
|
|
103
|
+
readonly language: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* `DATABASE_TABLE` plus one `DATABASE_COLUMN` per mapped field, or `[]` when
|
|
107
|
+
* `shape.table` is `null` — the disclosed refusal `tableOf()` already makes
|
|
108
|
+
* for an implicit table name, carried through rather than re-decided here.
|
|
109
|
+
*/
|
|
110
|
+
export declare function databaseTableNodesFromModel(scope: IdentityScope, shape: ModelTableShape, origin: ModelTableOrigin): readonly IRNode[];
|
|
111
|
+
//# sourceMappingURL=model-tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-tables.d.ts","sourceRoot":"","sources":["../src/model-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvD,kGAAkG;AAClG,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,wFAAwF;IACxF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,GACvB,SAAS,MAAM,EAAE,CAmCnB"}
|