@sdd-method/sdd-cli 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/catalogue/aggregate.d.ts.map +1 -1
- package/dist/lib/catalogue/aggregate.js +5 -4
- package/dist/lib/catalogue/aggregate.js.map +1 -1
- package/dist/lib/catalogue/build.d.ts.map +1 -1
- package/dist/lib/catalogue/build.js +16 -7
- package/dist/lib/catalogue/build.js.map +1 -1
- package/dist/lib/catalogue/builders/capability-edges.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/capability-edges.js +10 -1
- package/dist/lib/catalogue/builders/capability-edges.js.map +1 -1
- package/dist/lib/catalogue/builders/capability-spec.d.ts +9 -3
- package/dist/lib/catalogue/builders/capability-spec.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/capability-spec.js +9 -3
- package/dist/lib/catalogue/builders/capability-spec.js.map +1 -1
- package/dist/lib/catalogue/builders/index.d.ts +2 -0
- package/dist/lib/catalogue/builders/index.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/index.js +1 -0
- package/dist/lib/catalogue/builders/index.js.map +1 -1
- package/dist/lib/catalogue/builders/quality-scores.d.ts +14 -0
- package/dist/lib/catalogue/builders/quality-scores.d.ts.map +1 -0
- package/dist/lib/catalogue/builders/quality-scores.js +321 -0
- package/dist/lib/catalogue/builders/quality-scores.js.map +1 -0
- package/dist/lib/catalogue/builders/services.d.ts.map +1 -1
- package/dist/lib/catalogue/builders/services.js +5 -1
- package/dist/lib/catalogue/builders/services.js.map +1 -1
- package/dist/lib/catalogue/canonical-schema.yaml +255 -6
- package/dist/lib/catalogue/coverage-predicates.d.ts +176 -0
- package/dist/lib/catalogue/coverage-predicates.d.ts.map +1 -0
- package/dist/lib/catalogue/coverage-predicates.js +603 -0
- package/dist/lib/catalogue/coverage-predicates.js.map +1 -0
- package/dist/lib/catalogue/coverage-render.d.ts +54 -0
- package/dist/lib/catalogue/coverage-render.d.ts.map +1 -0
- package/dist/lib/catalogue/coverage-render.js +432 -0
- package/dist/lib/catalogue/coverage-render.js.map +1 -0
- package/dist/lib/catalogue/coverage-run.d.ts +33 -0
- package/dist/lib/catalogue/coverage-run.d.ts.map +1 -0
- package/dist/lib/catalogue/coverage-run.js +97 -0
- package/dist/lib/catalogue/coverage-run.js.map +1 -0
- package/dist/lib/catalogue/ddl-generator.d.ts +80 -0
- package/dist/lib/catalogue/ddl-generator.d.ts.map +1 -0
- package/dist/lib/catalogue/ddl-generator.js +215 -0
- package/dist/lib/catalogue/ddl-generator.js.map +1 -0
- package/dist/lib/catalogue/engine-validator.d.ts +103 -0
- package/dist/lib/catalogue/engine-validator.d.ts.map +1 -0
- package/dist/lib/catalogue/engine-validator.js +221 -0
- package/dist/lib/catalogue/engine-validator.js.map +1 -0
- package/dist/lib/catalogue/enum-validator.d.ts.map +1 -1
- package/dist/lib/catalogue/enum-validator.js +15 -0
- package/dist/lib/catalogue/enum-validator.js.map +1 -1
- package/dist/lib/catalogue/fk-validator.d.ts +6 -0
- package/dist/lib/catalogue/fk-validator.d.ts.map +1 -1
- package/dist/lib/catalogue/fk-validator.js +6 -0
- package/dist/lib/catalogue/fk-validator.js.map +1 -1
- package/dist/lib/catalogue/gate-checks.d.ts +117 -0
- package/dist/lib/catalogue/gate-checks.d.ts.map +1 -0
- package/dist/lib/catalogue/gate-checks.js +261 -0
- package/dist/lib/catalogue/gate-checks.js.map +1 -0
- package/dist/lib/catalogue/parity-harness.d.ts +48 -0
- package/dist/lib/catalogue/parity-harness.d.ts.map +1 -0
- package/dist/lib/catalogue/parity-harness.js +76 -0
- package/dist/lib/catalogue/parity-harness.js.map +1 -0
- package/dist/lib/catalogue/schema-compat.d.ts +3 -3
- package/dist/lib/catalogue/schema-compat.js +3 -3
- package/dist/lib/catalogue/scores-coverage.d.ts +138 -0
- package/dist/lib/catalogue/scores-coverage.d.ts.map +1 -0
- package/dist/lib/catalogue/scores-coverage.js +346 -0
- package/dist/lib/catalogue/scores-coverage.js.map +1 -0
- package/dist/lib/catalogue/validate.d.ts.map +1 -1
- package/dist/lib/catalogue/validate.js +6 -11
- package/dist/lib/catalogue/validate.js.map +1 -1
- package/dist/lib/mcp/parse/gate-registry.d.ts +63 -4
- package/dist/lib/mcp/parse/gate-registry.d.ts.map +1 -1
- package/dist/lib/mcp/parse/gate-registry.js +127 -31
- package/dist/lib/mcp/parse/gate-registry.js.map +1 -1
- package/dist/lib/mcp/resources/gates.d.ts.map +1 -1
- package/dist/lib/mcp/resources/gates.js +13 -27
- package/dist/lib/mcp/resources/gates.js.map +1 -1
- package/dist/lib/mcp/tools/query-gate-status.d.ts.map +1 -1
- package/dist/lib/mcp/tools/query-gate-status.js +13 -27
- package/dist/lib/mcp/tools/query-gate-status.js.map +1 -1
- package/dist/verbs/catalogue.d.ts.map +1 -1
- package/dist/verbs/catalogue.js +24 -0
- package/dist/verbs/catalogue.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase-0 gate checks as SQL — M-ADR 0205 §4.4 (engine-evolution Phase A3,
|
|
3
|
+
* final tranche). The nine small catalogue-integrity-gate steps
|
|
4
|
+
* re-expressed on the engine: emptiness-vs-populated-inputs signals
|
|
5
|
+
* (repo-edges 0157, data-model-entities 0159, capability-event 0160,
|
|
6
|
+
* feature-event 0161, platform-dependencies 0162, glossary-xref 0158),
|
|
7
|
+
* the per-domain event-catalogue count compare (0156), and the two
|
|
8
|
+
* features.csv Phase-0 checks (0177 F1 promotion, F2 near-duplicate
|
|
9
|
+
* surfaces — the classified borderline: engine for access, the token
|
|
10
|
+
* Jaccard stays host-language).
|
|
11
|
+
*
|
|
12
|
+
* The shell scripts remain the REFERENCE implementations until A4. Known,
|
|
13
|
+
* deliberate divergence class: several references read CSV columns
|
|
14
|
+
* POSITIONALLY with a naive comma split (`awk -F, $5`) and count PHYSICAL
|
|
15
|
+
* lines rather than CSV records — this port reads by column name over
|
|
16
|
+
* parsed records. Where real data makes those disagree, the dual-run
|
|
17
|
+
* driver surfaces it and the adjudication is a defect in the shell side
|
|
18
|
+
* (the exact matcher-error class M-ADR 0205 §1 exists to kill), never a
|
|
19
|
+
* smoothing of this side.
|
|
20
|
+
*
|
|
21
|
+
* File and YAML ingestion stay host-side, mirroring each reference's
|
|
22
|
+
* refusal semantics (a missing key, an unparseable document, an absent
|
|
23
|
+
* tool each behave exactly as the reference behaves).
|
|
24
|
+
*/
|
|
25
|
+
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import { parse as parseYaml } from "yaml";
|
|
28
|
+
async function scalar(session, sql) {
|
|
29
|
+
const reader = await session.conn.runAndReadAll(sql);
|
|
30
|
+
return Number(reader.getRows()[0][0]);
|
|
31
|
+
}
|
|
32
|
+
const count = (table, where = "") => `SELECT COUNT(*) FROM "${table}"${where ? ` WHERE ${where}` : ""};`;
|
|
33
|
+
export async function runEventCatalogueCheck(session, options) {
|
|
34
|
+
if (!options.eventsPresent)
|
|
35
|
+
return { skipped: true, gaps: [] };
|
|
36
|
+
const domainsDir = join(options.sddRoot, "docs", "domains");
|
|
37
|
+
if (!existsSync(domainsDir))
|
|
38
|
+
return { skipped: false, gaps: [] };
|
|
39
|
+
const gaps = [];
|
|
40
|
+
for (const domain of readdirSync(domainsDir).sort()) {
|
|
41
|
+
const catalogPath = join(domainsDir, domain, "contracts", "events", "event-catalog.yaml");
|
|
42
|
+
if (!existsSync(catalogPath))
|
|
43
|
+
continue;
|
|
44
|
+
// Mirror of `yq '.events | length' || echo 0`: missing key or null → 0,
|
|
45
|
+
// an array → its length, a mapping → its key count, unparseable → 0.
|
|
46
|
+
let declared = 0;
|
|
47
|
+
try {
|
|
48
|
+
const doc = parseYaml(readFileSync(catalogPath, "utf-8"));
|
|
49
|
+
const events = doc?.["events"];
|
|
50
|
+
if (Array.isArray(events))
|
|
51
|
+
declared = events.length;
|
|
52
|
+
else if (events !== null && events !== undefined && typeof events === "object")
|
|
53
|
+
declared = Object.keys(events).length;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
declared = 0;
|
|
57
|
+
}
|
|
58
|
+
if (declared <= 0)
|
|
59
|
+
continue;
|
|
60
|
+
const emitted = await scalar(session, count("events", `COALESCE("domain_id", '') = '${domain.replace(/'/g, "''")}'`));
|
|
61
|
+
if (emitted < declared)
|
|
62
|
+
gaps.push({ domain, declared, emitted });
|
|
63
|
+
}
|
|
64
|
+
return { skipped: false, gaps };
|
|
65
|
+
}
|
|
66
|
+
export async function runRepoEdgesCheck(session, options) {
|
|
67
|
+
const repoCaps = await scalar(session, count("repo_capability"));
|
|
68
|
+
const capSvcs = await scalar(session, count("capability_service"));
|
|
69
|
+
const svcsWithRepo = await scalar(session, count("services", `COALESCE("primary_repo_id", '') <> ''`));
|
|
70
|
+
const repoContracts = await scalar(session, count("repo_contract"));
|
|
71
|
+
const contracts = await scalar(session, count("contracts"));
|
|
72
|
+
const svcContracts = await scalar(session, count("service_contract"));
|
|
73
|
+
// Mirror of the reference's two glob patterns (bash without globstar:
|
|
74
|
+
// `**` collapses to one level) — direct files AND one directory deep,
|
|
75
|
+
// schema.yaml deliberately NOT excluded because the reference scans it.
|
|
76
|
+
let repoConfigsWithContracts = 0;
|
|
77
|
+
const cfgDir = join(options.sddRoot, "orchestration", "repo-config");
|
|
78
|
+
if (existsSync(cfgDir)) {
|
|
79
|
+
const candidates = [];
|
|
80
|
+
for (const entry of readdirSync(cfgDir, { withFileTypes: true })) {
|
|
81
|
+
const p = join(cfgDir, entry.name);
|
|
82
|
+
if (entry.isFile() && entry.name.endsWith(".yaml"))
|
|
83
|
+
candidates.push(p);
|
|
84
|
+
else if (entry.isDirectory()) {
|
|
85
|
+
for (const f of readdirSync(p)) {
|
|
86
|
+
if (f.endsWith(".yaml"))
|
|
87
|
+
candidates.push(join(p, f));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const p of candidates) {
|
|
92
|
+
if (/^contracts:/m.test(readFileSync(p, "utf-8")))
|
|
93
|
+
repoConfigsWithContracts++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
...(repoCaps === 0 && capSvcs > 0 && svcsWithRepo > 0
|
|
98
|
+
? { repoCapabilityGap: { capabilityService: capSvcs, servicesWithRepo: svcsWithRepo } }
|
|
99
|
+
: {}),
|
|
100
|
+
...(repoContracts === 0 && contracts > 0 && repoConfigsWithContracts > 0
|
|
101
|
+
? { repoContractForwardGap: { contracts, repoConfigsWithContracts } }
|
|
102
|
+
: {}),
|
|
103
|
+
...(repoContracts === 0 && svcContracts > 0 && svcsWithRepo > 0
|
|
104
|
+
? { repoContractPathXGap: { serviceContracts: svcContracts, servicesWithRepo: svcsWithRepo } }
|
|
105
|
+
: {}),
|
|
106
|
+
...(repoContracts === 0 &&
|
|
107
|
+
contracts > 0 &&
|
|
108
|
+
repoConfigsWithContracts === 0 &&
|
|
109
|
+
svcContracts === 0
|
|
110
|
+
? { repoContractReverseGap: { contracts } }
|
|
111
|
+
: {}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// ─── 0158: glossary-xref ingestion gap ───────────────────────────────────
|
|
115
|
+
export async function runGlossaryXrefCheck(session, options) {
|
|
116
|
+
const manifest = join(options.sddRoot, "docs", "platform", "reference", "glossary-alignment-manifest.yaml");
|
|
117
|
+
if (!existsSync(manifest) || !options.xrefPresent)
|
|
118
|
+
return { finding: false };
|
|
119
|
+
const rows = await scalar(session, count("glossary_xref"));
|
|
120
|
+
return { finding: rows === 0 };
|
|
121
|
+
}
|
|
122
|
+
export async function runDataModelEntitiesCheck(session) {
|
|
123
|
+
const domainModels = await scalar(session, count("domain_models"));
|
|
124
|
+
const entities = await scalar(session, count("entities"));
|
|
125
|
+
const services = await scalar(session, count("services"));
|
|
126
|
+
const serviceEntity = await scalar(session, count("service_entity"));
|
|
127
|
+
const containerEntity = await scalar(session, count("c4_container_entity"));
|
|
128
|
+
const containersWithService = await scalar(session, count("c4_containers", `COALESCE("service_id", '') <> ''`));
|
|
129
|
+
return {
|
|
130
|
+
...(domainModels > 0 && entities === 0 ? { entitiesGap: { domainModels } } : {}),
|
|
131
|
+
...(entities > 0 && services > 0 && serviceEntity === 0
|
|
132
|
+
? { serviceEntityGap: { entities, services } }
|
|
133
|
+
: {}),
|
|
134
|
+
...(serviceEntity > 0 && containersWithService > 0 && containerEntity === 0
|
|
135
|
+
? { containerEntityGap: { containersWithService, serviceEntity } }
|
|
136
|
+
: {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export async function runCapabilityEventCheck(session) {
|
|
140
|
+
const serviceEvent = await scalar(session, count("service_event"));
|
|
141
|
+
const capabilityService = await scalar(session, count("capability_service"));
|
|
142
|
+
const capabilityEvent = await scalar(session, count("capability_event"));
|
|
143
|
+
let authoredGap;
|
|
144
|
+
if (capabilityEvent > 0) {
|
|
145
|
+
const authored = await scalar(session, count("capability_event", `COALESCE("source", '') = 'authored'`));
|
|
146
|
+
const derived = await scalar(session, count("capability_event", `COALESCE("source", '') = 'derived'`));
|
|
147
|
+
if (authored === 0 && derived > 0)
|
|
148
|
+
authoredGap = { derived };
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
...(serviceEvent > 0 && capabilityService > 0 && capabilityEvent === 0
|
|
152
|
+
? { derivableGap: { serviceEvent, capabilityService } }
|
|
153
|
+
: {}),
|
|
154
|
+
...(authoredGap !== undefined ? { authoredGap } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// ─── 0161: feature_event derivation gap ──────────────────────────────────
|
|
158
|
+
export async function runFeatureEventCheck(session) {
|
|
159
|
+
const serviceEvent = await scalar(session, count("service_event"));
|
|
160
|
+
const featureService = await scalar(session, count("feature_service"));
|
|
161
|
+
const featureEvent = await scalar(session, count("feature_event"));
|
|
162
|
+
return serviceEvent > 0 && featureService > 0 && featureEvent === 0
|
|
163
|
+
? { gap: { serviceEvent, featureService } }
|
|
164
|
+
: {};
|
|
165
|
+
}
|
|
166
|
+
// ─── 0162: forward platform-dependencies parity gap ──────────────────────
|
|
167
|
+
export async function runPlatformDependenciesCheck(session, options) {
|
|
168
|
+
const forwardFile = join(options.sddRoot, "app-platform-dependencies.yaml");
|
|
169
|
+
const forwardAuthored = existsSync(forwardFile) &&
|
|
170
|
+
/^\s*platform_dependencies:/m.test(readFileSync(forwardFile, "utf-8"));
|
|
171
|
+
if (!forwardAuthored)
|
|
172
|
+
return { finding: false };
|
|
173
|
+
const ppd = await scalar(session, count("product_platform_dependencies"));
|
|
174
|
+
return { finding: ppd === 0 };
|
|
175
|
+
}
|
|
176
|
+
// ─── 0177 F1: feature-spec promotion ─────────────────────────────────────
|
|
177
|
+
/** Python's round(): half to even — the reference computes pct with it. */
|
|
178
|
+
function pythonRound(x) {
|
|
179
|
+
const floor = Math.floor(x);
|
|
180
|
+
const diff = x - floor;
|
|
181
|
+
if (diff > 0.5)
|
|
182
|
+
return floor + 1;
|
|
183
|
+
if (diff < 0.5)
|
|
184
|
+
return floor;
|
|
185
|
+
return floor % 2 === 0 ? floor : floor + 1;
|
|
186
|
+
}
|
|
187
|
+
export async function runFeatureSpecPromotionCheck(session) {
|
|
188
|
+
const reader = await session.conn.runAndReadAll(`SELECT COALESCE("source", '') FROM "features";`);
|
|
189
|
+
let total = 0;
|
|
190
|
+
let resolvable = 0;
|
|
191
|
+
let intermediate = 0;
|
|
192
|
+
for (const r of reader.getRows()) {
|
|
193
|
+
const src = String(r[0] ?? "").trim();
|
|
194
|
+
total++;
|
|
195
|
+
if (src === "feature-spec" || src === "feature-tree")
|
|
196
|
+
resolvable++;
|
|
197
|
+
else if (src === "capability-spec" || src === "feature-grounding")
|
|
198
|
+
intermediate++;
|
|
199
|
+
}
|
|
200
|
+
if (total === 0 || intermediate === 0)
|
|
201
|
+
return {};
|
|
202
|
+
return {
|
|
203
|
+
finding: {
|
|
204
|
+
intermediate,
|
|
205
|
+
total,
|
|
206
|
+
pctResolvable: pythonRound((100 * resolvable) / total),
|
|
207
|
+
note: intermediate >= resolvable ? "predominantly un-promoted" : "partially promoted",
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// ─── 0177 F2: near-duplicate feature surfaces (the borderline: engine for
|
|
212
|
+
// access, the token Jaccard host-language) ───────────────────────────
|
|
213
|
+
function tokens(slug) {
|
|
214
|
+
return new Set(slug.split("-").filter((t) => t !== ""));
|
|
215
|
+
}
|
|
216
|
+
function near(a, b) {
|
|
217
|
+
const ta = tokens(a);
|
|
218
|
+
const tb = tokens(b);
|
|
219
|
+
if (ta.size === 0 || tb.size === 0)
|
|
220
|
+
return false;
|
|
221
|
+
const inter = [...ta].filter((t) => tb.has(t)).length;
|
|
222
|
+
if (inter === ta.size || inter === tb.size)
|
|
223
|
+
return true; // subset either way
|
|
224
|
+
const union = ta.size + tb.size - inter;
|
|
225
|
+
return union > 0 && inter / union >= 0.5;
|
|
226
|
+
}
|
|
227
|
+
export async function runFeatureSurfaceDuplicationCheck(session) {
|
|
228
|
+
const reader = await session.conn.runAndReadAll(`SELECT COALESCE("capability_id", ''), COALESCE("name", ''), COALESCE("source", '') FROM "features";`);
|
|
229
|
+
const rollup = new Map();
|
|
230
|
+
const detailed = new Map();
|
|
231
|
+
for (const r of reader.getRows()) {
|
|
232
|
+
const cap = String(r[0] ?? "").trim();
|
|
233
|
+
const slug = String(r[1] ?? "").trim();
|
|
234
|
+
const src = String(r[2] ?? "").trim();
|
|
235
|
+
if (cap === "" || slug === "")
|
|
236
|
+
continue;
|
|
237
|
+
if (src === "capability-spec") {
|
|
238
|
+
rollup.set(cap, [...(rollup.get(cap) ?? []), slug]);
|
|
239
|
+
}
|
|
240
|
+
else if (src === "feature-grounding") {
|
|
241
|
+
detailed.set(cap, [...(detailed.get(cap) ?? []), slug]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
let pairs = 0;
|
|
245
|
+
const caps = new Set();
|
|
246
|
+
for (const [cap, rollupSlugs] of rollup) {
|
|
247
|
+
const detailedSlugs = detailed.get(cap);
|
|
248
|
+
if (!detailedSlugs)
|
|
249
|
+
continue;
|
|
250
|
+
for (const r of rollupSlugs) {
|
|
251
|
+
for (const d of detailedSlugs) {
|
|
252
|
+
if (r !== d && near(r, d)) {
|
|
253
|
+
pairs++;
|
|
254
|
+
caps.add(cap);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return pairs > 0 ? { finding: { pairs, capabilities: caps.size } } : {};
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=gate-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-checks.js","sourceRoot":"","sources":["../../../src/lib/catalogue/gate-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2 parity harness — M-ADR 0205 §4.4.
|
|
3
|
+
*
|
|
4
|
+
* Runs the in-memory validators (the reference implementation) and the
|
|
5
|
+
* engine path on IDENTICAL input and compares count AND list. Zero
|
|
6
|
+
* disagreements is the cutover precondition; any disagreement is a
|
|
7
|
+
* defect in one side, adjudicated, never smoothed.
|
|
8
|
+
*
|
|
9
|
+
* What is compared exactly: internal FK failures (field for field) and
|
|
10
|
+
* enum violations (field for field). External findings are compared by
|
|
11
|
+
* COUNT — the in-memory path reports them only as rendered finding text,
|
|
12
|
+
* so a list comparison would be parsing prose. Engine-only PK duplicates
|
|
13
|
+
* are carried as information, outside the parity claim (no counterpart
|
|
14
|
+
* instrument exists).
|
|
15
|
+
*/
|
|
16
|
+
import type { CanonicalSchema } from "./schema-loader.js";
|
|
17
|
+
import type { CatalogueRow } from "./csv-writer.js";
|
|
18
|
+
import type { FkValidationOptions } from "./fk-validator.js";
|
|
19
|
+
import { type PkDuplicate, type TypeNonconformance } from "./engine-validator.js";
|
|
20
|
+
export interface KeySetDiff {
|
|
21
|
+
readonly agree: boolean;
|
|
22
|
+
readonly onlyOld: readonly string[];
|
|
23
|
+
readonly onlyNew: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
/** Order-insensitive exact diff of two violation key lists. */
|
|
26
|
+
export declare function diffKeySets(oldKeys: readonly string[], newKeys: readonly string[]): KeySetDiff;
|
|
27
|
+
export interface ParityReport {
|
|
28
|
+
readonly agree: boolean;
|
|
29
|
+
readonly fk: KeySetDiff & {
|
|
30
|
+
readonly oldCount: number;
|
|
31
|
+
readonly newCount: number;
|
|
32
|
+
};
|
|
33
|
+
readonly enums: KeySetDiff & {
|
|
34
|
+
readonly oldCount: number;
|
|
35
|
+
readonly newCount: number;
|
|
36
|
+
};
|
|
37
|
+
readonly external: {
|
|
38
|
+
readonly agree: boolean;
|
|
39
|
+
readonly oldCount: number;
|
|
40
|
+
readonly newCount: number;
|
|
41
|
+
};
|
|
42
|
+
/** Engine-only information, outside the parity claim. */
|
|
43
|
+
readonly pkDuplicates: readonly PkDuplicate[];
|
|
44
|
+
/** Engine-only information, outside the parity claim. */
|
|
45
|
+
readonly typeNonconformances: readonly TypeNonconformance[];
|
|
46
|
+
}
|
|
47
|
+
export declare function runParity(schema: CanonicalSchema, rowsByCatalogue: ReadonlyMap<string, readonly CatalogueRow[]>, options?: FkValidationOptions): Promise<ParityReport>;
|
|
48
|
+
//# sourceMappingURL=parity-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parity-harness.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/parity-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,UAAU,CAqBZ;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,yDAAyD;IACzD,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9C,yDAAyD;IACzD,QAAQ,CAAC,mBAAmB,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC7D;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,eAAe,EACvB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,EAC7D,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC,CA0DvB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2 parity harness — M-ADR 0205 §4.4.
|
|
3
|
+
*
|
|
4
|
+
* Runs the in-memory validators (the reference implementation) and the
|
|
5
|
+
* engine path on IDENTICAL input and compares count AND list. Zero
|
|
6
|
+
* disagreements is the cutover precondition; any disagreement is a
|
|
7
|
+
* defect in one side, adjudicated, never smoothed.
|
|
8
|
+
*
|
|
9
|
+
* What is compared exactly: internal FK failures (field for field) and
|
|
10
|
+
* enum violations (field for field). External findings are compared by
|
|
11
|
+
* COUNT — the in-memory path reports them only as rendered finding text,
|
|
12
|
+
* so a list comparison would be parsing prose. Engine-only PK duplicates
|
|
13
|
+
* are carried as information, outside the parity claim (no counterpart
|
|
14
|
+
* instrument exists).
|
|
15
|
+
*/
|
|
16
|
+
import { FindingsLog } from "./findings.js";
|
|
17
|
+
import { validateForeignKeys } from "./fk-validator.js";
|
|
18
|
+
import { validateColumnEnums } from "./enum-validator.js";
|
|
19
|
+
import { validateWithEngine, } from "./engine-validator.js";
|
|
20
|
+
/** Order-insensitive exact diff of two violation key lists. */
|
|
21
|
+
export function diffKeySets(oldKeys, newKeys) {
|
|
22
|
+
const count = (keys) => {
|
|
23
|
+
const m = new Map();
|
|
24
|
+
for (const k of keys)
|
|
25
|
+
m.set(k, (m.get(k) ?? 0) + 1);
|
|
26
|
+
return m;
|
|
27
|
+
};
|
|
28
|
+
const oldCounts = count(oldKeys);
|
|
29
|
+
const newCounts = count(newKeys);
|
|
30
|
+
const onlyOld = [];
|
|
31
|
+
const onlyNew = [];
|
|
32
|
+
for (const [k, n] of oldCounts) {
|
|
33
|
+
const surplus = n - (newCounts.get(k) ?? 0);
|
|
34
|
+
for (let i = 0; i < surplus; i++)
|
|
35
|
+
onlyOld.push(k);
|
|
36
|
+
}
|
|
37
|
+
for (const [k, n] of newCounts) {
|
|
38
|
+
const surplus = n - (oldCounts.get(k) ?? 0);
|
|
39
|
+
for (let i = 0; i < surplus; i++)
|
|
40
|
+
onlyNew.push(k);
|
|
41
|
+
}
|
|
42
|
+
onlyOld.sort();
|
|
43
|
+
onlyNew.sort();
|
|
44
|
+
return { agree: onlyOld.length === 0 && onlyNew.length === 0, onlyOld, onlyNew };
|
|
45
|
+
}
|
|
46
|
+
export async function runParity(schema, rowsByCatalogue, options = {}) {
|
|
47
|
+
const oldFk = validateForeignKeys(schema, rowsByCatalogue, new FindingsLog(), options);
|
|
48
|
+
const oldEnums = validateColumnEnums(schema, rowsByCatalogue, new FindingsLog());
|
|
49
|
+
const engine = await validateWithEngine(schema, rowsByCatalogue, options);
|
|
50
|
+
const fkKey = (f) => `${f.catalogue}|${f.column}|${f.referencingRow}|${f.value}|${f.target}`;
|
|
51
|
+
const enumKey = (v) => `${v.catalogue}|${v.column}|${v.rowPk}|${v.value}`;
|
|
52
|
+
const fk = {
|
|
53
|
+
...diffKeySets(oldFk.internalFailures.map(fkKey), engine.fk.internalFailures.map(fkKey)),
|
|
54
|
+
oldCount: oldFk.internalFailures.length,
|
|
55
|
+
newCount: engine.fk.internalFailures.length,
|
|
56
|
+
};
|
|
57
|
+
const enums = {
|
|
58
|
+
...diffKeySets(oldEnums.violations.map(enumKey), engine.enums.violations.map(enumKey)),
|
|
59
|
+
oldCount: oldEnums.violations.length,
|
|
60
|
+
newCount: engine.enums.violations.length,
|
|
61
|
+
};
|
|
62
|
+
const external = {
|
|
63
|
+
agree: oldFk.externalFindings === engine.fk.externalFindings,
|
|
64
|
+
oldCount: oldFk.externalFindings,
|
|
65
|
+
newCount: engine.fk.externalFindings,
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
agree: fk.agree && enums.agree && external.agree,
|
|
69
|
+
fk,
|
|
70
|
+
enums,
|
|
71
|
+
external,
|
|
72
|
+
pkDuplicates: engine.pkDuplicates,
|
|
73
|
+
typeNonconformances: engine.typeNonconformances,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=parity-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parity-harness.js","sourceRoot":"","sources":["../../../src/lib/catalogue/parity-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* NOT require updating the entries here.
|
|
13
13
|
*
|
|
14
14
|
* Schemas:
|
|
15
|
-
* - catalogue_schema: docs/method/
|
|
16
|
-
* - sdd_manifest: docs/method/
|
|
17
|
-
* - aggregation_manifest: docs/method/
|
|
15
|
+
* - catalogue_schema: docs/method/foundations/schemas/catalogue-schema.yaml
|
|
16
|
+
* - sdd_manifest: docs/method/foundations/schemas/sdd-manifest-schema.yaml
|
|
17
|
+
* - aggregation_manifest: docs/method/foundations/schemas/aggregation-manifest-schema.yaml
|
|
18
18
|
*
|
|
19
19
|
* Bump rules per schema (in their respective YAML headers):
|
|
20
20
|
* - Patch: typo / description / non-structural fix.
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* NOT require updating the entries here.
|
|
13
13
|
*
|
|
14
14
|
* Schemas:
|
|
15
|
-
* - catalogue_schema: docs/method/
|
|
16
|
-
* - sdd_manifest: docs/method/
|
|
17
|
-
* - aggregation_manifest: docs/method/
|
|
15
|
+
* - catalogue_schema: docs/method/foundations/schemas/catalogue-schema.yaml
|
|
16
|
+
* - sdd_manifest: docs/method/foundations/schemas/sdd-manifest-schema.yaml
|
|
17
|
+
* - aggregation_manifest: docs/method/foundations/schemas/aggregation-manifest-schema.yaml
|
|
18
18
|
*
|
|
19
19
|
* Bump rules per schema (in their respective YAML headers):
|
|
20
20
|
* - Patch: typo / description / non-structural fix.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scores coverage — M-ADR 0205 §4.5's coverage instrument, the fourteenth
|
|
3
|
+
* engine check (Phase B, B2). SQL on the §4.1 engine, like every other
|
|
4
|
+
* catalogue-reading predicate; `check-repo-config-coverage.sh` remains the
|
|
5
|
+
* only shell survivor and is not the model for this.
|
|
6
|
+
*
|
|
7
|
+
* The claim: *every eligible artefact carries a current score*. Eligibility is
|
|
8
|
+
* computed per rubric against the catalogue that holds its targets, and the
|
|
9
|
+
* predicate reports BOTH directions, because the two say different things:
|
|
10
|
+
*
|
|
11
|
+
* - an eligible target with no score is a GAP — nobody has judged it;
|
|
12
|
+
* - a score whose target does not resolve is an ORPHANED SCORE — the
|
|
13
|
+
* assessment corpus has decayed away from the model it describes.
|
|
14
|
+
*
|
|
15
|
+
* The second direction is not decoration. Measured on the forward estate at
|
|
16
|
+
* introduction: 85 of 99 ADR scores point at ids that no longer exist, because
|
|
17
|
+
* a rename moved the ADR canon and the registry keys were never migrated. A
|
|
18
|
+
* one-directional predicate would have reported that estate as having 99
|
|
19
|
+
* scored ADRs while none of them resolved.
|
|
20
|
+
*
|
|
21
|
+
* THE JOIN VOCABULARY IS THE WHOLE DIFFICULTY, and it is declared rather than
|
|
22
|
+
* guessed. A registry's entry keys are not the catalogue's ids, and the
|
|
23
|
+
* mismatch differs per rubric — measured, not assumed:
|
|
24
|
+
*
|
|
25
|
+
* - contract-quality keys are SPEC PATHS (`contracts-avro/.../X.avsc`),
|
|
26
|
+
* joining `contracts.spec_path`; against `contracts.id` they score 0 of 55.
|
|
27
|
+
* - adr-quality keys carry a tier prefix (`M-ADR-0001`) the catalogue strips
|
|
28
|
+
* (`ADR-0001`); the raw join scores 0 of 99.
|
|
29
|
+
* - domain-architecture keys are plain domain slugs and join `domains.id`
|
|
30
|
+
* directly, 13 of 13.
|
|
31
|
+
*
|
|
32
|
+
* So each rubric declares its catalogue, its join column and its reference
|
|
33
|
+
* transform, and the predicate REPORTS the resolution rate it achieved. A join
|
|
34
|
+
* that silently resolves nothing looks exactly like an estate that has scored
|
|
35
|
+
* nothing — the confident-false-zero shape this whole phase exists to remove.
|
|
36
|
+
*
|
|
37
|
+
* Rubrics whose targets have NO catalogue (c4-diagram, strategic-doc,
|
|
38
|
+
* user-story, work-order) have no eligibility denominator to compute. They are
|
|
39
|
+
* reported as such by name and their scores are still resolution-checked as
|
|
40
|
+
* far as they can be — never silently omitted, because a rubric missing from
|
|
41
|
+
* the output reads as a rubric with nothing to say.
|
|
42
|
+
*
|
|
43
|
+
* Reporting-only at both tiers, per §4.5. Exemption vocabulary starts EMPTY
|
|
44
|
+
* (M-ADR 0199): there is no way to mark a target exempt yet, deliberately, so
|
|
45
|
+
* the first figure is the honest total.
|
|
46
|
+
*
|
|
47
|
+
* ADOPTION GATING — a rubric is measured only where its REGISTRY EXISTS. An SDD
|
|
48
|
+
* that carries no `<rubric>-scores.yaml` has not adopted that rubric, so it has
|
|
49
|
+
* no eligible population for it, and reporting its whole ADR/contract/capability
|
|
50
|
+
* corpus as unscored would be true-but-useless noise. This is the same n/a rule
|
|
51
|
+
* the repo-config predicate applies and the same rule the quality-scores builder
|
|
52
|
+
* applies to an absent registry directory: absence of the whole surface is not a
|
|
53
|
+
* gap in it. Measured before adopting it: without this rule ONE reverse-estate
|
|
54
|
+
* SDD emits 630 gap lines for rubrics it has never used, which across that
|
|
55
|
+
* estate would swamp the baseline re-take and bury the real signal.
|
|
56
|
+
*
|
|
57
|
+
* The distinction that must NOT be lost, and is not: a registry that EXISTS but
|
|
58
|
+
* is EMPTY reports its full population as gaps. That is the method repo's own
|
|
59
|
+
* state — fifteen deliberately-empty containers — and it is exactly the silence
|
|
60
|
+
* §4.5 exists to make loud. Absent surface and empty surface are different
|
|
61
|
+
* claims, and conflating them is the defect this whole phase is about.
|
|
62
|
+
*
|
|
63
|
+
* The n/a count is always printed. A rubric skipped silently reads as a rubric
|
|
64
|
+
* with nothing to report.
|
|
65
|
+
*/
|
|
66
|
+
import type { EngineSession } from "./engine-validator.js";
|
|
67
|
+
export type ScoresCoverageTier = "member" | "aggregate";
|
|
68
|
+
/**
|
|
69
|
+
* How a rubric's scores reach the catalogue rows they describe.
|
|
70
|
+
*
|
|
71
|
+
* `refTransform` is applied to the SCORE's target_ref before comparison, in
|
|
72
|
+
* SQL, so the transform is visible in the query rather than hidden in host
|
|
73
|
+
* code. `null` means the ref is already in the catalogue's vocabulary.
|
|
74
|
+
*/
|
|
75
|
+
export interface RubricEligibility {
|
|
76
|
+
readonly rubricId: string;
|
|
77
|
+
readonly targetKind: string;
|
|
78
|
+
/** Catalogue holding the eligible population; null when none exists. */
|
|
79
|
+
readonly catalogue: string | null;
|
|
80
|
+
/** Column in that catalogue the score's target_ref matches. */
|
|
81
|
+
readonly joinColumn: string;
|
|
82
|
+
/** SQL expression transforming target_ref into the catalogue's vocabulary. */
|
|
83
|
+
readonly refTransform: ((ref: string) => string) | null;
|
|
84
|
+
/** SQL predicate narrowing the catalogue to eligible rows; null = all rows. */
|
|
85
|
+
readonly eligibilityFilter: string | null;
|
|
86
|
+
/** Why the filter is what it is — rendered nowhere, read by whoever changes it. */
|
|
87
|
+
readonly eligibilityNote: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The declared mapping. Three entries are EXERCISED against real estate data
|
|
91
|
+
* (adr-quality, contract-quality, domain-architecture); the rest are declared
|
|
92
|
+
* from the registry and rubric shapes and have no populated corpus to verify
|
|
93
|
+
* against yet — a distinction the metric line states rather than blurs.
|
|
94
|
+
*/
|
|
95
|
+
export declare const RUBRIC_ELIGIBILITY: readonly RubricEligibility[];
|
|
96
|
+
export interface ScoresCoverageFinding {
|
|
97
|
+
readonly kind: "uncovered" | "orphaned-score" | "unresolvable-staleness";
|
|
98
|
+
readonly rubricId: string;
|
|
99
|
+
readonly subject: string;
|
|
100
|
+
}
|
|
101
|
+
export interface RubricCoverageMetric {
|
|
102
|
+
readonly rubricId: string;
|
|
103
|
+
readonly targetKind: string;
|
|
104
|
+
/** null when the rubric has no catalogued population. */
|
|
105
|
+
readonly eligible: number | null;
|
|
106
|
+
readonly covered: number;
|
|
107
|
+
/** Scores present for this rubric, however they resolve. */
|
|
108
|
+
readonly scored: number;
|
|
109
|
+
readonly orphaned: number;
|
|
110
|
+
}
|
|
111
|
+
export interface ScoresCoverageResult {
|
|
112
|
+
readonly findings: readonly ScoresCoverageFinding[];
|
|
113
|
+
readonly metrics: readonly RubricCoverageMetric[];
|
|
114
|
+
/** Rubrics carrying scores that no eligibility entry declares. */
|
|
115
|
+
readonly undeclaredRubrics: readonly string[];
|
|
116
|
+
/** Rubrics skipped because this SDD carries no registry for them. */
|
|
117
|
+
readonly notAdopted: readonly string[];
|
|
118
|
+
readonly stalenessBasis: {
|
|
119
|
+
readonly corpusRef: number;
|
|
120
|
+
readonly scoredAt: number;
|
|
121
|
+
readonly none: number;
|
|
122
|
+
};
|
|
123
|
+
readonly totalScores: number;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Runs the predicate. `available` names the catalogues actually present, so a
|
|
127
|
+
* rubric whose population file is absent is skipped the way every other
|
|
128
|
+
* predicate skips an absent population — silently, because absence of the
|
|
129
|
+
* whole surface is not a gap in it — while a rubric whose population is
|
|
130
|
+
* PRESENT but empty still reports its zero.
|
|
131
|
+
*/
|
|
132
|
+
export declare function runScoresCoverage(session: EngineSession, options: {
|
|
133
|
+
readonly tier: ScoresCoverageTier;
|
|
134
|
+
readonly available: ReadonlySet<string>;
|
|
135
|
+
/** SDD root — resolves which rubrics this SDD has actually adopted. */
|
|
136
|
+
readonly sddRoot: string;
|
|
137
|
+
}): Promise<ScoresCoverageResult>;
|
|
138
|
+
//# sourceMappingURL=scores-coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scores-coverage.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/scores-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,CAAC;IACxD,+EAA+E;IAC/E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,mFAAmF;IACnF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAiJ1D,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB,GAAG,wBAAwB,CAAC;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAClD,kEAAkE;IAClE,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAYD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE;IACP,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,oBAAoB,CAAC,CA+J/B"}
|