@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
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The golden corpus, parsed and validated — `fixtures/golden/patterns.json`.
|
|
3
|
+
*
|
|
4
|
+
* The golden is hand-written JSON that outlives every adapter, so it is parsed
|
|
5
|
+
* **strictly**: an unknown key is an error, not something to ignore. A typo in
|
|
6
|
+
* `requiredAtResolution` that silently parsed as "no requirement" would turn a
|
|
7
|
+
* recall gate into a no-op, and nothing downstream would ever notice — the suite
|
|
8
|
+
* would go green and stay green.
|
|
9
|
+
*
|
|
10
|
+
* One golden, N language bindings (`fixtures/README.md`). Nothing here is
|
|
11
|
+
* per-language, and nothing here may become per-language: the moment a pattern
|
|
12
|
+
* needs a different expectation per adapter it has stopped being a conformance
|
|
13
|
+
* pattern and become a language quirk, which belongs in `attrs`.
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
|
+
import { capabilityList, isFrameworkCapability } from "../capabilities.js";
|
|
17
|
+
import { isEdgeType, isNodeType } from "../vocabulary.js";
|
|
18
|
+
/** The wildcard target in a `forbiddenEdges` entry. See `compare.ts` for why it matters. */
|
|
19
|
+
export const ANY_TARGET = "*";
|
|
20
|
+
export class GoldenError extends Error {
|
|
21
|
+
name = "GoldenError";
|
|
22
|
+
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Strict parsing
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
function fail(where, detail) {
|
|
27
|
+
throw new GoldenError(`${where}: ${detail}`);
|
|
28
|
+
}
|
|
29
|
+
function object(value, where) {
|
|
30
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
31
|
+
fail(where, `expected an object, got ${Array.isArray(value) ? "an array" : typeof value}`);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function onlyKeys(value, allowed, where) {
|
|
36
|
+
const unknown = Object.keys(value).filter((k) => !allowed.includes(k));
|
|
37
|
+
if (unknown.length > 0) {
|
|
38
|
+
fail(where, `unknown key(s) ${unknown.map((k) => `"${k}"`).join(", ")}. The golden is parsed strictly ` +
|
|
39
|
+
`so a typo cannot silently disable an assertion; add the key to the parser deliberately.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function requiredString(value, key, where) {
|
|
43
|
+
const raw = value[key];
|
|
44
|
+
if (typeof raw !== "string" || raw === "")
|
|
45
|
+
fail(where, `"${key}" must be a non-empty string`);
|
|
46
|
+
return raw;
|
|
47
|
+
}
|
|
48
|
+
function optionalString(value, key, where) {
|
|
49
|
+
if (value[key] === undefined)
|
|
50
|
+
return undefined;
|
|
51
|
+
return requiredString(value, key, where);
|
|
52
|
+
}
|
|
53
|
+
function optionalResolution(value, key, where) {
|
|
54
|
+
const raw = value[key];
|
|
55
|
+
if (raw === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
if (raw !== 0 && raw !== 1 && raw !== 2 && raw !== 3 && raw !== 4) {
|
|
58
|
+
fail(where, `"${key}" must be a resolution level 0-4, got ${JSON.stringify(raw)}`);
|
|
59
|
+
}
|
|
60
|
+
return raw;
|
|
61
|
+
}
|
|
62
|
+
function optionalAttrs(value, where) {
|
|
63
|
+
if (value["attrs"] === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
return object(value["attrs"], `${where}.attrs`);
|
|
66
|
+
}
|
|
67
|
+
function array(value, where) {
|
|
68
|
+
if (!Array.isArray(value))
|
|
69
|
+
fail(where, "expected an array");
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
function nodeType(raw, where) {
|
|
73
|
+
if (!isNodeType(raw))
|
|
74
|
+
fail(where, `"${raw}" is not one of the 15 node types`);
|
|
75
|
+
return raw;
|
|
76
|
+
}
|
|
77
|
+
function edgeType(raw, where) {
|
|
78
|
+
if (!isEdgeType(raw))
|
|
79
|
+
fail(where, `"${raw}" is not one of the 15 edge types`);
|
|
80
|
+
return raw;
|
|
81
|
+
}
|
|
82
|
+
function parseNode(raw, where) {
|
|
83
|
+
const value = object(raw, where);
|
|
84
|
+
onlyKeys(value, ["role", "type", "sameFileAs", "attrs"], where);
|
|
85
|
+
const sameFileAs = optionalString(value, "sameFileAs", where);
|
|
86
|
+
const attrs = optionalAttrs(value, where);
|
|
87
|
+
return {
|
|
88
|
+
role: requiredString(value, "role", where),
|
|
89
|
+
type: nodeType(requiredString(value, "type", where), `${where}.type`),
|
|
90
|
+
...(sameFileAs === undefined ? {} : { sameFileAs }),
|
|
91
|
+
...(attrs === undefined ? {} : { attrs }),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function parseEdge(raw, where) {
|
|
95
|
+
const value = object(raw, where);
|
|
96
|
+
onlyKeys(value, ["from", "to", "type", "requiredAtResolution", "attrs"], where);
|
|
97
|
+
const requiredAtResolution = optionalResolution(value, "requiredAtResolution", where);
|
|
98
|
+
const attrs = optionalAttrs(value, where);
|
|
99
|
+
return {
|
|
100
|
+
from: requiredString(value, "from", where),
|
|
101
|
+
to: requiredString(value, "to", where),
|
|
102
|
+
type: edgeType(requiredString(value, "type", where), `${where}.type`),
|
|
103
|
+
...(requiredAtResolution === undefined ? {} : { requiredAtResolution }),
|
|
104
|
+
...(attrs === undefined ? {} : { attrs }),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function parseForbiddenEdge(raw, where) {
|
|
108
|
+
const value = object(raw, where);
|
|
109
|
+
onlyKeys(value, ["from", "to", "type", "atAnyResolution"], where);
|
|
110
|
+
const atAnyResolution = value["atAnyResolution"];
|
|
111
|
+
if (atAnyResolution !== undefined && typeof atAnyResolution !== "boolean") {
|
|
112
|
+
fail(where, `"atAnyResolution" must be a boolean`);
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
from: requiredString(value, "from", where),
|
|
116
|
+
to: requiredString(value, "to", where),
|
|
117
|
+
type: edgeType(requiredString(value, "type", where), `${where}.type`),
|
|
118
|
+
...(atAnyResolution === undefined ? {} : { atAnyResolution }),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function parseMustNotResolveTo(raw, where) {
|
|
122
|
+
const value = object(raw, where);
|
|
123
|
+
onlyKeys(value, ["edge", "target", "why"], where);
|
|
124
|
+
const edge = requiredString(value, "edge", where);
|
|
125
|
+
if (!edge.includes("->")) {
|
|
126
|
+
fail(`${where}.edge`, `expected "fromRole->toRole", got "${edge}"`);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
edge,
|
|
130
|
+
target: requiredString(value, "target", where),
|
|
131
|
+
why: requiredString(value, "why", where),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function parsePattern(raw, where) {
|
|
135
|
+
const value = object(raw, where);
|
|
136
|
+
onlyKeys(value, [
|
|
137
|
+
"description",
|
|
138
|
+
"nodes",
|
|
139
|
+
"edges",
|
|
140
|
+
"requiredAtResolution",
|
|
141
|
+
"requires",
|
|
142
|
+
"forbiddenEdges",
|
|
143
|
+
"mustNotResolveTo",
|
|
144
|
+
"mustNotBind",
|
|
145
|
+
"note",
|
|
146
|
+
], where);
|
|
147
|
+
const requiredAtResolution = optionalResolution(value, "requiredAtResolution", where);
|
|
148
|
+
const requires = optionalString(value, "requires", where);
|
|
149
|
+
if (requires !== undefined && !isFrameworkCapability(requires)) {
|
|
150
|
+
fail(`${where}.requires`, `unrecognised capability "${requires}". The recognised set is ${capabilityList()}. A new one ` +
|
|
151
|
+
`changes what "skipped" means in every report, so it is added deliberately or not at all — ` +
|
|
152
|
+
`and an unrecognised value fails here rather than skipping the pattern, because a pattern ` +
|
|
153
|
+
`that skips for a typo is a gate that has silently stopped running.`);
|
|
154
|
+
}
|
|
155
|
+
const note = optionalString(value, "note", where);
|
|
156
|
+
const forbidden = value["forbiddenEdges"];
|
|
157
|
+
const mustNot = value["mustNotResolveTo"];
|
|
158
|
+
const mustNotBind = value["mustNotBind"];
|
|
159
|
+
const pattern = {
|
|
160
|
+
description: requiredString(value, "description", where),
|
|
161
|
+
nodes: array(value["nodes"], `${where}.nodes`).map((n, i) => parseNode(n, `${where}.nodes[${i}]`)),
|
|
162
|
+
edges: array(value["edges"] ?? [], `${where}.edges`).map((e, i) => parseEdge(e, `${where}.edges[${i}]`)),
|
|
163
|
+
...(requiredAtResolution === undefined ? {} : { requiredAtResolution }),
|
|
164
|
+
...(requires === undefined ? {} : { requires }),
|
|
165
|
+
...(forbidden === undefined
|
|
166
|
+
? {}
|
|
167
|
+
: {
|
|
168
|
+
forbiddenEdges: array(forbidden, `${where}.forbiddenEdges`).map((f, i) => parseForbiddenEdge(f, `${where}.forbiddenEdges[${i}]`)),
|
|
169
|
+
}),
|
|
170
|
+
...(mustNot === undefined
|
|
171
|
+
? {}
|
|
172
|
+
: { mustNotResolveTo: parseMustNotResolveTo(mustNot, `${where}.mustNotResolveTo`) }),
|
|
173
|
+
...(mustNotBind === undefined
|
|
174
|
+
? {}
|
|
175
|
+
: {
|
|
176
|
+
mustNotBind: array(mustNotBind, `${where}.mustNotBind`).map((entry, i) => {
|
|
177
|
+
const at = `${where}.mustNotBind[${i}]`;
|
|
178
|
+
const raw = object(entry, at);
|
|
179
|
+
onlyKeys(raw, ["role", "why"], at);
|
|
180
|
+
return {
|
|
181
|
+
role: requiredString(raw, "role", at),
|
|
182
|
+
// Mandatory: a negative with no stated reason is deleted by the
|
|
183
|
+
// next person who cannot see what it was for.
|
|
184
|
+
why: requiredString(raw, "why", at),
|
|
185
|
+
};
|
|
186
|
+
}),
|
|
187
|
+
}),
|
|
188
|
+
...(note === undefined ? {} : { note }),
|
|
189
|
+
};
|
|
190
|
+
// Every role named by an edge, a forbidden edge or a mustNotResolveTo must be
|
|
191
|
+
// declared as a node of the pattern. Otherwise a role could be asserted about
|
|
192
|
+
// without ever being bound, and the binder would have nothing to look for.
|
|
193
|
+
const declared = new Set(pattern.nodes.map((n) => n.role));
|
|
194
|
+
const referenced = [];
|
|
195
|
+
for (const edge of pattern.edges)
|
|
196
|
+
referenced.push([edge.from, "edges.from"], [edge.to, "edges.to"]);
|
|
197
|
+
for (const node of pattern.nodes) {
|
|
198
|
+
if (node.sameFileAs !== undefined)
|
|
199
|
+
referenced.push([node.sameFileAs, "nodes.sameFileAs"]);
|
|
200
|
+
}
|
|
201
|
+
for (const forbiddenEdge of pattern.forbiddenEdges ?? []) {
|
|
202
|
+
referenced.push([forbiddenEdge.from, "forbiddenEdges.from"]);
|
|
203
|
+
// `to` is deliberately exempt: ANY_TARGET is not a role.
|
|
204
|
+
if (forbiddenEdge.to !== ANY_TARGET)
|
|
205
|
+
referenced.push([forbiddenEdge.to, "forbiddenEdges.to"]);
|
|
206
|
+
}
|
|
207
|
+
if (pattern.mustNotResolveTo !== undefined) {
|
|
208
|
+
referenced.push([pattern.mustNotResolveTo.target, "mustNotResolveTo.target"]);
|
|
209
|
+
}
|
|
210
|
+
for (const [role, field] of referenced) {
|
|
211
|
+
if (!declared.has(role)) {
|
|
212
|
+
fail(where, `${field} names role "${role}", which the pattern does not declare as a node`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return pattern;
|
|
216
|
+
}
|
|
217
|
+
export function parseGolden(raw) {
|
|
218
|
+
const value = object(raw, "golden");
|
|
219
|
+
onlyKeys(value, ["version", "note", "conventions", "patterns"], "golden");
|
|
220
|
+
if (typeof value["version"] !== "number")
|
|
221
|
+
fail("golden", `"version" must be a number`);
|
|
222
|
+
const patterns = object(value["patterns"], "golden.patterns");
|
|
223
|
+
const parsed = {};
|
|
224
|
+
for (const [id, pattern] of Object.entries(patterns)) {
|
|
225
|
+
parsed[id] = parsePattern(pattern, `golden.patterns["${id}"]`);
|
|
226
|
+
}
|
|
227
|
+
if (Object.keys(parsed).length === 0)
|
|
228
|
+
fail("golden", "the corpus is empty");
|
|
229
|
+
return { version: value["version"], patterns: parsed };
|
|
230
|
+
}
|
|
231
|
+
export function loadGolden(path) {
|
|
232
|
+
return parseGolden(JSON.parse(readFileSync(path, "utf8")));
|
|
233
|
+
}
|
|
234
|
+
/** Every role any pattern names. Used to check a manifest binds the whole corpus. */
|
|
235
|
+
export function goldenRoles(golden) {
|
|
236
|
+
const roles = new Set();
|
|
237
|
+
for (const pattern of Object.values(golden.patterns)) {
|
|
238
|
+
for (const node of pattern.nodes)
|
|
239
|
+
roles.add(node.role);
|
|
240
|
+
}
|
|
241
|
+
return [...roles].sort();
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The roles a single pattern needs bound before it can be checked.
|
|
245
|
+
*
|
|
246
|
+
* `forbiddenEdges[].to === ANY_TARGET` contributes nothing here, which is the
|
|
247
|
+
* point of the wildcard: it names no role, so it needs none bound.
|
|
248
|
+
*/
|
|
249
|
+
export function patternRoles(pattern) {
|
|
250
|
+
return [...new Set(pattern.nodes.map((n) => n.role))];
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=golden.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"golden.js","sourceRoot":"","sources":["../../src/conformance/golden.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The conformance harness — `fixtures/` turned into a release gate.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@descryy/ir` rather than `@descryy/core` because an adapter repo
|
|
5
|
+
* depends on the IR package and nothing else (DEC-001), and the gate has to be
|
|
6
|
+
* runnable by the thing it gates.
|
|
7
|
+
*/
|
|
8
|
+
export { ANY_TARGET, GoldenError, goldenRoles, loadGolden, parseGolden, patternRoles, } from "./golden.ts";
|
|
9
|
+
export type { Golden, GoldenEdge, GoldenForbiddenEdge, GoldenMustNotResolveTo, GoldenNode, GoldenPattern, } from "./golden.ts";
|
|
10
|
+
export { ManifestError, loadManifest, parseManifest } from "./manifest.ts";
|
|
11
|
+
export type { CorpusManifest, RoleBinding } from "./manifest.ts";
|
|
12
|
+
export { bindRoles, samePath } from "./bind.ts";
|
|
13
|
+
export type { BindFailure, BindFailureReason, BindResult } from "./bind.ts";
|
|
14
|
+
export { EDGE_TYPE_ALTERNATIVES, UNMAPPED_ATTR_NODE_TYPES, acceptedEdgeTypes, attrsSubset, mapFieldNames, } from "./compare.ts";
|
|
15
|
+
export type { AttrMismatch } from "./compare.ts";
|
|
16
|
+
export { checkManifest } from "./manifest-check.ts";
|
|
17
|
+
export type { ManifestCheck, ManifestFinding } from "./manifest-check.ts";
|
|
18
|
+
export { composeSources } from "./compose.ts";
|
|
19
|
+
export type { ComposedSource, CompositionConflict } from "./compose.ts";
|
|
20
|
+
export { runConformance, runConformanceSweep } from "./run.ts";
|
|
21
|
+
export type { ConformanceFinding, ConformanceInput, ConformanceResult, FindingKind, PatternResult, PatternVerdict, SweepInput, SweepResult, } from "./run.ts";
|
|
22
|
+
export { formatReport, formatSweepReport } from "./report.ts";
|
|
23
|
+
export { main as conformanceCli, parseArgs } from "./cli.ts";
|
|
24
|
+
export { CLIENT_CALL_EXTRACTOR, FRAMEWORK_CAPABILITIES, ORM_EXTRACTOR, ROUTE_EXTRACTOR, capabilityList, isFrameworkCapability, } from "../capabilities.ts";
|
|
25
|
+
export type { FrameworkCapability } from "../capabilities.ts";
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conformance/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5E,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,GACZ,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,IAAI,IAAI,cAAc,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The conformance harness — `fixtures/` turned into a release gate.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@descryy/ir` rather than `@descryy/core` because an adapter repo
|
|
5
|
+
* depends on the IR package and nothing else (DEC-001), and the gate has to be
|
|
6
|
+
* runnable by the thing it gates.
|
|
7
|
+
*/
|
|
8
|
+
export { ANY_TARGET, GoldenError, goldenRoles, loadGolden, parseGolden, patternRoles, } from "./golden.js";
|
|
9
|
+
export { ManifestError, loadManifest, parseManifest } from "./manifest.js";
|
|
10
|
+
export { bindRoles, samePath } from "./bind.js";
|
|
11
|
+
export { EDGE_TYPE_ALTERNATIVES, UNMAPPED_ATTR_NODE_TYPES, acceptedEdgeTypes, attrsSubset, mapFieldNames, } from "./compare.js";
|
|
12
|
+
export { checkManifest } from "./manifest-check.js";
|
|
13
|
+
export { composeSources } from "./compose.js";
|
|
14
|
+
export { runConformance, runConformanceSweep } from "./run.js";
|
|
15
|
+
export { formatReport, formatSweepReport } from "./report.js";
|
|
16
|
+
export { main as conformanceCli, parseArgs } from "./cli.js";
|
|
17
|
+
export { CLIENT_CALL_EXTRACTOR, FRAMEWORK_CAPABILITIES, ORM_EXTRACTOR, ROUTE_EXTRACTOR, capabilityList, isFrameworkCapability, } from "../capabilities.js";
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/conformance/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AAUrB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG3E,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAY/D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,IAAI,IAAI,cAAc,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does an adapter do what it says it does? — DEC-070.
|
|
3
|
+
*
|
|
4
|
+
* ## The failure this closes, which has happened twice
|
|
5
|
+
*
|
|
6
|
+
* The conformance corpus checks an adapter's **output against goldens**. Its
|
|
7
|
+
* `capabilities()` manifest is checked against nothing at all, and the harness
|
|
8
|
+
* *reads* that manifest to decide whether a pattern applies. So an adapter that
|
|
9
|
+
* under-declares does not fail — it gets its gates **skipped**, which looks like
|
|
10
|
+
* a clean run.
|
|
11
|
+
*
|
|
12
|
+
* It has happened in both directions of the same idea:
|
|
13
|
+
*
|
|
14
|
+
* - The TypeScript adapter emitted **1,114 `USES_TYPE` edges** while omitting
|
|
15
|
+
* `USES_TYPE` from `capabilities().edgeTypes`. Golden pattern 13 reported
|
|
16
|
+
* `SKIP — declared incapacity` instead of running. The adapter had silently
|
|
17
|
+
* opted itself out of its own gate, and only adding a *new* pattern that
|
|
18
|
+
* happened to need that capability surfaced it.
|
|
19
|
+
* - The Python adapter computed a complete list of `unittest` test cases and
|
|
20
|
+
* threw it away unread, so one repository reported 0 tests out of 223.
|
|
21
|
+
*
|
|
22
|
+
* Both are one shape: **one side of a contract is right and nothing checks that
|
|
23
|
+
* the other side agrees.**
|
|
24
|
+
*
|
|
25
|
+
* ## The two directions are deliberately not symmetric
|
|
26
|
+
*
|
|
27
|
+
* **Emitted but not declared → a hard failure of the adapter.** Always a defect.
|
|
28
|
+
* Under-claiming is precisely what makes the harness skip a gate rather than run
|
|
29
|
+
* it, so it converts a real capability into an untested one.
|
|
30
|
+
*
|
|
31
|
+
* **Declared but not emitted → not an adapter failure.** Measured: the
|
|
32
|
+
* TypeScript adapter declares `INHERITS` and emits none over
|
|
33
|
+
* `fixtures/languages/typescript`, because that fixture contains no class
|
|
34
|
+
* `extends` while the Python one does. The adapter is correct and the corpus is
|
|
35
|
+
* thin. Failing the adapter there punishes it for a hole in someone else's file,
|
|
36
|
+
* and the predictable response is to delete the declaration — the exact
|
|
37
|
+
* behaviour this module exists to prevent.
|
|
38
|
+
*
|
|
39
|
+
* So that direction reports **`unexercised`**: it fails the *corpus* gate, and
|
|
40
|
+
* it blocks a capability-tier claim for that type (open item 20). An adapter may
|
|
41
|
+
* not be published as S/A/B/C for something the corpus never ran.
|
|
42
|
+
*
|
|
43
|
+
* ## Why here and not a lint
|
|
44
|
+
*
|
|
45
|
+
* The declaration is data returned at runtime and the emission depends on
|
|
46
|
+
* fixture content. Only executing both can compare them.
|
|
47
|
+
*/
|
|
48
|
+
import type { IRBatch } from "../ir.ts";
|
|
49
|
+
import type { CapabilityMatrix } from "../contracts.ts";
|
|
50
|
+
/** One disagreement between what an adapter declares and what it produced. */
|
|
51
|
+
export interface ManifestFinding {
|
|
52
|
+
/** `undeclared` fails the adapter; `unexercised` fails the corpus. */
|
|
53
|
+
readonly kind: "undeclared" | "unexercised";
|
|
54
|
+
readonly what: "edge" | "node" | "capability";
|
|
55
|
+
readonly type: string;
|
|
56
|
+
/** How many the adapter emitted. Zero for `unexercised`, by definition. */
|
|
57
|
+
readonly emitted: number;
|
|
58
|
+
readonly detail: string;
|
|
59
|
+
}
|
|
60
|
+
export interface ManifestCheck {
|
|
61
|
+
readonly findings: readonly ManifestFinding[];
|
|
62
|
+
/** Any `undeclared` finding. The adapter is at fault and must not pass. */
|
|
63
|
+
readonly adapterFailed: boolean;
|
|
64
|
+
/** Any `unexercised` finding. The corpus is thin; the adapter is not at fault. */
|
|
65
|
+
readonly corpusThin: boolean;
|
|
66
|
+
/** Types no pattern exercised — not publishable as a tier claim. */
|
|
67
|
+
readonly unpublishable: readonly string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Compare a declared capability matrix against a batch the adapter produced.
|
|
71
|
+
*
|
|
72
|
+
* `capabilities` absent means the source does not declare one — an `IRSource`
|
|
73
|
+
* such as the git reader, which is not an adapter and has nothing to check.
|
|
74
|
+
* Returning "no findings" there is correct rather than lenient: there is no
|
|
75
|
+
* claim to contradict.
|
|
76
|
+
*/
|
|
77
|
+
export declare function checkManifest(capabilities: CapabilityMatrix | undefined, batch: IRBatch): ManifestCheck;
|
|
78
|
+
//# sourceMappingURL=manifest-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-check.d.ts","sourceRoot":"","sources":["../../src/conformance/manifest-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,2EAA2E;IAC3E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AASD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,gBAAgB,GAAG,SAAS,EAC1C,KAAK,EAAE,OAAO,GACb,aAAa,CA0Ff"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does an adapter do what it says it does? — DEC-070.
|
|
3
|
+
*
|
|
4
|
+
* ## The failure this closes, which has happened twice
|
|
5
|
+
*
|
|
6
|
+
* The conformance corpus checks an adapter's **output against goldens**. Its
|
|
7
|
+
* `capabilities()` manifest is checked against nothing at all, and the harness
|
|
8
|
+
* *reads* that manifest to decide whether a pattern applies. So an adapter that
|
|
9
|
+
* under-declares does not fail — it gets its gates **skipped**, which looks like
|
|
10
|
+
* a clean run.
|
|
11
|
+
*
|
|
12
|
+
* It has happened in both directions of the same idea:
|
|
13
|
+
*
|
|
14
|
+
* - The TypeScript adapter emitted **1,114 `USES_TYPE` edges** while omitting
|
|
15
|
+
* `USES_TYPE` from `capabilities().edgeTypes`. Golden pattern 13 reported
|
|
16
|
+
* `SKIP — declared incapacity` instead of running. The adapter had silently
|
|
17
|
+
* opted itself out of its own gate, and only adding a *new* pattern that
|
|
18
|
+
* happened to need that capability surfaced it.
|
|
19
|
+
* - The Python adapter computed a complete list of `unittest` test cases and
|
|
20
|
+
* threw it away unread, so one repository reported 0 tests out of 223.
|
|
21
|
+
*
|
|
22
|
+
* Both are one shape: **one side of a contract is right and nothing checks that
|
|
23
|
+
* the other side agrees.**
|
|
24
|
+
*
|
|
25
|
+
* ## The two directions are deliberately not symmetric
|
|
26
|
+
*
|
|
27
|
+
* **Emitted but not declared → a hard failure of the adapter.** Always a defect.
|
|
28
|
+
* Under-claiming is precisely what makes the harness skip a gate rather than run
|
|
29
|
+
* it, so it converts a real capability into an untested one.
|
|
30
|
+
*
|
|
31
|
+
* **Declared but not emitted → not an adapter failure.** Measured: the
|
|
32
|
+
* TypeScript adapter declares `INHERITS` and emits none over
|
|
33
|
+
* `fixtures/languages/typescript`, because that fixture contains no class
|
|
34
|
+
* `extends` while the Python one does. The adapter is correct and the corpus is
|
|
35
|
+
* thin. Failing the adapter there punishes it for a hole in someone else's file,
|
|
36
|
+
* and the predictable response is to delete the declaration — the exact
|
|
37
|
+
* behaviour this module exists to prevent.
|
|
38
|
+
*
|
|
39
|
+
* So that direction reports **`unexercised`**: it fails the *corpus* gate, and
|
|
40
|
+
* it blocks a capability-tier claim for that type (open item 20). An adapter may
|
|
41
|
+
* not be published as S/A/B/C for something the corpus never ran.
|
|
42
|
+
*
|
|
43
|
+
* ## Why here and not a lint
|
|
44
|
+
*
|
|
45
|
+
* The declaration is data returned at runtime and the emission depends on
|
|
46
|
+
* fixture content. Only executing both can compare them.
|
|
47
|
+
*/
|
|
48
|
+
const EMPTY = {
|
|
49
|
+
findings: [],
|
|
50
|
+
adapterFailed: false,
|
|
51
|
+
corpusThin: false,
|
|
52
|
+
unpublishable: [],
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Compare a declared capability matrix against a batch the adapter produced.
|
|
56
|
+
*
|
|
57
|
+
* `capabilities` absent means the source does not declare one — an `IRSource`
|
|
58
|
+
* such as the git reader, which is not an adapter and has nothing to check.
|
|
59
|
+
* Returning "no findings" there is correct rather than lenient: there is no
|
|
60
|
+
* claim to contradict.
|
|
61
|
+
*/
|
|
62
|
+
export function checkManifest(capabilities, batch) {
|
|
63
|
+
if (capabilities === undefined)
|
|
64
|
+
return EMPTY;
|
|
65
|
+
const declaredEdges = new Set(capabilities.edgeTypes);
|
|
66
|
+
const declaredNodes = new Set(capabilities.nodeTypes);
|
|
67
|
+
const emittedEdges = new Map();
|
|
68
|
+
for (const edge of batch.edges)
|
|
69
|
+
emittedEdges.set(edge.type, (emittedEdges.get(edge.type) ?? 0) + 1);
|
|
70
|
+
const emittedNodes = new Map();
|
|
71
|
+
for (const node of batch.nodes)
|
|
72
|
+
emittedNodes.set(node.type, (emittedNodes.get(node.type) ?? 0) + 1);
|
|
73
|
+
const findings = [];
|
|
74
|
+
// An extractor bound with nothing said about what it supplies. This is an
|
|
75
|
+
// ADAPTER failure rather than a skip on purpose: the extractor names are the
|
|
76
|
+
// adapter's own vocabulary and the harness must never interpret them, so this
|
|
77
|
+
// adapter has told the harness nothing it can act on. Defaulting either way
|
|
78
|
+
// would be a gate quietly changing what it checks — treat it as supplying
|
|
79
|
+
// everything and a pattern passes unearned, treat it as supplying nothing and
|
|
80
|
+
// a pattern stops being graded. Both look green.
|
|
81
|
+
const bound = capabilities.frameworkExtractors ?? [];
|
|
82
|
+
if (bound.length > 0 && capabilities.frameworkCapabilities === undefined) {
|
|
83
|
+
findings.push({
|
|
84
|
+
kind: "undeclared",
|
|
85
|
+
what: "capability",
|
|
86
|
+
type: bound.join(", "),
|
|
87
|
+
emitted: 0,
|
|
88
|
+
detail: `binds ${bound.length} framework extractor(s) and declares no ` +
|
|
89
|
+
`frameworkCapabilities, so the harness cannot tell which patterns they unlock. Declare ` +
|
|
90
|
+
`what they supply from the closed set in capabilities.ts — what the extractor actually ` +
|
|
91
|
+
`produces, not what the framework could.`,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
for (const [type, count] of [...emittedEdges].sort()) {
|
|
95
|
+
if (declaredEdges.has(type))
|
|
96
|
+
continue;
|
|
97
|
+
findings.push({
|
|
98
|
+
kind: "undeclared",
|
|
99
|
+
what: "edge",
|
|
100
|
+
type,
|
|
101
|
+
emitted: count,
|
|
102
|
+
detail: `emitted ${String(count)} ${type} edge(s) but capabilities().edgeTypes omits it. ` +
|
|
103
|
+
`The harness reads that list to decide whether a pattern applies, so this adapter ` +
|
|
104
|
+
`is skipping gates it would pass — an untested capability, not a missing one.`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
for (const [type, count] of [...emittedNodes].sort()) {
|
|
108
|
+
if (declaredNodes.has(type))
|
|
109
|
+
continue;
|
|
110
|
+
findings.push({
|
|
111
|
+
kind: "undeclared",
|
|
112
|
+
what: "node",
|
|
113
|
+
type,
|
|
114
|
+
emitted: count,
|
|
115
|
+
detail: `emitted ${String(count)} ${type} node(s) but capabilities().nodeTypes omits it.`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
for (const type of [...declaredEdges].sort()) {
|
|
119
|
+
if (emittedEdges.has(type))
|
|
120
|
+
continue;
|
|
121
|
+
findings.push({
|
|
122
|
+
kind: "unexercised",
|
|
123
|
+
what: "edge",
|
|
124
|
+
type,
|
|
125
|
+
emitted: 0,
|
|
126
|
+
detail: `declares ${type} and the corpus never elicited one. This is a hole in the ` +
|
|
127
|
+
`fixtures, not a defect in the adapter — but the capability is unverified and ` +
|
|
128
|
+
`must not be published as a tier claim until a pattern exercises it.`,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
for (const type of [...declaredNodes].sort()) {
|
|
132
|
+
if (emittedNodes.has(type))
|
|
133
|
+
continue;
|
|
134
|
+
findings.push({
|
|
135
|
+
kind: "unexercised",
|
|
136
|
+
what: "node",
|
|
137
|
+
type,
|
|
138
|
+
emitted: 0,
|
|
139
|
+
detail: `declares ${type} and the corpus never elicited one.`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
findings,
|
|
144
|
+
adapterFailed: findings.some((finding) => finding.kind === "undeclared"),
|
|
145
|
+
corpusThin: findings.some((finding) => finding.kind === "unexercised"),
|
|
146
|
+
unpublishable: findings.filter((f) => f.kind === "unexercised").map((f) => f.type).sort(),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=manifest-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-check.js","sourceRoot":"","sources":["../../src/conformance/manifest-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A corpus binding manifest — `fixtures/languages/<name>/manifest.json`.
|
|
3
|
+
*
|
|
4
|
+
* The golden says *what shape* a pattern has; a manifest says *which symbols in
|
|
5
|
+
* this corpus play those parts*. That split is what lets one golden gate many
|
|
6
|
+
* adapters, and it is why the manifest is data a human wrote rather than
|
|
7
|
+
* something an adapter supplies: an adapter that told the harness which of its
|
|
8
|
+
* own nodes to compare would be grading its own paper.
|
|
9
|
+
*
|
|
10
|
+
* Parsed as strictly as the golden, with one deliberate exception — any key
|
|
11
|
+
* ending in `Note` is documentation and is ignored. The corpus uses those to
|
|
12
|
+
* record *why* an override exists, which `fixtures/README.md` step 4 requires,
|
|
13
|
+
* and losing them to a strict parser would push the reasoning out of the file
|
|
14
|
+
* that needs it.
|
|
15
|
+
*/
|
|
16
|
+
import { type FrameworkCapability } from "../capabilities.ts";
|
|
17
|
+
import type { ResolutionLevel } from "../ir.ts";
|
|
18
|
+
import { type NodeType } from "../vocabulary.ts";
|
|
19
|
+
export interface RoleBinding {
|
|
20
|
+
/** The symbol a human would point at. Matched against `IRNode.name` — see `bind.ts`. */
|
|
21
|
+
readonly symbol: string;
|
|
22
|
+
/** Repo-relative, or null for a fileless node type (DEC-014). */
|
|
23
|
+
readonly file: string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Other places this role may legitimately be declared.
|
|
26
|
+
*
|
|
27
|
+
* **More than one producer can declare the same thing, and neither is wrong.**
|
|
28
|
+
* A route exists in the published contract as `GET /orders/{id}` and in the
|
|
29
|
+
* service source as `GET /orders/:id`; a DTO is a schema in the contract and
|
|
30
|
+
* a request type in the code. `adapter-openapi` produces the first, a
|
|
31
|
+
* framework extractor will produce the second, and the corpus must be able to
|
|
32
|
+
* accept whichever producer is running without pretending the other does not
|
|
33
|
+
* exist.
|
|
34
|
+
*
|
|
35
|
+
* Tried in order after the primary binding, and a failure lists every place
|
|
36
|
+
* that was looked. This is not a loosening: each alternate is still an exact
|
|
37
|
+
* `(file, symbol)` pair that a human can point at, and a role matching in two
|
|
38
|
+
* places at once is still ambiguous and still fails.
|
|
39
|
+
*/
|
|
40
|
+
readonly alternates?: readonly {
|
|
41
|
+
readonly symbol: string;
|
|
42
|
+
readonly file: string | null;
|
|
43
|
+
}[];
|
|
44
|
+
}
|
|
45
|
+
export interface CorpusManifest {
|
|
46
|
+
readonly adapter: string;
|
|
47
|
+
readonly language: string;
|
|
48
|
+
readonly root: string;
|
|
49
|
+
readonly parseGlobs: readonly string[];
|
|
50
|
+
readonly sqlGlobs: readonly string[];
|
|
51
|
+
/**
|
|
52
|
+
* Where a published contract lives, for the format adapters that read one.
|
|
53
|
+
*
|
|
54
|
+
* Documentation in the same sense `sqlGlobs` is: the adapter carries its own
|
|
55
|
+
* defaults, and this states where the corpus put the file so a reader does not
|
|
56
|
+
* have to infer it from a glob buried in a package.
|
|
57
|
+
*/
|
|
58
|
+
readonly contractGlobs: readonly string[];
|
|
59
|
+
/**
|
|
60
|
+
* The best this corpus can honestly ask of this adapter. Patterns requiring
|
|
61
|
+
* more are `not-required` rather than failures — `fixtures/README.md` step 3.
|
|
62
|
+
*/
|
|
63
|
+
readonly expectedMaxResolution: ResolutionLevel;
|
|
64
|
+
readonly frameworkExtractors: readonly string[];
|
|
65
|
+
/**
|
|
66
|
+
* What those extractors supply, when the corpus rather than the adapter is the
|
|
67
|
+
* one saying. Absent means the adapter's own `capabilities()` is the only
|
|
68
|
+
* source, which is the normal case — the adapter is the authority on what it
|
|
69
|
+
* can do, and this exists for sources that have no capability matrix at all.
|
|
70
|
+
*/
|
|
71
|
+
readonly frameworkCapabilities?: readonly FrameworkCapability[];
|
|
72
|
+
readonly roles: Readonly<Record<string, RoleBinding>>;
|
|
73
|
+
/** A role whose node type genuinely differs here. Every entry needs a written reason. */
|
|
74
|
+
readonly roleTypeOverrides: Readonly<Record<string, NodeType>>;
|
|
75
|
+
/** Golden field name -> this corpus's idiomatic spelling. Compares meaning, not spelling. */
|
|
76
|
+
readonly fieldNameMap: Readonly<Record<string, string>>;
|
|
77
|
+
}
|
|
78
|
+
export declare class ManifestError extends Error {
|
|
79
|
+
readonly name = "ManifestError";
|
|
80
|
+
}
|
|
81
|
+
export declare function parseManifest(raw: unknown): CorpusManifest;
|
|
82
|
+
export declare function loadManifest(path: string): CorpusManifest;
|
|
83
|
+
//# sourceMappingURL=manifest.d.ts.map
|