kibi-cli 2.38.0 → 2.40.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/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +4 -0
- package/dist/cli-register-foundation.js +2 -2
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +33 -9
- package/dist/commands/coverage.d.ts +1 -0
- package/dist/commands/coverage.d.ts.map +1 -1
- package/dist/commands/coverage.js +40 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +29 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +4 -0
- package/dist/commands/migrate-plan-record.d.ts +18 -0
- package/dist/commands/migrate-plan-record.d.ts.map +1 -0
- package/dist/commands/migrate-plan-record.js +112 -0
- package/dist/commands/migrate.d.ts +11 -2
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +60 -8
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +18 -3
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +17 -4
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +6 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +8 -0
- package/dist/commands/telemetry.d.ts.map +1 -1
- package/dist/commands/telemetry.js +12 -2
- package/dist/extractors/markdown.d.ts +6 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +21 -0
- package/dist/extractors/symbol-title-match.d.ts +31 -0
- package/dist/extractors/symbol-title-match.d.ts.map +1 -0
- package/dist/extractors/symbol-title-match.js +133 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +81 -12
- package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery-evidence.js +44 -2
- package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery.js +1 -0
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +12 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts +7 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
- package/dist/operations/bootstrap/plugin-offers.js +73 -3
- package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
- package/dist/operations/modeling/logic-modeling.js +2 -1
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +2 -1
- package/dist/operations/mutation/symbol-refresh.d.ts +2 -0
- package/dist/operations/mutation/symbol-refresh.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-refresh.js +6 -1
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +7 -0
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +2 -1
- package/dist/operations/proof/claim-bindings.d.ts +11 -0
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
- package/dist/operations/proof/claim-bindings.js +144 -1
- package/dist/operations/proof/code-certificates.d.ts +10 -3
- package/dist/operations/proof/code-certificates.d.ts.map +1 -1
- package/dist/operations/proof/code-certificates.js +65 -13
- package/dist/operations/proof/code-languages.d.ts +104 -0
- package/dist/operations/proof/code-languages.d.ts.map +1 -0
- package/dist/operations/proof/code-languages.js +119 -0
- package/dist/operations/proof/code-models.d.ts +2 -0
- package/dist/operations/proof/code-models.d.ts.map +1 -1
- package/dist/operations/proof/code-models.js +11 -5
- package/dist/operations/proof/code-runner.d.ts +12 -9
- package/dist/operations/proof/code-runner.d.ts.map +1 -1
- package/dist/operations/proof/code-runner.js +81 -38
- package/dist/operations/proof/code-scope.d.ts +8 -0
- package/dist/operations/proof/code-scope.d.ts.map +1 -1
- package/dist/operations/proof/code-scope.js +30 -1
- package/dist/operations/proof/explain.d.ts +76 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +228 -0
- package/dist/operations/proof/ingest-proof.d.ts +2 -0
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +1 -0
- package/dist/operations/proof/java-package-shadow.d.ts +14 -0
- package/dist/operations/proof/java-package-shadow.d.ts.map +1 -0
- package/dist/operations/proof/java-package-shadow.js +389 -0
- package/dist/operations/proof/prolog-evaluator.d.ts +14 -0
- package/dist/operations/proof/prolog-evaluator.d.ts.map +1 -0
- package/dist/operations/proof/prolog-evaluator.js +247 -0
- package/dist/operations/proof/prolog-source-reader.d.ts +20 -0
- package/dist/operations/proof/prolog-source-reader.d.ts.map +1 -0
- package/dist/operations/proof/prolog-source-reader.js +1123 -0
- package/dist/operations/proof/source-code-readers.d.ts +6 -0
- package/dist/operations/proof/source-code-readers.d.ts.map +1 -1
- package/dist/operations/proof/source-code-readers.js +879 -75
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/case-preview.js +216 -0
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +3 -0
- package/dist/operations/semantic-advisor/types.d.ts +23 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +15 -34
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.js +15 -34
- package/dist/plugins/plugin-install-check.d.ts +21 -0
- package/dist/plugins/plugin-install-check.d.ts.map +1 -0
- package/dist/plugins/plugin-install-check.js +62 -0
- package/dist/plugins/proof-reference-extractors.d.ts +20 -0
- package/dist/plugins/proof-reference-extractors.d.ts.map +1 -0
- package/dist/plugins/proof-reference-extractors.js +104 -0
- package/dist/plugins/reference-language-suggestion.d.ts +51 -0
- package/dist/plugins/reference-language-suggestion.d.ts.map +1 -0
- package/dist/plugins/reference-language-suggestion.js +277 -0
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +3 -1
- package/dist/plugins/source-analysis-service.d.ts.map +1 -1
- package/dist/plugins/source-analysis-service.js +4 -0
- package/dist/plugins/source-change-analysis.d.ts +26 -1
- package/dist/plugins/source-change-analysis.d.ts.map +1 -1
- package/dist/plugins/source-change-analysis.js +77 -5
- package/dist/plugins/source-classification.d.ts +2 -2
- package/dist/plugins/source-classification.d.ts.map +1 -1
- package/dist/plugins/source-classification.js +45 -1
- package/dist/public/operations/catalog.d.ts +62 -7
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +3 -0
- package/dist/public/operations/evidence-floor.d.ts +8 -0
- package/dist/public/operations/evidence-floor.d.ts.map +1 -1
- package/dist/public/operations/evidence-floor.js +19 -1
- package/dist/public/operations/repair-plan.d.ts +46 -0
- package/dist/public/operations/repair-plan.d.ts.map +1 -1
- package/dist/public/operations/repair-plan.js +110 -1
- package/dist/public/operations/schema6-check-actions.js +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +3 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +61 -6
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +30 -0
- package/dist/public/operations/specs/reporting.d.ts +8 -0
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +26 -3
- package/dist/public/operations/specs/semantic.d.ts.map +1 -1
- package/dist/public/operations/specs/semantic.js +2 -1
- package/dist/public/operations/specs/upsert.d.ts +61 -6
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-coordinates-check.d.ts +11 -0
- package/dist/public/operations/symbol-coordinates-check.d.ts.map +1 -0
- package/dist/public/operations/symbol-coordinates-check.js +66 -0
- package/dist/public/proof-protocol.d.ts +31 -6
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +45 -15
- package/dist/public/proof-sources.d.ts +4 -2
- package/dist/public/proof-sources.d.ts.map +1 -1
- package/dist/public/proof-sources.js +43 -4
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +59 -0
- package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/public/skills/kibi-usage/SKILL.md +14 -3
- package/dist/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +44 -3
- package/dist/schemas/entity.schema.json +126 -6
- package/dist/search-answer.d.ts +3 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +56 -3
- package/dist/traceability/analysis-gate.d.ts +3 -1
- package/dist/traceability/analysis-gate.d.ts.map +1 -1
- package/dist/traceability/analysis-gate.js +9 -1
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +2 -0
- package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
- package/dist/traceability/staged-file-coverage.js +7 -2
- package/dist/traceability/symbol-extract.d.ts +17 -0
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +69 -15
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +11 -1
- package/dist/traceability/validate.d.ts.map +1 -1
- package/dist/traceability/validate.js +5 -7
- package/dist/types/entities.d.ts +12 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/usage-telemetry.d.ts +9 -0
- package/dist/usage-telemetry.d.ts.map +1 -1
- package/dist/usage-telemetry.js +50 -4
- package/dist/utils/first-sentence.d.ts +9 -0
- package/dist/utils/first-sentence.d.ts.map +1 -0
- package/dist/utils/first-sentence.js +52 -0
- package/dist/utils/rule-registry.generated.d.ts +11 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +13 -0
- package/package.json +5 -5
- package/schema/entities.pl +12 -0
- package/src/public/operations/check-executor.ts +8 -0
- package/src/public/operations/evidence-floor.ts +29 -1
- package/src/public/operations/repair-plan.ts +152 -1
- package/src/public/operations/schema6-check-actions.ts +1 -1
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/mutation-schemas.ts +34 -0
- package/src/public/operations/specs/reporting.ts +38 -3
- package/src/public/operations/specs/semantic.ts +2 -1
- package/src/public/operations/symbol-coordinates-check.ts +79 -0
- package/src/public/proof-protocol-types.d.ts +22 -5
- package/src/public/proof-protocol.ts +78 -19
- package/src/public/proof-sources.ts +51 -3
- package/src/public/schemas/entity.ts +65 -0
- package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/src/public/skills/kibi-decisions/SKILL.md +7 -2
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/src/public/skills/kibi-usage/SKILL.md +14 -3
- package/src/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
- package/src/public/skills/kibi-usage/resources/proof.md +44 -3
- package/src/schemas/entity.schema.json +126 -6
|
@@ -18,7 +18,11 @@
|
|
|
18
18
|
import { randomBytes } from "node:crypto";
|
|
19
19
|
import { rmSync, writeFileSync } from "node:fs";
|
|
20
20
|
import path from "node:path";
|
|
21
|
+
import fg from "fast-glob";
|
|
22
|
+
import { normalizeEntityId, parseTriples } from "../../prolog/codec.js";
|
|
21
23
|
import { runOperationJsonQuery, toPrologAtom, } from "../../public/operations/prolog-json.js";
|
|
24
|
+
import { loadEntities } from "../../public/operations/discovery-entities.js";
|
|
25
|
+
import { matchWorkspaceFiles } from "../../public/proof-sources.js";
|
|
22
26
|
import { compileWitness, loadSymbol, smtAssertion, } from "./code-certificates.js";
|
|
23
27
|
import { stringConstraintProblem } from "./code-models.js";
|
|
24
28
|
function record(value) {
|
|
@@ -264,6 +268,143 @@ async function derivedProblem(context, contract, certificate, row, coveredBy) {
|
|
|
264
268
|
return `the query does not assert the negation of ${factId}'s constraint ${negation}`;
|
|
265
269
|
return null;
|
|
266
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Callees that read one environment variable. A string_args read of one of
|
|
273
|
+
* them sees only that getter's first arguments, never the other ways the
|
|
274
|
+
* code reads the environment, so it cannot decide an eq, subset_of or
|
|
275
|
+
* excludes claim about what the code reads; the env extract reads them all.
|
|
276
|
+
*/
|
|
277
|
+
const ENVIRONMENT_GETTER = /(?:^|[.:/])(?:getenv|Getenv|LookupEnv|getenvb|GetEnvironmentVariable)$|(?:^|[.:/])env::var(?:_os)?$|^(?:os\.environ\.get|ENV\.fetch|process\.env)$/;
|
|
278
|
+
export function environmentGetterCallee(callee) {
|
|
279
|
+
return ENVIRONMENT_GETTER.test(callee.replace(/\s+/g, "").replace(/\/\d+$/, ""));
|
|
280
|
+
}
|
|
281
|
+
const CLOSED_OPERATORS = new Set(["eq", "subset_of", "excludes"]);
|
|
282
|
+
const FILE_NAME_TOKEN = /[A-Za-z0-9_][A-Za-z0-9_./-]*\.[A-Za-z0-9]{1,10}\b/g;
|
|
283
|
+
/** A quoted or backticked path, which may hold spaces (`automated install/x.sh`). */
|
|
284
|
+
const QUOTED_PATH = /[`'"]([^`'"\n]*[/.][^`'"\n]*)[`'"]/g;
|
|
285
|
+
/** A slashed path without an extension (`src/match` for src/match.c). */
|
|
286
|
+
const BARE_PATH = /[A-Za-z0-9_][A-Za-z0-9_.-]*(?:\/[A-Za-z0-9_.-]+)+/g;
|
|
287
|
+
function claimFileCandidates(token) {
|
|
288
|
+
const escaped = fg.escapePath(token.replace(/^\.?\/+/, ""));
|
|
289
|
+
const segments = escaped.split("/");
|
|
290
|
+
// The token as a path, as a name anywhere, then with leading segments
|
|
291
|
+
// dropped (a repository prefix such as fzy/src/match.c), then, for a
|
|
292
|
+
// slashed name without an extension, any extension.
|
|
293
|
+
const tries = [[escaped], [`**/${escaped}`]];
|
|
294
|
+
for (let drop = 1; drop < segments.length; drop += 1)
|
|
295
|
+
tries.push([`**/${segments.slice(drop).join("/")}`]);
|
|
296
|
+
if (segments.length > 1 && !/\.[^/.]+$/.test(escaped))
|
|
297
|
+
tries.push([`${escaped}.*`, `**/${escaped}.*`]);
|
|
298
|
+
return tries;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The project files a claim names in its subject key or claim text (for
|
|
302
|
+
* example `src/match.c`, `utils.sh`, `fzy/src/match.c`, `src/Match.c` or
|
|
303
|
+
* `src/match`): a token resolves, ignoring case, to the file at that path,
|
|
304
|
+
* else to every project file with that name or path suffix, else (for a
|
|
305
|
+
* slashed name without an extension) to the files with that stem. Tokens
|
|
306
|
+
* that name no file (dotted subject keys such as `kibi.cli`) resolve to
|
|
307
|
+
* nothing.
|
|
308
|
+
*/
|
|
309
|
+
// implements REQ-kibi-source-proof-kinds
|
|
310
|
+
export function namedClaimFiles(workspaceRoot, texts) {
|
|
311
|
+
const named = new Map();
|
|
312
|
+
for (const value of texts) {
|
|
313
|
+
const tokens = [
|
|
314
|
+
...[...value.matchAll(QUOTED_PATH)].map((match) => match[1] ?? ""),
|
|
315
|
+
...[...value.matchAll(FILE_NAME_TOKEN)].map((match) => match[0]),
|
|
316
|
+
...[...value.matchAll(BARE_PATH)].map((match) => match[0]),
|
|
317
|
+
];
|
|
318
|
+
for (const raw of tokens) {
|
|
319
|
+
const token = raw.trim();
|
|
320
|
+
if (token === "" || named.has(token))
|
|
321
|
+
continue;
|
|
322
|
+
for (const patterns of claimFileCandidates(token)) {
|
|
323
|
+
const files = matchWorkspaceFiles(workspaceRoot, patterns, [], false);
|
|
324
|
+
if (files.length > 0) {
|
|
325
|
+
named.set(token, files);
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return named;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* What a references read must cover for the claims it proves. The read
|
|
335
|
+
* decides a claim only for the files it reads, so every symbol the test
|
|
336
|
+
* covers (covered_by) and every symbol that implements the claim's
|
|
337
|
+
* requirement must lie in one of those files: otherwise the claim, which is
|
|
338
|
+
* about that symbol's code, would be decided on other files. A string_args
|
|
339
|
+
* read of an environment getter cannot decide a closed claim (eq, subset_of,
|
|
340
|
+
* excludes) about what the code reads, since the other getters are unread.
|
|
341
|
+
*/
|
|
342
|
+
// implements REQ-kibi-source-proof-kinds
|
|
343
|
+
async function sourceScopeCheck(context, contract, coveredBy) {
|
|
344
|
+
const spec = contract.source;
|
|
345
|
+
if (contract.kind !== "source" || spec?.reader !== "references")
|
|
346
|
+
return null;
|
|
347
|
+
const list = (value) => typeof value === "string"
|
|
348
|
+
? [value]
|
|
349
|
+
: Array.isArray(value)
|
|
350
|
+
? value.filter((item) => typeof item === "string")
|
|
351
|
+
: [];
|
|
352
|
+
const read = new Set(matchWorkspaceFiles(context.workspaceRoot, list(spec.files), list(spec.ignore)));
|
|
353
|
+
const implementers = new Map();
|
|
354
|
+
if (context.prolog !== undefined) {
|
|
355
|
+
const result = await context.prolog.query("findall([From,To,'implements'], kb_relationship(implements, From, To), Rels)");
|
|
356
|
+
if (!result.success)
|
|
357
|
+
throw new Error(`implements relationship query failed: ${result.error ?? "Unknown error"}`);
|
|
358
|
+
for (const [from, to] of parseTriples(result.bindings.Rels ?? "[]")) {
|
|
359
|
+
const requirement = normalizeEntityId(to);
|
|
360
|
+
implementers.set(requirement, [
|
|
361
|
+
...(implementers.get(requirement) ?? []),
|
|
362
|
+
normalizeEntityId(from),
|
|
363
|
+
]);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const files = new Map();
|
|
367
|
+
const fileOf = async (symbolId) => {
|
|
368
|
+
if (!files.has(symbolId))
|
|
369
|
+
files.set(symbolId, (await loadSymbol(context, symbolId))?.sourceFile ?? "");
|
|
370
|
+
return files.get(symbolId) ?? "";
|
|
371
|
+
};
|
|
372
|
+
const callee = typeof spec.callee === "string" ? spec.callee : "";
|
|
373
|
+
const getter = spec.extract === "string_args" && environmentGetterCallee(callee);
|
|
374
|
+
return async (row) => {
|
|
375
|
+
const operator = text(record(row.obligation)?.operator);
|
|
376
|
+
if (getter && CLOSED_OPERATORS.has(operator))
|
|
377
|
+
return `a string_args read of ${callee} sees only that getter's arguments, not the other ways the code reads the environment, so it cannot decide a ${operator} claim; read the files with extract env`;
|
|
378
|
+
const linked = [
|
|
379
|
+
...[...coveredBy].map((id) => ({ id, how: "is covered by the test" })),
|
|
380
|
+
...(implementers.get(row.requirement_id ?? "") ?? []).map((id) => ({
|
|
381
|
+
id,
|
|
382
|
+
how: `implements ${row.requirement_id}`,
|
|
383
|
+
})),
|
|
384
|
+
];
|
|
385
|
+
if (row.fact_id && context.prolog !== undefined) {
|
|
386
|
+
const [fact] = await loadEntities(context.prolog, { id: row.fact_id, type: "fact" });
|
|
387
|
+
const named = namedClaimFiles(context.workspaceRoot, [
|
|
388
|
+
text(fact?.subject_key),
|
|
389
|
+
text(fact?.claim_text),
|
|
390
|
+
]);
|
|
391
|
+
const unread = [...named].filter(([, paths]) => !paths.some((file) => read.has(file)));
|
|
392
|
+
if (unread.length > 0) {
|
|
393
|
+
const [token, paths] = unread[0];
|
|
394
|
+
return `the claim is about ${token}${paths[0] !== token ? ` (${paths.slice(0, 3).join(", ")})` : ""}, which the read does not include. Kibi decides the claim only on the files it reads, so add that file to files; if Kibi cannot read it, the claim cannot be decided`;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const outside = [];
|
|
398
|
+
for (const { id, how } of linked) {
|
|
399
|
+
const file = await fileOf(id);
|
|
400
|
+
if (file !== "" && !read.has(file) && !outside.some((text) => text.startsWith(`${id} `)))
|
|
401
|
+
outside.push(`${id} (${file}) ${how}`);
|
|
402
|
+
}
|
|
403
|
+
if (outside.length === 0)
|
|
404
|
+
return null;
|
|
405
|
+
return `the read does not cover the code the claim is about: ${outside.slice(0, 3).join("; ")}${outside.length > 3 ? ` and ${outside.length - 3} more` : ""}. Kibi decides the claim only on the files it reads, so add those files to files; if Kibi cannot read them, the claim cannot be decided for them`;
|
|
406
|
+
};
|
|
407
|
+
}
|
|
267
408
|
/**
|
|
268
409
|
* The evidence level a receipt records. A certificate that re-checks but
|
|
269
410
|
* derives none of the claims it names from the code proves nothing about
|
|
@@ -306,6 +447,7 @@ export async function judgeClaimBindings(context, input) {
|
|
|
306
447
|
const harnessed = input.contract.kind === "rule" &&
|
|
307
448
|
Object.values(input.contract.predicate_source ?? {}).some((row) => (row.harness_for ?? []).length > 0);
|
|
308
449
|
const certificate = record(input.verdict.certificate) ?? {};
|
|
450
|
+
const scopeCheck = await sourceScopeCheck(context, input.contract, coveredBy);
|
|
309
451
|
const bindings = [];
|
|
310
452
|
for (const row of rows) {
|
|
311
453
|
const base = {
|
|
@@ -344,7 +486,8 @@ export async function judgeClaimBindings(context, input) {
|
|
|
344
486
|
});
|
|
345
487
|
continue;
|
|
346
488
|
}
|
|
347
|
-
const problem = await
|
|
489
|
+
const problem = (await scopeCheck?.(row)) ??
|
|
490
|
+
(await derivedProblem(context, input.contract, certificate, row, coveredBy));
|
|
348
491
|
const numeric = text(obligation.kind) === "numeric_constraint";
|
|
349
492
|
bindings.push(problem === null
|
|
350
493
|
? {
|
|
@@ -23,7 +23,9 @@ export declare function readWorkspaceFile(workspaceRoot: string, relative: strin
|
|
|
23
23
|
* `identifier`: the domain is read from the code, not hand-listed. A suite
|
|
24
24
|
* that tests compiled output imports the domain from the TypeScript
|
|
25
25
|
* project's `outDir`; given the workspace root, such an import counts when it
|
|
26
|
-
* maps back to the domain's source file under `rootDir`.
|
|
26
|
+
* maps back to the domain's source file under `rootDir`. A SWI-Prolog proof
|
|
27
|
+
* names the predicate and loads its file (use_module, ensure_loaded, consult
|
|
28
|
+
* or a load list), or is the plunit file beside it (`x.plt` for `x.pl`).
|
|
27
29
|
*/
|
|
28
30
|
export declare function importsDomain(source: string, sourcePath: string, targetPath: string, identifier: string, workspaceRoot?: string): boolean;
|
|
29
31
|
/**
|
|
@@ -47,6 +49,8 @@ export declare function evaluateDomain(workspaceRoot: string, sourceFile: string
|
|
|
47
49
|
runners?: readonly ("bun" | "tsx" | "node")[];
|
|
48
50
|
/** Read this field of each member instead of the member itself. */
|
|
49
51
|
field?: string;
|
|
52
|
+
/** A Prolog predicate's argument that names each member. */
|
|
53
|
+
arg?: number;
|
|
50
54
|
}>): {
|
|
51
55
|
ok: true;
|
|
52
56
|
count: number;
|
|
@@ -56,9 +60,12 @@ export declare function evaluateDomain(workspaceRoot: string, sourceFile: string
|
|
|
56
60
|
reason: string;
|
|
57
61
|
};
|
|
58
62
|
/**
|
|
59
|
-
* The number a value_source export holds, read the same way as a domain.
|
|
63
|
+
* The number a value_source export holds, read the same way as a domain. A
|
|
64
|
+
* Prolog constant is a predicate with a single solution holding a number.
|
|
60
65
|
*/
|
|
61
|
-
export declare function evaluateScalar(workspaceRoot: string, sourceFile: string, exportName: string
|
|
66
|
+
export declare function evaluateScalar(workspaceRoot: string, sourceFile: string, exportName: string, options?: Readonly<{
|
|
67
|
+
arg?: number;
|
|
68
|
+
}>): {
|
|
62
69
|
ok: true;
|
|
63
70
|
value: number;
|
|
64
71
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-certificates.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-certificates.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAKjF,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEf,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"code-certificates.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-certificates.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAKjF,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEf,MAAM,gCAAgC,CAAC;AA2BxC;;;GAGG;AAEH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,IAAI,EAAE,SAAS,CAAC;IAChB,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAYpF,wBAAsB,UAAU,CAC9B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAS3B;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iBAIxE;AAKD;;;;;;;;GAQG;AAEH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAoBT;AAqGD;;;;;GAKG;AAEH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,MAAM,GAAG,IAAI,CA2Bf;AAsFD;;;;;;;;GAQG;AAEH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,QAAQ,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,CAAC,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IAC9C,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAM,GAEL;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,GAC9D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAShC;AAED;;;GAGG;AAEH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,QAAQ,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GACvC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAM7D;AAqFD;;;GAGG;AAEH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,EACzE,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,GAAG,IAAI,CAiBf;AAwHD;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,QAAQ,CAAC;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAM,GAEzD;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA2DvD;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAiF3E,2EAA2E;AAC3E,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,KAAK,GAAG,MAAM,EACzB,GAAG,EAAE,cAAc,GAClB,MAAM,CAKR;AAED;;;;GAIG;AAEH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,GACtB,OAAO,CACN;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAC5D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAChC,CA4CA;AAmED,4EAA4E;AAE5E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAyB9C;AAuGD;;;;;GAKG;AAEH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,OAAO,GACZ,OAAO,CACR;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CACnF,CAsCA;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,MAAM,GACb,MAAM,CAOR;AAED,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;GAQG;AAEH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,QAAQ,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,GACD,OAAO,CAAC,kBAAkB,CAAC,CAoF7B"}
|
|
@@ -25,6 +25,8 @@ import { canonicalCertificateJson, certificateDigest, } from "../../public/proof
|
|
|
25
25
|
import { CODE_CERTIFICATE_VERSION, isCertificateProofKind, } from "../../public/proof-protocol.js";
|
|
26
26
|
import { describeSource, normalizeSourceSpec, readSource, } from "../../public/proof-sources.js";
|
|
27
27
|
import { runCodeEvaluator, spawnSyncThroughFiles, TS_RESOLVE_HOOKS, } from "./code-runner.js";
|
|
28
|
+
import { CODE_LANGUAGE_NAMES, codeLanguage, prologLoadSpecs, stripPrologExtension, unsupportedLanguageReason, } from "./code-languages.js";
|
|
29
|
+
import { PROLOG_EVALUATOR } from "./prolog-evaluator.js";
|
|
28
30
|
import { evaluateSourceCode } from "./source-code-readers.js";
|
|
29
31
|
import { machineCertificateProblem, patternCertificateProblem, ruleCertificateProblem, } from "./code-models.js";
|
|
30
32
|
function record(value) {
|
|
@@ -59,10 +61,14 @@ const IMPORT_SPECIFIER = /(?:\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*
|
|
|
59
61
|
* `identifier`: the domain is read from the code, not hand-listed. A suite
|
|
60
62
|
* that tests compiled output imports the domain from the TypeScript
|
|
61
63
|
* project's `outDir`; given the workspace root, such an import counts when it
|
|
62
|
-
* maps back to the domain's source file under `rootDir`.
|
|
64
|
+
* maps back to the domain's source file under `rootDir`. A SWI-Prolog proof
|
|
65
|
+
* names the predicate and loads its file (use_module, ensure_loaded, consult
|
|
66
|
+
* or a load list), or is the plunit file beside it (`x.plt` for `x.pl`).
|
|
63
67
|
*/
|
|
64
68
|
// implements REQ-kibi-code-proof-kinds
|
|
65
69
|
export function importsDomain(source, sourcePath, targetPath, identifier, workspaceRoot) {
|
|
70
|
+
if (codeLanguage(targetPath) === "prolog")
|
|
71
|
+
return prologLoadsModule(source, sourcePath, targetPath, identifier);
|
|
66
72
|
// A dotted export (BRAND.name) is imported under its head.
|
|
67
73
|
const imported = identifier.split(".")[0] ?? "";
|
|
68
74
|
if (imported === "" || !new RegExp(`\\b${escapeRegExp(imported)}\\b`).test(source))
|
|
@@ -85,6 +91,23 @@ export function importsDomain(source, sourcePath, targetPath, identifier, worksp
|
|
|
85
91
|
}
|
|
86
92
|
return false;
|
|
87
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether a SWI-Prolog proof names the predicate `identifier` (Name/Arity,
|
|
96
|
+
* optionally module-qualified) and loads the file at `targetPath`: a relative
|
|
97
|
+
* path resolved from the proof's directory, `library(X)` for a pack's
|
|
98
|
+
* `prolog/X.pl`, or the plunit convention of a `.plt` file beside its `.pl`.
|
|
99
|
+
*/
|
|
100
|
+
function prologLoadsModule(source, sourcePath, targetPath, identifier) {
|
|
101
|
+
const name = identifier.replace(/^[^:]*:/, "").replace(/\/\/?\d+$/, "");
|
|
102
|
+
if (name === "" || !new RegExp(`(?<![\\w])${escapeRegExp(name)}(?![\\w])`).test(source))
|
|
103
|
+
return false;
|
|
104
|
+
const target = stripPrologExtension(targetPath);
|
|
105
|
+
if (stripPrologExtension(sourcePath) === target && /\.plt$/i.test(sourcePath))
|
|
106
|
+
return true;
|
|
107
|
+
return prologLoadSpecs(source).some((spec) => "library" in spec
|
|
108
|
+
? `${path.sep}${target}`.endsWith(`${path.sep}prolog${path.sep}${path.normalize(spec.library)}`)
|
|
109
|
+
: stripPrologExtension(path.join(path.dirname(sourcePath), spec.path)) === target);
|
|
110
|
+
}
|
|
88
111
|
const PYTHON_FROM_IMPORT = /^\s*from\s+(\.*)([\w.]*)\s+import\b/gm;
|
|
89
112
|
const PYTHON_IMPORT = /^\s*import\s+([\w.]+(?:\s*,\s*[\w.]+)*)/gm;
|
|
90
113
|
/**
|
|
@@ -288,7 +311,7 @@ else:
|
|
|
288
311
|
*/
|
|
289
312
|
// implements REQ-kibi-code-proof-kinds
|
|
290
313
|
export function evaluateDomain(workspaceRoot, sourceFile, exportName, options = {}) {
|
|
291
|
-
const evaluated = evaluateExport(workspaceRoot, sourceFile, exportName, options);
|
|
314
|
+
const evaluated = evaluateExport(workspaceRoot, sourceFile, exportName, "domain", options);
|
|
292
315
|
if (!evaluated.ok)
|
|
293
316
|
return evaluated;
|
|
294
317
|
if (evaluated.scalar !== undefined)
|
|
@@ -299,20 +322,44 @@ export function evaluateDomain(workspaceRoot, sourceFile, exportName, options =
|
|
|
299
322
|
return { ok: true, count: evaluated.count, members: evaluated.members };
|
|
300
323
|
}
|
|
301
324
|
/**
|
|
302
|
-
* The number a value_source export holds, read the same way as a domain.
|
|
325
|
+
* The number a value_source export holds, read the same way as a domain. A
|
|
326
|
+
* Prolog constant is a predicate with a single solution holding a number.
|
|
303
327
|
*/
|
|
304
328
|
// implements REQ-kibi-claim-bound-proofs
|
|
305
|
-
export function evaluateScalar(workspaceRoot, sourceFile, exportName) {
|
|
306
|
-
const evaluated = evaluateExport(workspaceRoot, sourceFile, exportName);
|
|
329
|
+
export function evaluateScalar(workspaceRoot, sourceFile, exportName, options = {}) {
|
|
330
|
+
const evaluated = evaluateExport(workspaceRoot, sourceFile, exportName, "scalar", options);
|
|
307
331
|
if (!evaluated.ok)
|
|
308
332
|
return evaluated;
|
|
309
333
|
if (evaluated.scalar === undefined || !Number.isFinite(evaluated.scalar))
|
|
310
334
|
return { ok: false, reason: `${exportName} in ${sourceFile} is not a finite number` };
|
|
311
335
|
return { ok: true, value: evaluated.scalar };
|
|
312
336
|
}
|
|
313
|
-
function evaluateExport(workspaceRoot, sourceFile, exportName, options = {}) {
|
|
337
|
+
function evaluateExport(workspaceRoot, sourceFile, exportName, want, options = {}) {
|
|
314
338
|
const absolute = path.resolve(workspaceRoot, sourceFile);
|
|
315
|
-
const
|
|
339
|
+
const language = codeLanguage(sourceFile);
|
|
340
|
+
if (language === null)
|
|
341
|
+
return {
|
|
342
|
+
ok: false,
|
|
343
|
+
reason: unsupportedLanguageReason("Kibi's domain loader", ["js", "python", "prolog"], [sourceFile]),
|
|
344
|
+
};
|
|
345
|
+
if (language === "prolog" && options.field !== undefined)
|
|
346
|
+
return {
|
|
347
|
+
ok: false,
|
|
348
|
+
reason: `a SWI-Prolog predicate has arguments, not fields: name the argument of ${exportName} with arg instead of field`,
|
|
349
|
+
};
|
|
350
|
+
if (language !== "prolog" && options.arg !== undefined)
|
|
351
|
+
return {
|
|
352
|
+
ok: false,
|
|
353
|
+
reason: `arg applies only to a SWI-Prolog predicate, not to ${CODE_LANGUAGE_NAMES[language]} in ${sourceFile}`,
|
|
354
|
+
};
|
|
355
|
+
const ref = {
|
|
356
|
+
file: absolute,
|
|
357
|
+
export: exportName,
|
|
358
|
+
...(options.arg === undefined ? {} : { arg: options.arg }),
|
|
359
|
+
};
|
|
360
|
+
const run = runCodeEvaluator(workspaceRoot, sourceFile, { js: DOMAIN_EVALUATOR, python: PYTHON_DOMAIN_EVALUATOR, prolog: PROLOG_EVALUATOR }, language === "prolog"
|
|
361
|
+
? [JSON.stringify({ mode: "export", want, ref })]
|
|
362
|
+
: [absolute, exportName, options.field ?? ""], (parsed) => {
|
|
316
363
|
const row = parsed;
|
|
317
364
|
return (row.error !== undefined ||
|
|
318
365
|
typeof row.scalar === "number" ||
|
|
@@ -321,7 +368,7 @@ function evaluateExport(workspaceRoot, sourceFile, exportName, options = {}) {
|
|
|
321
368
|
if (!run.ok)
|
|
322
369
|
return {
|
|
323
370
|
ok: false,
|
|
324
|
-
reason: `Kibi could not load ${exportName} from ${sourceFile}${run.failure ? `: ${run.failure}` : ""}${run.python ? " (a Python domain loads with KIBI_PYTHON, the active or project virtualenv (.venv or venv), then python3 on PATH)" : " (without bun or the workspace's tsx, node's type stripping loads the domain; a type imported without import type stops it)"}`,
|
|
371
|
+
reason: `Kibi could not load ${exportName} from ${sourceFile}${run.failure ? `: ${run.failure}` : ""}${run.language === "python" ? " (a Python domain loads with KIBI_PYTHON, the active or project virtualenv (.venv or venv), then python3 on PATH)" : run.language === "prolog" ? " (a SWI-Prolog domain loads with KIBI_SWIPL, the bundled SWI-Prolog, then swipl on PATH)" : " (without bun or the workspace's tsx, node's type stripping loads the domain; a type imported without import type stops it)"}`,
|
|
325
372
|
};
|
|
326
373
|
const parsed = run.value;
|
|
327
374
|
if (parsed.error !== undefined)
|
|
@@ -606,13 +653,13 @@ export async function valueSourceValues(context, contract) {
|
|
|
606
653
|
if (source.measure === "count") {
|
|
607
654
|
// A count claim reads the collection itself, not a number kept
|
|
608
655
|
// beside it for the proof.
|
|
609
|
-
const domain = evaluateDomain(context.workspaceRoot, symbol.sourceFile, exportName);
|
|
656
|
+
const domain = evaluateDomain(context.workspaceRoot, symbol.sourceFile, exportName, source.arg === undefined ? {} : { arg: source.arg });
|
|
610
657
|
if (!domain.ok)
|
|
611
658
|
return domain;
|
|
612
659
|
values.push({ symbol_id: source.symbol_id, value: domain.count });
|
|
613
660
|
continue;
|
|
614
661
|
}
|
|
615
|
-
const evaluated = evaluateScalar(context.workspaceRoot, symbol.sourceFile, exportName);
|
|
662
|
+
const evaluated = evaluateScalar(context.workspaceRoot, symbol.sourceFile, exportName, source.arg === undefined ? {} : { arg: source.arg });
|
|
616
663
|
if (!evaluated.ok)
|
|
617
664
|
return evaluated;
|
|
618
665
|
values.push({ symbol_id: source.symbol_id, value: evaluated.value });
|
|
@@ -729,9 +776,14 @@ async function workspaceProblem(context, contract, certificate) {
|
|
|
729
776
|
if (!importing)
|
|
730
777
|
return `the proof does not import ${exportName || domainId} from ${domain.sourceFile}, so its domain may be hand-listed${contract.domain_source?.export === undefined ? ` (Kibi reads the export named by the symbol's title; set domain_source.export when the export has another name)` : ""}`;
|
|
731
778
|
if (kind === "exhaustive") {
|
|
732
|
-
const evaluated = evaluateDomain(context.workspaceRoot, domain.sourceFile, exportName,
|
|
733
|
-
|
|
734
|
-
|
|
779
|
+
const evaluated = evaluateDomain(context.workspaceRoot, domain.sourceFile, exportName, {
|
|
780
|
+
...(contract.domain_source?.field === undefined
|
|
781
|
+
? {}
|
|
782
|
+
: { field: contract.domain_source.field }),
|
|
783
|
+
...(contract.domain_source?.arg === undefined
|
|
784
|
+
? {}
|
|
785
|
+
: { arg: contract.domain_source.arg }),
|
|
786
|
+
});
|
|
735
787
|
if (!evaluated.ok)
|
|
736
788
|
return evaluated.reason;
|
|
737
789
|
const members = record(certificate.domain)?.members;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The languages Kibi reads code models in, decided by a file's extension in
|
|
3
|
+
* one place. Every proof kind that loads code (exhaustive domains, value
|
|
4
|
+
* constants, rule tables, state machines, patterns) asks this module which
|
|
5
|
+
* evaluator a file needs, so adding a language adds one entry here and its
|
|
6
|
+
* evaluator scripts, not another extension test at each call site.
|
|
7
|
+
*/
|
|
8
|
+
export type CodeLanguage = "js" | "python" | "prolog";
|
|
9
|
+
/** The language whose evaluator reads `file`, or null for any other file. */
|
|
10
|
+
export declare function codeLanguage(file: string): CodeLanguage | null;
|
|
11
|
+
export type PrologLoadSpec = {
|
|
12
|
+
library: string;
|
|
13
|
+
} | {
|
|
14
|
+
path: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The files a SWI-Prolog source loads, read from its text: use_module,
|
|
18
|
+
* ensure_loaded, consult, load_files, reexport and include with a quoted or
|
|
19
|
+
* plain path or `library(X)`, and `:- [a, b]` load lists. Nothing runs.
|
|
20
|
+
*/
|
|
21
|
+
export declare function prologLoadSpecs(source: string): PrologLoadSpec[];
|
|
22
|
+
export declare function stripPrologExtension(file: string): string;
|
|
23
|
+
/** How a reason names a language. */
|
|
24
|
+
/**
|
|
25
|
+
* Languages whose references a qualified plugin reads (kibi-plugin-treesitter
|
|
26
|
+
* through kibi.reference-extractor.v1). Kibi itself runs nothing for them.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PLUGIN_REFERENCE_LANGUAGES: readonly [{
|
|
29
|
+
readonly name: "Go";
|
|
30
|
+
readonly pattern: RegExp;
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "Java";
|
|
33
|
+
readonly pattern: RegExp;
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "C#";
|
|
36
|
+
readonly pattern: RegExp;
|
|
37
|
+
}, {
|
|
38
|
+
readonly name: "Rust";
|
|
39
|
+
readonly pattern: RegExp;
|
|
40
|
+
}];
|
|
41
|
+
/**
|
|
42
|
+
* The data-only kibi-lang-* packs kibi-plugin-treesitter reads these
|
|
43
|
+
* languages with, by the file extensions its catalog maps to them. Every
|
|
44
|
+
* grammar ships in a pack; `.pl` counts as SWI-Prolog here.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PLUGIN_LANGUAGE_PACKS: readonly [{
|
|
47
|
+
readonly pack: "kibi-lang-go";
|
|
48
|
+
readonly name: "Go";
|
|
49
|
+
readonly pattern: RegExp;
|
|
50
|
+
}, {
|
|
51
|
+
readonly pack: "kibi-lang-rust";
|
|
52
|
+
readonly name: "Rust";
|
|
53
|
+
readonly pattern: RegExp;
|
|
54
|
+
}, {
|
|
55
|
+
readonly pack: "kibi-lang-java";
|
|
56
|
+
readonly name: "Java";
|
|
57
|
+
readonly pattern: RegExp;
|
|
58
|
+
}, {
|
|
59
|
+
readonly pack: "kibi-lang-csharp";
|
|
60
|
+
readonly name: "C#";
|
|
61
|
+
readonly pattern: RegExp;
|
|
62
|
+
}, {
|
|
63
|
+
readonly pack: "kibi-lang-php";
|
|
64
|
+
readonly name: "PHP";
|
|
65
|
+
readonly pattern: RegExp;
|
|
66
|
+
}, {
|
|
67
|
+
readonly pack: "kibi-lang-c";
|
|
68
|
+
readonly name: "C";
|
|
69
|
+
readonly pattern: RegExp;
|
|
70
|
+
}, {
|
|
71
|
+
readonly pack: "kibi-lang-cpp";
|
|
72
|
+
readonly name: "C++";
|
|
73
|
+
readonly pattern: RegExp;
|
|
74
|
+
}, {
|
|
75
|
+
readonly pack: "kibi-lang-bash";
|
|
76
|
+
readonly name: "Bash";
|
|
77
|
+
readonly pattern: RegExp;
|
|
78
|
+
}, {
|
|
79
|
+
readonly pack: "kibi-lang-ruby";
|
|
80
|
+
readonly name: "Ruby";
|
|
81
|
+
readonly pattern: RegExp;
|
|
82
|
+
}, {
|
|
83
|
+
readonly pack: "kibi-lang-hcl";
|
|
84
|
+
readonly name: "Terraform/HCL";
|
|
85
|
+
readonly pattern: RegExp;
|
|
86
|
+
}, {
|
|
87
|
+
readonly pack: "kibi-lang-python";
|
|
88
|
+
readonly name: "Python";
|
|
89
|
+
readonly pattern: RegExp;
|
|
90
|
+
}, {
|
|
91
|
+
readonly pack: "kibi-lang-prolog";
|
|
92
|
+
readonly name: "SWI-Prolog";
|
|
93
|
+
readonly pattern: RegExp;
|
|
94
|
+
}];
|
|
95
|
+
export declare function pluginReferenceLanguage(file: string): string | null;
|
|
96
|
+
export declare const CODE_LANGUAGE_NAMES: Readonly<Record<CodeLanguage, string>>;
|
|
97
|
+
/** How a reason names the language of `file`. */
|
|
98
|
+
export declare function languageName(file: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* The one refusal for a file whose language a reader cannot read: what reads
|
|
101
|
+
* which languages, and the files it was handed outside them.
|
|
102
|
+
*/
|
|
103
|
+
export declare function unsupportedLanguageReason(reader: string, supported: readonly CodeLanguage[], files: readonly string[]): string;
|
|
104
|
+
//# sourceMappingURL=code-languages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-languages.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-languages.ts"],"names":[],"mappings":"AAoBA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAQtD,6EAA6E;AAE7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAK9D;AAMD,MAAM,MAAM,cAAc,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAehE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,qCAAqC;AACrC;;;GAGG;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;EAK7B,CAAC;AAEX;;;;GAIG;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAaxB,CAAC;AAEX,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAItE,CAAC;AAEF,iDAAiD;AACjD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;GAGG;AAEH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,YAAY,EAAE,EAClC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,CAOR"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
+
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
const JS_FILE = /\.(?:[cm]?[jt]sx?)$/i;
|
|
20
|
+
const PYTHON_FILE = /\.py$/i;
|
|
21
|
+
// Symbol discovery resolves an ambiguous `.pl` file by its content; one that
|
|
22
|
+
// is Perl fails to load in SWI-Prolog, so the read refuses rather than guess.
|
|
23
|
+
const PROLOG_FILE = /\.(?:pl|plt)$/i;
|
|
24
|
+
/** The language whose evaluator reads `file`, or null for any other file. */
|
|
25
|
+
// implements REQ-kibi-multilingual-code-proofs
|
|
26
|
+
export function codeLanguage(file) {
|
|
27
|
+
if (JS_FILE.test(file))
|
|
28
|
+
return "js";
|
|
29
|
+
if (PYTHON_FILE.test(file))
|
|
30
|
+
return "python";
|
|
31
|
+
if (PROLOG_FILE.test(file))
|
|
32
|
+
return "prolog";
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const PROLOG_LOAD = /\b(?:use_module|ensure_loaded|consult|load_files|reexport|include)\s*\(\s*(?:library\(\s*([^)\s]+)\s*\)|'([^']+)'|"([^"]+)"|([a-z][\w/]*))/g;
|
|
36
|
+
const PROLOG_LOAD_LIST = /:-\s*\[([^\]]+)\]/g;
|
|
37
|
+
/**
|
|
38
|
+
* The files a SWI-Prolog source loads, read from its text: use_module,
|
|
39
|
+
* ensure_loaded, consult, load_files, reexport and include with a quoted or
|
|
40
|
+
* plain path or `library(X)`, and `:- [a, b]` load lists. Nothing runs.
|
|
41
|
+
*/
|
|
42
|
+
// implements REQ-kibi-multilingual-code-proofs
|
|
43
|
+
export function prologLoadSpecs(source) {
|
|
44
|
+
const specs = [];
|
|
45
|
+
for (const match of source.matchAll(PROLOG_LOAD)) {
|
|
46
|
+
if (match[1] !== undefined)
|
|
47
|
+
specs.push({ library: match[1] });
|
|
48
|
+
else {
|
|
49
|
+
const spec = match[2] ?? match[3] ?? match[4] ?? "";
|
|
50
|
+
if (spec !== "")
|
|
51
|
+
specs.push({ path: spec });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (const match of source.matchAll(PROLOG_LOAD_LIST))
|
|
55
|
+
for (const item of (match[1] ?? "").split(",")) {
|
|
56
|
+
const spec = item.trim().replace(/^['"]|['"]$/g, "");
|
|
57
|
+
if (spec !== "")
|
|
58
|
+
specs.push({ path: spec });
|
|
59
|
+
}
|
|
60
|
+
return specs;
|
|
61
|
+
}
|
|
62
|
+
export function stripPrologExtension(file) {
|
|
63
|
+
return path.normalize(file).replace(/\.(?:pl|plt|pro)$/i, "");
|
|
64
|
+
}
|
|
65
|
+
/** How a reason names a language. */
|
|
66
|
+
/**
|
|
67
|
+
* Languages whose references a qualified plugin reads (kibi-plugin-treesitter
|
|
68
|
+
* through kibi.reference-extractor.v1). Kibi itself runs nothing for them.
|
|
69
|
+
*/
|
|
70
|
+
// implements REQ-kibi-tree-sitter-references
|
|
71
|
+
export const PLUGIN_REFERENCE_LANGUAGES = [
|
|
72
|
+
{ name: "Go", pattern: /\.go$/i },
|
|
73
|
+
{ name: "Java", pattern: /\.java$/i },
|
|
74
|
+
{ name: "C#", pattern: /\.cs$/i },
|
|
75
|
+
{ name: "Rust", pattern: /\.rs$/i },
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* The data-only kibi-lang-* packs kibi-plugin-treesitter reads these
|
|
79
|
+
* languages with, by the file extensions its catalog maps to them. Every
|
|
80
|
+
* grammar ships in a pack; `.pl` counts as SWI-Prolog here.
|
|
81
|
+
*/
|
|
82
|
+
// implements REQ-kibi-tree-sitter-language-packs
|
|
83
|
+
export const PLUGIN_LANGUAGE_PACKS = [
|
|
84
|
+
{ pack: "kibi-lang-go", name: "Go", pattern: /\.go$/i },
|
|
85
|
+
{ pack: "kibi-lang-rust", name: "Rust", pattern: /\.rs$/i },
|
|
86
|
+
{ pack: "kibi-lang-java", name: "Java", pattern: /\.java$/i },
|
|
87
|
+
{ pack: "kibi-lang-csharp", name: "C#", pattern: /\.cs$/i },
|
|
88
|
+
{ pack: "kibi-lang-php", name: "PHP", pattern: /\.php$/i },
|
|
89
|
+
{ pack: "kibi-lang-c", name: "C", pattern: /\.c$/i },
|
|
90
|
+
{ pack: "kibi-lang-cpp", name: "C++", pattern: /\.(?:cc|cpp|cxx|hh|hpp|hxx)$/i },
|
|
91
|
+
{ pack: "kibi-lang-bash", name: "Bash", pattern: /\.(?:bash|sh)$/i },
|
|
92
|
+
{ pack: "kibi-lang-ruby", name: "Ruby", pattern: /\.rb$/i },
|
|
93
|
+
{ pack: "kibi-lang-hcl", name: "Terraform/HCL", pattern: /\.(?:tf|hcl)$/i },
|
|
94
|
+
{ pack: "kibi-lang-python", name: "Python", pattern: /\.pyi?$/i },
|
|
95
|
+
{ pack: "kibi-lang-prolog", name: "SWI-Prolog", pattern: /\.(?:pl|plt)$/i },
|
|
96
|
+
];
|
|
97
|
+
export function pluginReferenceLanguage(file) {
|
|
98
|
+
return PLUGIN_REFERENCE_LANGUAGES.find((language) => language.pattern.test(file))?.name ?? null;
|
|
99
|
+
}
|
|
100
|
+
export const CODE_LANGUAGE_NAMES = {
|
|
101
|
+
js: "TypeScript or JavaScript",
|
|
102
|
+
python: "Python",
|
|
103
|
+
prolog: "SWI-Prolog",
|
|
104
|
+
};
|
|
105
|
+
/** How a reason names the language of `file`. */
|
|
106
|
+
export function languageName(file) {
|
|
107
|
+
const language = codeLanguage(file);
|
|
108
|
+
return language === null ? "an unsupported language" : CODE_LANGUAGE_NAMES[language];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The one refusal for a file whose language a reader cannot read: what reads
|
|
112
|
+
* which languages, and the files it was handed outside them.
|
|
113
|
+
*/
|
|
114
|
+
// implements REQ-kibi-multilingual-code-proofs
|
|
115
|
+
export function unsupportedLanguageReason(reader, supported, files) {
|
|
116
|
+
const names = supported.map((language) => language === "js" ? "TypeScript, JavaScript" : CODE_LANGUAGE_NAMES[language]);
|
|
117
|
+
const listed = names.length > 1 ? `${names.slice(0, -1).join(", ")} and ${names.at(-1)}` : (names[0] ?? "no");
|
|
118
|
+
return `${reader} reads ${listed} files, not ${files.slice(0, 3).join(", ")}${files.length > 3 ? ` and ${files.length - 3} more` : ""}`;
|
|
119
|
+
}
|
|
@@ -3,9 +3,11 @@ import type { ProofContract } from "../../public/proof-protocol.js";
|
|
|
3
3
|
import { type LanguageSpec } from "./regular-language.js";
|
|
4
4
|
/** The most predicate calls one rule certificate may need. */
|
|
5
5
|
export declare const MAX_TABLE_ROWS = 100000;
|
|
6
|
+
/** A code export Kibi reads; `arg` projects a Prolog predicate's solutions. */
|
|
6
7
|
export type Resolved = {
|
|
7
8
|
file: string;
|
|
8
9
|
export: string;
|
|
10
|
+
arg?: number;
|
|
9
11
|
};
|
|
10
12
|
export type TableRow = Readonly<{
|
|
11
13
|
args: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-models.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-models.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"code-models.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-models.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,uBAAuB,CAAC;AAY/B,8DAA8D;AAC9D,eAAO,MAAM,cAAc,SAAU,CAAC;AAGtC,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC/B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC,CAAC,CAAC;CAC3D,CAAC,CAAC;AAEH,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IACpD,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GACpB,QAAQ,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAA;CAAE,CAAC,GACpF,QAAQ,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAiThD;;;GAGG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA0BxD;AAED;;;GAGG;AAEH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,GACpD,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA+BzE;AAED,qEAAqE;AAErE,wBAAsB,eAAe,CACnC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B5E;AAED,4EAA4E;AAE5E,wBAAsB,eAAe,CACnC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAS5E;AA2CD;;;;GAIG;AAEH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqCxB;AAED,gFAAgF;AAEhF,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB;AAED,+EAA+E;AAE/E,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAExD;AAED;;;;;;;;GAQG;AAEH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAgDf"}
|