kibi-cli 2.32.0 → 2.35.1
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.d.ts.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/commands/check-generated.d.ts +5 -1
- package/dist/commands/check-generated.d.ts.map +1 -1
- package/dist/commands/check-generated.js +24 -35
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +8 -5
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +23 -5
- package/dist/commands/sync/manifest.d.ts +10 -1
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +87 -14
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +19 -0
- package/dist/extractors/markdown.d.ts +1 -1
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +2 -2
- package/dist/extractors/symbols-coordinator.d.ts +2 -4
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +1 -2
- package/dist/operations/migration/proof-contract-claims.d.ts +23 -10
- package/dist/operations/migration/proof-contract-claims.d.ts.map +1 -1
- package/dist/operations/migration/proof-contract-claims.js +35 -2
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +2 -4
- package/dist/operations/migration/symbol-coordinates-refresh.d.ts +3 -2
- package/dist/operations/migration/symbol-coordinates-refresh.d.ts.map +1 -1
- package/dist/operations/migration/symbol-coordinates-refresh.js +4 -3
- package/dist/operations/migration/untrack-symbol-coordinates.d.ts +23 -0
- package/dist/operations/migration/untrack-symbol-coordinates.d.ts.map +1 -0
- package/dist/operations/migration/untrack-symbol-coordinates.js +67 -0
- package/dist/operations/modeling/requirement-modeler.d.ts.map +1 -1
- package/dist/operations/modeling/requirement-modeler.js +48 -1
- package/dist/operations/modeling/requirement-types.d.ts +2 -1
- package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
- package/dist/operations/modeling/requirement-utils.d.ts +1 -1
- package/dist/operations/modeling/requirement-utils.d.ts.map +1 -1
- package/dist/operations/modeling/requirement-utils.js +8 -1
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +39 -20
- package/dist/operations/proof/claim-bindings.d.ts +18 -0
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
- package/dist/operations/proof/claim-bindings.js +157 -4
- package/dist/operations/proof/code-certificates.d.ts +34 -14
- package/dist/operations/proof/code-certificates.d.ts.map +1 -1
- package/dist/operations/proof/code-certificates.js +266 -157
- package/dist/operations/proof/code-models.d.ts +96 -0
- package/dist/operations/proof/code-models.d.ts.map +1 -0
- package/dist/operations/proof/code-models.js +601 -0
- package/dist/operations/proof/code-runner.d.ts +40 -0
- package/dist/operations/proof/code-runner.d.ts.map +1 -0
- package/dist/operations/proof/code-runner.js +164 -0
- package/dist/operations/proof/code-scope.d.ts +3 -0
- package/dist/operations/proof/code-scope.d.ts.map +1 -1
- package/dist/operations/proof/code-scope.js +26 -2
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +2 -1
- package/dist/operations/proof/regular-language.d.ts +89 -0
- package/dist/operations/proof/regular-language.d.ts.map +1 -0
- package/dist/operations/proof/regular-language.js +943 -0
- package/dist/operations/proof/source-code-readers.d.ts +12 -0
- package/dist/operations/proof/source-code-readers.d.ts.map +1 -0
- package/dist/operations/proof/source-code-readers.js +699 -0
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +2 -1
- package/dist/operations/semantic-advisor/strict-count-rules.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/strict-count-rules.js +8 -2
- package/dist/operations/semantic-advisor/strict-rules.d.ts +8 -0
- package/dist/operations/semantic-advisor/strict-rules.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/strict-rules.js +231 -1
- package/dist/operations/semantic-advisor/types.d.ts +1 -1
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +13 -3
- package/dist/public/operations/catalog.d.ts +156 -13
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/evidence-floor.js +1 -1
- package/dist/public/operations/proof-contract-claims.js +1 -1
- package/dist/public/operations/specs/composite.d.ts +16 -3
- package/dist/public/operations/specs/composite.d.ts.map +1 -1
- package/dist/public/operations/specs/modeling.d.ts +16 -3
- package/dist/public/operations/specs/modeling.d.ts.map +1 -1
- package/dist/public/operations/specs/modeling.js +22 -3
- package/dist/public/operations/specs/mutation-schemas.d.ts +140 -10
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +14 -3
- package/dist/public/operations/specs/upsert.d.ts +140 -10
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/proof-certificates.d.ts +75 -1
- package/dist/public/proof-certificates.d.ts.map +1 -1
- package/dist/public/proof-certificates.js +212 -0
- package/dist/public/proof-protocol.d.ts +143 -10
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +301 -16
- package/dist/public/proof-receipt.d.ts +4 -3
- package/dist/public/proof-receipt.d.ts.map +1 -1
- package/dist/public/proof-receipt.js +6 -1
- package/dist/public/proof-sources.d.ts +102 -0
- package/dist/public/proof-sources.d.ts.map +1 -0
- package/dist/public/proof-sources.js +1292 -0
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +21 -1
- package/dist/public/skills/kibi-commit-review/SKILL.md +8 -8
- package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +6 -6
- package/dist/public/skills/kibi-decisions/SKILL.md +5 -2
- package/dist/public/skills/kibi-decisions/resources/decision-records.md +4 -1
- package/dist/public/skills/kibi-freshness/SKILL.md +2 -2
- package/dist/public/skills/kibi-traceability/SKILL.md +3 -2
- package/dist/public/skills/kibi-usage/SKILL.md +5 -3
- package/dist/public/skills/kibi-usage/resources/proof.md +105 -9
- package/dist/report/html-report.css +45 -10
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +74 -17
- package/dist/report/report-view.d.ts +1 -1
- package/dist/report/report-view.d.ts.map +1 -1
- package/dist/report/report-view.js +1 -0
- package/dist/schemas/entity.schema.json +199 -8
- package/dist/traceability/evidence-model.d.ts +13 -12
- package/dist/traceability/evidence-model.d.ts.map +1 -1
- package/dist/traceability/evidence-model.js +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-diagnostics.js +24 -20
- package/dist/traceability/staged-impact-contract.d.ts +4 -4
- package/dist/traceability/staged-impact-contract.js +9 -9
- package/dist/traceability/staged-symbols-manifest.d.ts +11 -3
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +47 -140
- package/dist/types/entities.d.ts +1 -1
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.d.ts +1 -1
- package/dist/utils/rule-registry.generated.js +1 -1
- package/dist/utils/schema-version.d.ts +1 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/schema-version.js +3 -1
- package/dist/utils/strict-modeling.d.ts +3 -2
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +37 -4
- package/dist/workspace-cwd.d.ts +15 -0
- package/dist/workspace-cwd.d.ts.map +1 -0
- package/dist/workspace-cwd.js +86 -0
- package/package.json +2 -2
- package/schema/validation.pl +3 -1
- package/src/public/operations/evidence-floor.ts +1 -1
- package/src/public/operations/proof-contract-claims.ts +1 -1
- package/src/public/operations/specs/modeling.ts +24 -5
- package/src/public/operations/specs/mutation-schemas.ts +14 -3
- package/src/public/proof-certificates.ts +296 -1
- package/src/public/proof-protocol-types.d.ts +54 -2
- package/src/public/proof-protocol.ts +396 -20
- package/src/public/proof-receipt.ts +8 -2
- package/src/public/proof-sources.ts +1656 -0
- package/src/public/schemas/entity.ts +32 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +8 -8
- package/src/public/skills/kibi-commit-review/resources/staged-gate.md +6 -6
- package/src/public/skills/kibi-decisions/SKILL.md +5 -2
- package/src/public/skills/kibi-decisions/resources/decision-records.md +4 -1
- package/src/public/skills/kibi-freshness/SKILL.md +2 -2
- package/src/public/skills/kibi-traceability/SKILL.md +3 -2
- package/src/public/skills/kibi-usage/SKILL.md +5 -3
- package/src/public/skills/kibi-usage/resources/proof.md +105 -9
- package/src/schemas/entity.schema.json +199 -8
- package/dist/traceability/reviewed-coordinate-refresh.d.ts +0 -10
- package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +0 -1
- package/dist/traceability/reviewed-coordinate-refresh.js +0 -49
|
@@ -22,8 +22,12 @@ import { createRequire } from "node:module";
|
|
|
22
22
|
import path from "node:path";
|
|
23
23
|
import { loadEntities } from "../../public/operations/discovery-entities.js";
|
|
24
24
|
import { runOperationJsonQuery, toPrologAtom, } from "../../public/operations/prolog-json.js";
|
|
25
|
-
import { certificateDigest } from "../../public/proof-certificates.js";
|
|
25
|
+
import { canonicalCertificateJson, certificateDigest, } from "../../public/proof-certificates.js";
|
|
26
26
|
import { CODE_CERTIFICATE_VERSION, isCertificateProofKind, } from "../../public/proof-protocol.js";
|
|
27
|
+
import { describeSource, normalizeSourceSpec, readSource, } from "../../public/proof-sources.js";
|
|
28
|
+
import { runCodeEvaluator, TS_RESOLVE_HOOKS, } from "./code-runner.js";
|
|
29
|
+
import { evaluateSourceCode } from "./source-code-readers.js";
|
|
30
|
+
import { machineCertificateProblem, patternCertificateProblem, ruleCertificateProblem, } from "./code-models.js";
|
|
27
31
|
function record(value) {
|
|
28
32
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
29
33
|
? value
|
|
@@ -198,26 +202,6 @@ function stripExtension(file) {
|
|
|
198
202
|
function escapeRegExp(value) {
|
|
199
203
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
200
204
|
}
|
|
201
|
-
// Node's type stripping resolves only exact specifiers. TypeScript apps
|
|
202
|
-
// import relative modules without an extension, or with `.js` for a `.ts`
|
|
203
|
-
// file; this resolve hook retries those as the TypeScript files they name.
|
|
204
|
-
const TS_RESOLVE_HOOKS = `
|
|
205
|
-
const SUFFIXES = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
206
|
-
export async function resolve(specifier, context, next) {
|
|
207
|
-
try {
|
|
208
|
-
return await next(specifier, context);
|
|
209
|
-
} catch (error) {
|
|
210
|
-
if (error?.code !== "ERR_MODULE_NOT_FOUND" || !/^\\.\\.?\\//.test(specifier)) throw error;
|
|
211
|
-
const base = specifier.replace(/\\.[cm]?js$/, "");
|
|
212
|
-
for (const suffix of SUFFIXES) {
|
|
213
|
-
try {
|
|
214
|
-
return await next(base + suffix, context);
|
|
215
|
-
} catch {}
|
|
216
|
-
}
|
|
217
|
-
throw error;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
`;
|
|
221
205
|
const DOMAIN_EVALUATOR = `
|
|
222
206
|
const [file, name] = process.argv.slice(-2);
|
|
223
207
|
const { pathToFileURL } = await import("node:url");
|
|
@@ -274,63 +258,6 @@ elif items is None:
|
|
|
274
258
|
else:
|
|
275
259
|
print(json.dumps({"count": len(items), "members": [text(i) for i in items] if all(primitive(i) for i in items) else None}))
|
|
276
260
|
`;
|
|
277
|
-
function workspaceBin(workspaceRoot, name) {
|
|
278
|
-
let dir = path.resolve(workspaceRoot);
|
|
279
|
-
for (;;) {
|
|
280
|
-
const candidate = path.join(dir, "node_modules", ".bin", name);
|
|
281
|
-
if (existsSync(candidate))
|
|
282
|
-
return candidate;
|
|
283
|
-
if (path.dirname(dir) === dir)
|
|
284
|
-
return null;
|
|
285
|
-
dir = path.dirname(dir);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* The Python interpreters a domain loads with, most specific first: the
|
|
290
|
-
* KIBI_PYTHON override, the active virtualenv, a project virtualenv (`.venv`
|
|
291
|
-
* or `venv`) between the domain file and the workspace root, then python3
|
|
292
|
-
* and python on PATH. The system interpreter usually cannot import the
|
|
293
|
-
* project's dependencies, so a project environment comes before it.
|
|
294
|
-
*/
|
|
295
|
-
// implements REQ-kibi-code-proof-kinds
|
|
296
|
-
export function pythonDomainInterpreters(workspaceRoot, sourceFile, env = process.env) {
|
|
297
|
-
const interpreters = [];
|
|
298
|
-
const add = (candidate) => {
|
|
299
|
-
if (candidate && !interpreters.includes(candidate))
|
|
300
|
-
interpreters.push(candidate);
|
|
301
|
-
};
|
|
302
|
-
add(env.KIBI_PYTHON?.trim() || undefined);
|
|
303
|
-
const venvPython = (venv) => [
|
|
304
|
-
path.join(venv, "bin", "python"),
|
|
305
|
-
path.join(venv, "Scripts", "python.exe"),
|
|
306
|
-
].find((candidate) => existsSync(candidate));
|
|
307
|
-
if (env.VIRTUAL_ENV)
|
|
308
|
-
add(venvPython(env.VIRTUAL_ENV));
|
|
309
|
-
const root = path.resolve(workspaceRoot);
|
|
310
|
-
let dir = path.dirname(path.resolve(root, sourceFile));
|
|
311
|
-
for (;;) {
|
|
312
|
-
for (const name of [".venv", "venv"])
|
|
313
|
-
add(venvPython(path.join(dir, name)));
|
|
314
|
-
if (dir === root || path.dirname(dir) === dir)
|
|
315
|
-
break;
|
|
316
|
-
if (!dir.startsWith(`${root}${path.sep}`))
|
|
317
|
-
break;
|
|
318
|
-
dir = path.dirname(dir);
|
|
319
|
-
}
|
|
320
|
-
add("python3");
|
|
321
|
-
add("python");
|
|
322
|
-
return interpreters;
|
|
323
|
-
}
|
|
324
|
-
/** The line of a runner's stderr that names the failure. */
|
|
325
|
-
function failureLine(stderr, python) {
|
|
326
|
-
const lines = stderr
|
|
327
|
-
.trim()
|
|
328
|
-
.split("\n")
|
|
329
|
-
.map((line) => line.trim())
|
|
330
|
-
.filter((line) => line !== "");
|
|
331
|
-
// A Python traceback names the exception on its last line.
|
|
332
|
-
return (python ? lines.at(-1) : lines[0]) ?? "";
|
|
333
|
-
}
|
|
334
261
|
/**
|
|
335
262
|
* The domain as the code defines it: Kibi imports the domain_source file
|
|
336
263
|
* itself and reads the named export's members, so a certificate cannot cover
|
|
@@ -366,60 +293,26 @@ export function evaluateScalar(workspaceRoot, sourceFile, exportName) {
|
|
|
366
293
|
}
|
|
367
294
|
function evaluateExport(workspaceRoot, sourceFile, exportName, options = {}) {
|
|
368
295
|
const absolute = path.resolve(workspaceRoot, sourceFile);
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
process.execPath,
|
|
386
|
-
[
|
|
387
|
-
"--experimental-strip-types",
|
|
388
|
-
"--no-warnings",
|
|
389
|
-
"--input-type=module",
|
|
390
|
-
"-e",
|
|
391
|
-
DOMAIN_EVALUATOR,
|
|
392
|
-
],
|
|
393
|
-
],
|
|
394
|
-
];
|
|
395
|
-
});
|
|
396
|
-
let failure = "";
|
|
397
|
-
for (const [command, argv] of runners) {
|
|
398
|
-
const run = spawnSync(command, [...argv, absolute, exportName], {
|
|
399
|
-
cwd: workspaceRoot,
|
|
400
|
-
encoding: "utf8",
|
|
401
|
-
timeout: 60_000,
|
|
402
|
-
});
|
|
403
|
-
if (run.error)
|
|
404
|
-
continue;
|
|
405
|
-
const line = (run.stdout ?? "").trim().split("\n").pop() ?? "";
|
|
406
|
-
try {
|
|
407
|
-
const parsed = JSON.parse(line);
|
|
408
|
-
if (parsed.error !== undefined)
|
|
409
|
-
return { ok: false, reason: parsed.error };
|
|
410
|
-
if (typeof parsed.scalar === "number")
|
|
411
|
-
return { ok: true, count: 0, members: null, scalar: parsed.scalar };
|
|
412
|
-
if (typeof parsed.count === "number")
|
|
413
|
-
return { ok: true, count: parsed.count, members: parsed.members ?? null };
|
|
414
|
-
}
|
|
415
|
-
catch {
|
|
416
|
-
// Fall through to the next runner.
|
|
417
|
-
}
|
|
418
|
-
failure = failureLine(run.stderr ?? "", python);
|
|
419
|
-
}
|
|
296
|
+
const run = runCodeEvaluator(workspaceRoot, sourceFile, { js: DOMAIN_EVALUATOR, python: PYTHON_DOMAIN_EVALUATOR }, [absolute, exportName], (parsed) => {
|
|
297
|
+
const row = parsed;
|
|
298
|
+
return (row.error !== undefined ||
|
|
299
|
+
typeof row.scalar === "number" ||
|
|
300
|
+
typeof row.count === "number");
|
|
301
|
+
}, options);
|
|
302
|
+
if (!run.ok)
|
|
303
|
+
return {
|
|
304
|
+
ok: false,
|
|
305
|
+
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)"}`,
|
|
306
|
+
};
|
|
307
|
+
const parsed = run.value;
|
|
308
|
+
if (parsed.error !== undefined)
|
|
309
|
+
return { ok: false, reason: parsed.error };
|
|
310
|
+
if (typeof parsed.scalar === "number")
|
|
311
|
+
return { ok: true, count: 0, members: null, scalar: parsed.scalar };
|
|
420
312
|
return {
|
|
421
|
-
ok:
|
|
422
|
-
|
|
313
|
+
ok: true,
|
|
314
|
+
count: parsed.count,
|
|
315
|
+
members: parsed.members ?? null,
|
|
423
316
|
};
|
|
424
317
|
}
|
|
425
318
|
/**
|
|
@@ -447,37 +340,135 @@ export function domainCoverageProblem(exportName, evaluated, certified) {
|
|
|
447
340
|
: `the certificate covers ${certified.length} members but ${exportName} has ${evaluated.count}`;
|
|
448
341
|
}
|
|
449
342
|
/**
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
343
|
+
* The TypeScript compiler API for a witness: the package nearest the witness
|
|
344
|
+
* first, then the workspace root. TypeScript 7 ships without the JS compiler
|
|
345
|
+
* API, so a 7.x install is skipped for an older one further up, and named in
|
|
346
|
+
* the reason when none is left.
|
|
453
347
|
*/
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
348
|
+
function loadTypeScript(workspaceRoot, absoluteWitness) {
|
|
349
|
+
const noApi = [];
|
|
350
|
+
const bases = [
|
|
351
|
+
path.join(path.dirname(absoluteWitness), "noop.js"),
|
|
352
|
+
path.join(workspaceRoot, "package.json"),
|
|
353
|
+
];
|
|
354
|
+
for (const base of bases) {
|
|
355
|
+
let loaded;
|
|
356
|
+
try {
|
|
357
|
+
loaded = createRequire(base)("typescript");
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (typeof loaded.createProgram === "function")
|
|
363
|
+
return { ok: true, ts: loaded };
|
|
364
|
+
noApi.push(String(loaded.version ?? "unknown"));
|
|
465
365
|
}
|
|
366
|
+
return {
|
|
367
|
+
ok: false,
|
|
368
|
+
reason: noApi.length > 0
|
|
369
|
+
? `the workspace's TypeScript ${noApi[0]} has no compiler API to compile the witness (TypeScript 7 ships without it); add typescript@6 as a dev dependency for typecheck proofs`
|
|
370
|
+
: "Kibi could not load TypeScript from the workspace to compile the witness (install typescript)",
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/** Options that decide how the witness's imports resolve, from the nearest tsconfig. */
|
|
374
|
+
const RESOLUTION_OPTIONS = [
|
|
375
|
+
"module",
|
|
376
|
+
"moduleResolution",
|
|
377
|
+
"baseUrl",
|
|
378
|
+
"paths",
|
|
379
|
+
"rootDirs",
|
|
380
|
+
"customConditions",
|
|
381
|
+
"resolvePackageJsonExports",
|
|
382
|
+
"resolvePackageJsonImports",
|
|
383
|
+
"allowImportingTsExtensions",
|
|
384
|
+
"resolveJsonModule",
|
|
385
|
+
"jsx",
|
|
386
|
+
"jsxImportSource",
|
|
387
|
+
"lib",
|
|
388
|
+
"target",
|
|
389
|
+
"esModuleInterop",
|
|
390
|
+
"allowSyntheticDefaultImports",
|
|
391
|
+
"verbatimModuleSyntax",
|
|
392
|
+
];
|
|
393
|
+
/**
|
|
394
|
+
* The nearest tsconfig's resolution options, and the declaration files it
|
|
395
|
+
* includes: global typings such as a `reset.d.ts` that the project's types
|
|
396
|
+
* rely on, which a witness importing those types needs too.
|
|
397
|
+
*/
|
|
398
|
+
function projectCompileSettings(ts, workspaceRoot, absoluteWitness) {
|
|
399
|
+
const none = { options: {}, declarations: [] };
|
|
400
|
+
const configPath = ts.findConfigFile(path.dirname(absoluteWitness), ts.sys.fileExists, "tsconfig.json");
|
|
401
|
+
if (configPath === undefined ||
|
|
402
|
+
path.relative(workspaceRoot, configPath).startsWith(".."))
|
|
403
|
+
return none;
|
|
404
|
+
const read = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
405
|
+
if (read.error !== undefined)
|
|
406
|
+
return none;
|
|
407
|
+
const parsed = ts.parseJsonConfigFileContent(read.config, ts.sys, path.dirname(configPath), undefined, configPath);
|
|
408
|
+
const options = {};
|
|
409
|
+
for (const key of RESOLUTION_OPTIONS)
|
|
410
|
+
if (parsed.options[key] !== undefined)
|
|
411
|
+
options[key] = parsed.options[key];
|
|
412
|
+
return {
|
|
413
|
+
options: options,
|
|
414
|
+
declarations: parsed.fileNames.filter((file) => file.endsWith(".d.ts")),
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Whether a witness can stop compiling when a domain member goes unhandled:
|
|
419
|
+
* it uses the never type (a switch ending in a never assignment) or a
|
|
420
|
+
* satisfies expression (a map over the domain). Read from the syntax tree,
|
|
421
|
+
* so the word never in a comment or a string does not count.
|
|
422
|
+
*/
|
|
423
|
+
function hasExhaustivenessCheck(ts, witness) {
|
|
424
|
+
const visit = (node) => node.kind === ts.SyntaxKind.NeverKeyword ||
|
|
425
|
+
node.kind === ts.SyntaxKind.SatisfiesExpression ||
|
|
426
|
+
(ts.forEachChild(node, (child) => (visit(child) ? true : undefined)) ??
|
|
427
|
+
false);
|
|
428
|
+
return visit(witness);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Kibi compiles a typecheck witness itself, with the workspace's TypeScript.
|
|
432
|
+
* Imports resolve the way the project's own tsconfig says (module,
|
|
433
|
+
* moduleResolution, paths, ...) and its declaration files are in the
|
|
434
|
+
* program, but the checking options stay fixed and
|
|
435
|
+
* strict, so a lax project tsconfig cannot make the never check vacuous. It
|
|
436
|
+
* accepts the witness only with no errors in it.
|
|
437
|
+
*/
|
|
438
|
+
// implements REQ-kibi-code-proof-kinds
|
|
439
|
+
export function compileWitness(workspaceRoot, witnessPath, options = {}) {
|
|
466
440
|
const absolute = path.resolve(workspaceRoot, witnessPath);
|
|
467
|
-
const
|
|
441
|
+
const loaded = loadTypeScript(workspaceRoot, absolute);
|
|
442
|
+
if (!loaded.ok)
|
|
443
|
+
return loaded;
|
|
444
|
+
const { ts } = loaded;
|
|
445
|
+
const { options: project, declarations } = projectCompileSettings(ts, workspaceRoot, absolute);
|
|
446
|
+
// module and moduleResolution must agree, so take both or neither.
|
|
447
|
+
const moduleOptions = project.module !== undefined || project.moduleResolution !== undefined
|
|
448
|
+
? {}
|
|
449
|
+
: {
|
|
450
|
+
module: ts.ModuleKind.NodeNext,
|
|
451
|
+
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
452
|
+
};
|
|
453
|
+
const program = ts.createProgram([absolute, ...declarations], {
|
|
454
|
+
target: ts.ScriptTarget.ES2022,
|
|
455
|
+
...moduleOptions,
|
|
456
|
+
...project,
|
|
468
457
|
strict: true,
|
|
469
458
|
noEmit: true,
|
|
470
459
|
skipLibCheck: true,
|
|
471
460
|
allowJs: true,
|
|
472
461
|
checkJs: true,
|
|
473
|
-
target: ts.ScriptTarget.ES2022,
|
|
474
|
-
module: ts.ModuleKind.NodeNext,
|
|
475
|
-
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
476
462
|
types: [],
|
|
477
463
|
});
|
|
478
464
|
const witness = program.getSourceFile(absolute);
|
|
479
465
|
if (witness === undefined)
|
|
480
466
|
return { ok: false, reason: `Kibi could not read the witness ${witnessPath}` };
|
|
467
|
+
if (options.requireExhaustiveness === true && !hasExhaustivenessCheck(ts, witness))
|
|
468
|
+
return {
|
|
469
|
+
ok: false,
|
|
470
|
+
reason: `the witness ${witnessPath} has no exhaustiveness check (a never type or a satisfies map), so a new domain member would still compile`,
|
|
471
|
+
};
|
|
481
472
|
const errors = [
|
|
482
473
|
...program.getSyntacticDiagnostics(witness),
|
|
483
474
|
...program.getSemanticDiagnostics(witness),
|
|
@@ -486,6 +477,13 @@ export function compileWitness(workspaceRoot, witnessPath) {
|
|
|
486
477
|
return {
|
|
487
478
|
ok: false,
|
|
488
479
|
reason: `TypeScript ${ts.version} rejects the witness ${witnessPath}: ${ts.flattenDiagnosticMessageText(errors[0]?.messageText ?? "", " ")}`,
|
|
480
|
+
// Zero-based witness lines with an error, so a generated witness can
|
|
481
|
+
// say which of its checks failed.
|
|
482
|
+
errorLines: [
|
|
483
|
+
...new Set(errors
|
|
484
|
+
.filter((error) => error.file === witness && error.start !== undefined)
|
|
485
|
+
.map((error) => witness.getLineAndCharacterOfPosition(error.start ?? 0).line)),
|
|
486
|
+
],
|
|
489
487
|
};
|
|
490
488
|
return { ok: true, version: ts.version };
|
|
491
489
|
}
|
|
@@ -561,19 +559,41 @@ export function smtAssertion(property, valueType, row) {
|
|
|
561
559
|
}
|
|
562
560
|
/**
|
|
563
561
|
* The values a contract's value_source exports hold, read from the code the
|
|
564
|
-
* same way as a domain
|
|
562
|
+
* same way as a domain (a count measure is the collection's size), or why
|
|
563
|
+
* one cannot be read.
|
|
565
564
|
*/
|
|
566
565
|
// implements REQ-kibi-claim-bound-proofs
|
|
567
566
|
export async function valueSourceValues(context, contract) {
|
|
568
567
|
const values = [];
|
|
569
568
|
for (const source of contract.value_source ?? []) {
|
|
569
|
+
if ("source" in source) {
|
|
570
|
+
// A source count reads the members Kibi reads from the project.
|
|
571
|
+
const read = await readSource(context.workspaceRoot, source.source, evaluateSourceCode);
|
|
572
|
+
if (!read.ok)
|
|
573
|
+
return {
|
|
574
|
+
ok: false,
|
|
575
|
+
reason: `Kibi could not read the value_source ${describeSource(source.source)}: ${read.reason}`,
|
|
576
|
+
};
|
|
577
|
+
values.push({ symbol_id: describeSource(source.source), value: read.model.members.length });
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
570
580
|
const symbol = await loadSymbol(context, source.symbol_id);
|
|
571
581
|
if (!symbol || symbol.sourceFile === "")
|
|
572
582
|
return {
|
|
573
583
|
ok: false,
|
|
574
584
|
reason: `the value_source symbol ${source.symbol_id} has no source file`,
|
|
575
585
|
};
|
|
576
|
-
const
|
|
586
|
+
const exportName = source.export ?? symbol.title;
|
|
587
|
+
if (source.measure === "count") {
|
|
588
|
+
// A count claim reads the collection itself, not a number kept
|
|
589
|
+
// beside it for the proof.
|
|
590
|
+
const domain = evaluateDomain(context.workspaceRoot, symbol.sourceFile, exportName);
|
|
591
|
+
if (!domain.ok)
|
|
592
|
+
return domain;
|
|
593
|
+
values.push({ symbol_id: source.symbol_id, value: domain.count });
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
const evaluated = evaluateScalar(context.workspaceRoot, symbol.sourceFile, exportName);
|
|
577
597
|
if (!evaluated.ok)
|
|
578
598
|
return evaluated;
|
|
579
599
|
values.push({ symbol_id: source.symbol_id, value: evaluated.value });
|
|
@@ -710,9 +730,13 @@ async function workspaceProblem(context, contract, certificate) {
|
|
|
710
730
|
const sha = createHash("sha256").update(content).digest("hex");
|
|
711
731
|
if (text(witness?.sha256) !== sha)
|
|
712
732
|
return `the witness sha256 does not match ${witnessPath} in the workspace`;
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
733
|
+
// With proves, Kibi decides each claim with its own witness (set
|
|
734
|
+
// equality, required fields), so the author's witness only has to
|
|
735
|
+
// compile. Without proves, the receipt's proved rests on this witness
|
|
736
|
+
// alone, so it must be able to fail when a domain member goes unhandled.
|
|
737
|
+
const compiled = compileWitness(context.workspaceRoot, witnessPath, {
|
|
738
|
+
requireExhaustiveness: (contract.proves ?? []).length === 0,
|
|
739
|
+
});
|
|
716
740
|
if (!compiled.ok)
|
|
717
741
|
return compiled.reason;
|
|
718
742
|
}
|
|
@@ -728,22 +752,107 @@ async function workspaceProblem(context, contract, certificate) {
|
|
|
728
752
|
if (!rerun.ok)
|
|
729
753
|
return rerun.reason;
|
|
730
754
|
}
|
|
755
|
+
if (kind === "rule")
|
|
756
|
+
return ruleCertificateProblem(context, contract, certificate);
|
|
757
|
+
if (kind === "state_machine")
|
|
758
|
+
return machineCertificateProblem(context, contract, certificate);
|
|
759
|
+
if (kind === "regex")
|
|
760
|
+
return patternCertificateProblem(context, contract, certificate);
|
|
731
761
|
return null;
|
|
732
762
|
}
|
|
763
|
+
/**
|
|
764
|
+
* The certificate of a source proof: the contract's source and what Kibi
|
|
765
|
+
* reads from it. A certificate the run left must name the same source, and
|
|
766
|
+
* a model it carries must be what Kibi reads; either way the stored model is
|
|
767
|
+
* Kibi's own read, so the proof never rests on members the test listed.
|
|
768
|
+
*/
|
|
769
|
+
// implements REQ-kibi-source-proof-kinds
|
|
770
|
+
export async function completeSourceCertificate(context, testId, contract, left) {
|
|
771
|
+
const spec = contract.source;
|
|
772
|
+
if (spec === undefined)
|
|
773
|
+
return { ok: false, reason: "the source contract names no source" };
|
|
774
|
+
const row = record(left);
|
|
775
|
+
if (left !== undefined && left !== null && row === null)
|
|
776
|
+
return { ok: false, reason: "the run left a source certificate that is not a JSON object" };
|
|
777
|
+
if (row !== null) {
|
|
778
|
+
if (text(row.kind) !== "source")
|
|
779
|
+
return { ok: false, reason: `the certificate kind ${text(row.kind) || "(none)"} is not the contract kind source` };
|
|
780
|
+
if (text(row.test_id) !== testId)
|
|
781
|
+
return { ok: false, reason: `the certificate is for ${text(row.test_id)}` };
|
|
782
|
+
if (row.source !== undefined &&
|
|
783
|
+
canonicalCertificateJson(normalizeSourceSpec(row.source) ?? row.source) !==
|
|
784
|
+
canonicalCertificateJson(spec))
|
|
785
|
+
return { ok: false, reason: `the certificate reads ${JSON.stringify(row.source)}, not the contract's source` };
|
|
786
|
+
}
|
|
787
|
+
const read = await readSource(context.workspaceRoot, spec, evaluateSourceCode);
|
|
788
|
+
if (!read.ok)
|
|
789
|
+
return { ok: false, reason: `Kibi could not read ${describeSource(spec)}: ${read.reason}` };
|
|
790
|
+
const model = read.model;
|
|
791
|
+
if (row?.model !== undefined && canonicalCertificateJson(row.model) !== canonicalCertificateJson(model))
|
|
792
|
+
return {
|
|
793
|
+
ok: false,
|
|
794
|
+
reason: `the certificate's model is not what Kibi reads from ${describeSource(spec)} (${model.members.slice(0, 8).join(", ") || "no members"})`,
|
|
795
|
+
};
|
|
796
|
+
return {
|
|
797
|
+
ok: true,
|
|
798
|
+
certificate: {
|
|
799
|
+
version: CODE_CERTIFICATE_VERSION,
|
|
800
|
+
kind: "source",
|
|
801
|
+
test_id: testId,
|
|
802
|
+
source: spec,
|
|
803
|
+
model,
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
const WITNESS_NOT_ACCEPTED = "the type checker did not accept the witness";
|
|
808
|
+
/**
|
|
809
|
+
* A typecheck certificate whose own outcome is failed says only that: add
|
|
810
|
+
* what Kibi's compile of the same witness reports, so the author sees the
|
|
811
|
+
* first error, or learns that the test compiled it differently.
|
|
812
|
+
*/
|
|
813
|
+
export function withWitnessDiagnosis(context, contract, reason) {
|
|
814
|
+
const witnessPath = contract.witness?.path ?? "";
|
|
815
|
+
if (reason !== WITNESS_NOT_ACCEPTED || witnessPath === "")
|
|
816
|
+
return reason;
|
|
817
|
+
const compiled = compileWitness(context.workspaceRoot, witnessPath);
|
|
818
|
+
return compiled.ok
|
|
819
|
+
? `${reason}, though Kibi's own compile of ${witnessPath} with TypeScript ${compiled.version} accepts it (the test compiled it with other settings)`
|
|
820
|
+
: `${reason}: ${compiled.reason}`;
|
|
821
|
+
}
|
|
822
|
+
export { pythonDomainInterpreters, runCodeEvaluator, TS_RESOLVE_HOOKS, } from "./code-runner.js";
|
|
733
823
|
/**
|
|
734
824
|
* Re-check the certificate a certificate-kind run left for one test. A
|
|
735
825
|
* runner kind (e2e, example, property) supports tested evidence and needs
|
|
736
826
|
* no certificate; a certificate kind supports proved evidence only when the
|
|
737
827
|
* certificate re-checks: its structure and arithmetic in code_certificates.pl,
|
|
738
828
|
* and here that the proof read its domain from the code, that the witness is
|
|
739
|
-
* the workspace file,
|
|
829
|
+
* the workspace file, that the solver still answers unsat, and that a rule
|
|
830
|
+
* table, state machine or pattern is what Kibi itself reads from the code.
|
|
740
831
|
*/
|
|
741
832
|
// implements REQ-kibi-code-proof-kinds
|
|
742
833
|
export async function checkCodeCertificate(context, input) {
|
|
743
834
|
const kind = input.contract.kind ?? "e2e";
|
|
744
835
|
if (!isCertificateProofKind(kind))
|
|
745
836
|
return { kind, evidence_level: "tested" };
|
|
746
|
-
|
|
837
|
+
let left = input.certificate;
|
|
838
|
+
if (kind === "source" && input.outcome === "passed") {
|
|
839
|
+
// Kibi reads the source itself, so the certificate it stores is its own
|
|
840
|
+
// read, whatever the run left (or nothing).
|
|
841
|
+
const completed = await completeSourceCertificate(context, input.testId, input.contract, input.certificate);
|
|
842
|
+
if (!completed.ok) {
|
|
843
|
+
const leftRecord = record(left);
|
|
844
|
+
return {
|
|
845
|
+
kind,
|
|
846
|
+
evidence_level: "tested",
|
|
847
|
+
...(leftRecord
|
|
848
|
+
? { certificate: leftRecord, certificate_digest: certificateDigest(leftRecord) }
|
|
849
|
+
: {}),
|
|
850
|
+
certificate_rejection: completed.reason,
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
left = completed.certificate;
|
|
854
|
+
}
|
|
855
|
+
const certificate = record(left);
|
|
747
856
|
if (!certificate)
|
|
748
857
|
return {
|
|
749
858
|
kind,
|
|
@@ -768,7 +877,7 @@ export async function checkCodeCertificate(context, input) {
|
|
|
768
877
|
return rejected("no Prolog runtime is attached to re-check the certificate");
|
|
769
878
|
const checked = await runOperationJsonQuery(context.prolog, "code_certificates.pl", `code_certificates:code_certificate_check_json(${toPrologAtom(JSON.stringify(certificate))}, JsonString)`, "Code certificate check");
|
|
770
879
|
if (checked.accepted !== true)
|
|
771
|
-
return rejected(checked.reason ?? "the certificate did not re-check");
|
|
880
|
+
return rejected(withWitnessDiagnosis(context, input.contract, checked.reason ?? "the certificate did not re-check"));
|
|
772
881
|
// Every later re-check hashes the stored certificate in Prolog, so a
|
|
773
882
|
// certificate whose two canonical forms differ would silently lose proved.
|
|
774
883
|
if (checked.digest !== digest)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { OperationContext } from "../../public/operations/runtime-types.js";
|
|
2
|
+
import type { ProofContract } from "../../public/proof-protocol.js";
|
|
3
|
+
import { type LanguageSpec } from "./regular-language.js";
|
|
4
|
+
/** The most predicate calls one rule certificate may need. */
|
|
5
|
+
export declare const MAX_TABLE_ROWS = 100000;
|
|
6
|
+
export type Resolved = {
|
|
7
|
+
file: string;
|
|
8
|
+
export: string;
|
|
9
|
+
};
|
|
10
|
+
export type TableRow = Readonly<{
|
|
11
|
+
args: readonly string[];
|
|
12
|
+
value?: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** What Kibi read for a rule certificate: domains and predicate tables. */
|
|
16
|
+
export type RuleModel = Readonly<{
|
|
17
|
+
domains: Readonly<Record<string, readonly string[]>>;
|
|
18
|
+
predicates: Readonly<Record<string, readonly TableRow[]>>;
|
|
19
|
+
}>;
|
|
20
|
+
/** What Kibi read for a state_machine certificate. */
|
|
21
|
+
export type MachineModel = Readonly<{
|
|
22
|
+
states: readonly string[];
|
|
23
|
+
transitions: readonly (readonly [string, string])[];
|
|
24
|
+
initial?: readonly string[];
|
|
25
|
+
}>;
|
|
26
|
+
/** What Kibi read for a regex certificate. */
|
|
27
|
+
export type PatternModel = Readonly<{
|
|
28
|
+
type: "regexp";
|
|
29
|
+
source: string;
|
|
30
|
+
flags: string;
|
|
31
|
+
flavor: "js" | "python";
|
|
32
|
+
}> | Readonly<{
|
|
33
|
+
type: "string";
|
|
34
|
+
value: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Run one evaluation plan (table, machine or pattern mode) against the code
|
|
38
|
+
* files it names, in the language of those files.
|
|
39
|
+
*/
|
|
40
|
+
export declare function evaluateCodeModel<T>(workspaceRoot: string, files: readonly Resolved[], plan: Record<string, unknown>): {
|
|
41
|
+
ok: true;
|
|
42
|
+
model: T;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
reason: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Evaluate every predicate a rule contract names over every combination of
|
|
49
|
+
* its argument domains, with the argument types the certificate declares.
|
|
50
|
+
*/
|
|
51
|
+
export declare function evaluateRuleModel(context: OperationContext, contract: ProofContract, argTypes: Readonly<Record<string, readonly string[]>>): Promise<{
|
|
52
|
+
ok: true;
|
|
53
|
+
model: RuleModel;
|
|
54
|
+
} | {
|
|
55
|
+
ok: false;
|
|
56
|
+
reason: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** Read a state machine's states, transitions and initial states. */
|
|
59
|
+
export declare function evaluateMachine(context: OperationContext, contract: ProofContract): Promise<{
|
|
60
|
+
ok: true;
|
|
61
|
+
model: MachineModel;
|
|
62
|
+
} | {
|
|
63
|
+
ok: false;
|
|
64
|
+
reason: string;
|
|
65
|
+
}>;
|
|
66
|
+
/** Read the pattern or string a regex contract's pattern_source exports. */
|
|
67
|
+
export declare function evaluatePattern(context: OperationContext, contract: ProofContract): Promise<{
|
|
68
|
+
ok: true;
|
|
69
|
+
model: PatternModel;
|
|
70
|
+
} | {
|
|
71
|
+
ok: false;
|
|
72
|
+
reason: string;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* A rule certificate re-checks only when its domains and every predicate
|
|
76
|
+
* table are what Kibi reads from the code: the same values, and the same
|
|
77
|
+
* decision for every combination of arguments.
|
|
78
|
+
*/
|
|
79
|
+
export declare function ruleCertificateProblem(context: OperationContext, contract: ProofContract, certificate: Record<string, unknown>): Promise<string | null>;
|
|
80
|
+
/** A state_machine certificate re-checks only when it is the code's machine. */
|
|
81
|
+
export declare function machineCertificateProblem(context: OperationContext, contract: ProofContract, certificate: Record<string, unknown>): Promise<string | null>;
|
|
82
|
+
/** A regex certificate re-checks only when it holds the code's own pattern. */
|
|
83
|
+
export declare function patternCertificateProblem(context: OperationContext, contract: ProofContract, certificate: Record<string, unknown>): Promise<string | null>;
|
|
84
|
+
/** The fact's pattern: a JavaScript pattern with the u flag, matched whole. */
|
|
85
|
+
export declare function factPattern(source: string): LanguageSpec;
|
|
86
|
+
/**
|
|
87
|
+
* Whether the code's string or pattern meets a string fact's constraint,
|
|
88
|
+
* decided exactly. For a string constant: eq and neq compare it, matches
|
|
89
|
+
* tests it against the fact's pattern. For a pattern (the strings a
|
|
90
|
+
* validator accepts): eq means it accepts exactly that string, neq that it
|
|
91
|
+
* rejects it, matches that it accepts exactly the strings the fact's pattern
|
|
92
|
+
* describes. Polarity forbid negates the constraint; for a pattern, a
|
|
93
|
+
* forbidden match means no string matches both.
|
|
94
|
+
*/
|
|
95
|
+
export declare function stringConstraintProblem(certificate: Record<string, unknown>, obligation: Readonly<Record<string, unknown>>, factId: string): string | null;
|
|
96
|
+
//# sourceMappingURL=code-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-models.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-models.ts"],"names":[],"mappings":"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"}
|