kibi-cli 2.31.0 → 2.32.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-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +19 -7
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +2 -0
- package/dist/commands/check.d.ts +1 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +14 -5
- package/dist/commands/discovery-table.d.ts.map +1 -1
- package/dist/commands/discovery-table.js +51 -4
- package/dist/commands/doctor.js +19 -4
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +89 -3
- package/dist/commands/prove.d.ts +48 -1
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +293 -8
- package/dist/commands/report.d.ts +1 -0
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +70 -5
- package/dist/commands/signoff.d.ts.map +1 -1
- package/dist/commands/signoff.js +21 -2
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +20 -4
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +16 -5
- package/dist/diagnostics.js +1 -1
- package/dist/engine.js +1 -1
- package/dist/extractors/markdown.d.ts +3 -1
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +17 -0
- package/dist/operations/bootstrap/candidate-helpers.d.ts +3 -0
- package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidate-helpers.js +4 -0
- package/dist/operations/migration/evidence-floor.d.ts +41 -0
- package/dist/operations/migration/evidence-floor.d.ts.map +1 -0
- package/dist/operations/migration/evidence-floor.js +230 -0
- package/dist/operations/migration/proof-contract-claims.d.ts +59 -0
- package/dist/operations/migration/proof-contract-claims.d.ts.map +1 -0
- package/dist/operations/migration/proof-contract-claims.js +182 -0
- package/dist/operations/migration/schema6.d.ts +6 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +94 -0
- package/dist/operations/mutation/omitted-properties.d.ts +11 -0
- package/dist/operations/mutation/omitted-properties.d.ts.map +1 -0
- package/dist/operations/mutation/omitted-properties.js +76 -0
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +1 -0
- package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
- package/dist/operations/mutation/strict-fact.js +6 -2
- package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-granularity.js +5 -3
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +7 -1
- package/dist/operations/mutation/validation.d.ts +2 -0
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +4 -0
- package/dist/operations/proof/claim-bindings.d.ts +23 -0
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -0
- package/dist/operations/proof/claim-bindings.js +211 -0
- package/dist/operations/proof/code-certificates.d.ts +135 -0
- package/dist/operations/proof/code-certificates.d.ts.map +1 -0
- package/dist/operations/proof/code-certificates.js +785 -0
- package/dist/operations/proof/code-scope.d.ts +11 -1
- package/dist/operations/proof/code-scope.d.ts.map +1 -1
- package/dist/operations/proof/code-scope.js +20 -2
- package/dist/operations/proof/compact-receipts.d.ts.map +1 -1
- package/dist/operations/proof/compact-receipts.js +4 -3
- package/dist/operations/proof/explain.d.ts +32 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +91 -0
- package/dist/operations/proof/ingest-proof.d.ts +9 -1
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +41 -2
- package/dist/operations/proof/receipt-compaction.d.ts +2 -0
- package/dist/operations/proof/receipt-compaction.d.ts.map +1 -1
- package/dist/operations/proof/receipt-compaction.js +6 -2
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +4 -0
- package/dist/operations/semantic-advisor/strict-rules.js +3 -3
- package/dist/operations/semantic-advisor/types.d.ts +2 -1
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +6 -6
- package/dist/plugins/approved-source-analyzers.generated.js +6 -6
- package/dist/proof/command-test-report.d.ts +4 -3
- package/dist/proof/command-test-report.d.ts.map +1 -1
- package/dist/proof/command-test-report.js +4 -10
- package/dist/proof/evaluate.d.ts.map +1 -1
- package/dist/proof/evaluate.js +18 -2
- package/dist/proof/inspect.d.ts.map +1 -1
- package/dist/proof/inspect.js +58 -0
- package/dist/proof/producers/playwright-reporter.d.ts +3 -0
- package/dist/proof/producers/playwright-reporter.d.ts.map +1 -1
- package/dist/proof/producers/playwright-reporter.js +25 -2
- package/dist/proof/step-runner.d.ts +36 -0
- package/dist/proof/step-runner.d.ts.map +1 -0
- package/dist/proof/step-runner.js +234 -0
- package/dist/public/evidence-levels.d.ts +12 -0
- package/dist/public/evidence-levels.d.ts.map +1 -0
- package/dist/public/evidence-levels.js +19 -0
- package/dist/public/impact/coverage-depth-quality.d.ts +7 -0
- package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
- package/dist/public/impact/coverage-depth-quality.js +59 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +3 -1
- package/dist/public/operations/catalog.d.ts +167 -6
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts +2 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +6 -0
- package/dist/public/operations/evidence-floor.d.ts +48 -0
- package/dist/public/operations/evidence-floor.d.ts.map +1 -0
- package/dist/public/operations/evidence-floor.js +143 -0
- package/dist/public/operations/migration-plan.d.ts +19 -5
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +22 -5
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +4 -1
- package/dist/public/operations/proof-contract-claims.d.ts +26 -0
- package/dist/public/operations/proof-contract-claims.d.ts.map +1 -0
- package/dist/public/operations/proof-contract-claims.js +71 -0
- 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 +157 -5
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +15 -2
- package/dist/public/operations/specs/proof.d.ts +9 -0
- package/dist/public/operations/specs/proof.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +19 -10
- package/dist/public/operations/specs/upsert.d.ts +157 -5
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/proof-certificates.d.ts +89 -0
- package/dist/public/proof-certificates.d.ts.map +1 -0
- package/dist/public/proof-certificates.js +207 -0
- package/dist/public/proof-protocol.d.ts +126 -3
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +239 -3
- package/dist/public/proof-receipt.d.ts +89 -6
- package/dist/public/proof-receipt.d.ts.map +1 -1
- package/dist/public/proof-receipt.js +83 -7
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +18 -1
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +6 -1
- package/dist/public/skills/kibi-decisions/SKILL.md +10 -2
- package/dist/public/skills/kibi-decisions/resources/decision-records.md +6 -1
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/dist/public/skills/kibi-freshness/SKILL.md +5 -1
- package/dist/public/skills/kibi-traceability/SKILL.md +11 -1
- package/dist/public/skills/kibi-usage/SKILL.md +6 -4
- package/dist/public/skills/kibi-usage/resources/proof.md +124 -19
- package/dist/public/skills/kibi-usage/resources/workflows.md +4 -4
- package/dist/report/html-report.css +38 -1
- package/dist/report/html-report.d.ts +8 -0
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +141 -6
- 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 +7 -0
- package/dist/schemas/entity.schema.json +212 -4
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +1 -0
- package/dist/signoff/html.d.ts.map +1 -1
- package/dist/signoff/html.js +3 -0
- package/dist/signoff/markdown.d.ts.map +1 -1
- package/dist/signoff/markdown.js +3 -0
- package/dist/signoff/model.d.ts +20 -0
- package/dist/signoff/model.d.ts.map +1 -1
- package/dist/signoff/model.js +20 -1
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +1 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +1 -0
- package/dist/types/entities.d.ts +4 -1
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/merge-driver-setup.d.ts +8 -1
- package/dist/utils/merge-driver-setup.d.ts.map +1 -1
- package/dist/utils/merge-driver-setup.js +23 -2
- package/dist/utils/rule-registry.generated.d.ts +10 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +12 -0
- 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 +5 -1
- package/package.json +6 -2
- package/schema/entities.pl +6 -0
- package/schema/validation.pl +4 -1
- package/src/public/evidence-levels.ts +23 -0
- package/src/public/impact/coverage-depth-quality.ts +73 -0
- package/src/public/impact/full-kb-quality.ts +6 -1
- package/src/public/operations/check-executor.ts +13 -0
- package/src/public/operations/evidence-floor.ts +203 -0
- package/src/public/operations/migration-plan.ts +39 -6
- package/src/public/operations/node-ports.ts +3 -1
- package/src/public/operations/proof-contract-claims.ts +103 -0
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/mutation-schemas.ts +17 -2
- package/src/public/operations/specs/reporting.ts +20 -10
- package/src/public/proof-certificates.ts +271 -0
- package/src/public/proof-protocol-types.d.ts +17 -1
- package/src/public/proof-protocol.ts +318 -3
- package/src/public/proof-receipt.ts +127 -7
- package/src/public/schemas/entity.ts +19 -1
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/src/public/skills/kibi-commit-review/resources/staged-gate.md +6 -1
- package/src/public/skills/kibi-decisions/SKILL.md +10 -2
- package/src/public/skills/kibi-decisions/resources/decision-records.md +6 -1
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/src/public/skills/kibi-freshness/SKILL.md +5 -1
- package/src/public/skills/kibi-traceability/SKILL.md +11 -1
- package/src/public/skills/kibi-usage/SKILL.md +6 -4
- package/src/public/skills/kibi-usage/resources/proof.md +124 -19
- package/src/public/skills/kibi-usage/resources/workflows.md +4 -4
- package/src/schemas/entity.schema.json +212 -4
- package/dist/commands/proof-impact.d.ts +0 -7
- package/dist/commands/proof-impact.d.ts.map +0 -1
- package/dist/commands/proof-impact.js +0 -39
- package/dist/operations/proof/baseline-diff.d.ts +0 -41
- package/dist/operations/proof/baseline-diff.d.ts.map +0 -1
- package/dist/operations/proof/baseline-diff.js +0 -153
- package/dist/operations/proof/impact.d.ts +0 -51
- package/dist/operations/proof/impact.d.ts.map +0 -1
- package/dist/operations/proof/impact.js +0 -138
|
@@ -0,0 +1,211 @@
|
|
|
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 { randomBytes } from "node:crypto";
|
|
19
|
+
import { rmSync, writeFileSync } from "node:fs";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { runOperationJsonQuery, toPrologAtom, } from "../../public/operations/prolog-json.js";
|
|
22
|
+
import { compileWitness, loadSymbol, smtAssertion, } from "./code-certificates.js";
|
|
23
|
+
function record(value) {
|
|
24
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
25
|
+
? value
|
|
26
|
+
: null;
|
|
27
|
+
}
|
|
28
|
+
function text(value) {
|
|
29
|
+
return typeof value === "string" ? value : "";
|
|
30
|
+
}
|
|
31
|
+
function sorted(values) {
|
|
32
|
+
return [...new Set(values)].sort();
|
|
33
|
+
}
|
|
34
|
+
function setDifference(code, fact) {
|
|
35
|
+
const factSet = new Set(fact);
|
|
36
|
+
const codeSet = new Set(code);
|
|
37
|
+
const missing = fact.filter((member) => !codeSet.has(member));
|
|
38
|
+
const extra = code.filter((member) => !factSet.has(member));
|
|
39
|
+
return [
|
|
40
|
+
missing.length > 0 ? `missing ${missing.slice(0, 5).join(", ")}` : "",
|
|
41
|
+
extra.length > 0 ? `not in the set ${extra.slice(0, 5).join(", ")}` : "",
|
|
42
|
+
]
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
.join("; ");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The type-level witness Kibi writes for a typecheck claim binding: it
|
|
48
|
+
* compiles only when the domain type has exactly the fact's members.
|
|
49
|
+
*/
|
|
50
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
51
|
+
export function setEqualityWitness(importPath, members, membersType) {
|
|
52
|
+
const union = members.map((member) => JSON.stringify(member)).join(" | ");
|
|
53
|
+
return [
|
|
54
|
+
`import type * as domain from ${JSON.stringify(importPath)};`,
|
|
55
|
+
"type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;",
|
|
56
|
+
`type Members = ${membersType};`,
|
|
57
|
+
`const exact: Equals<Members, ${union}> = true;`,
|
|
58
|
+
"void exact;",
|
|
59
|
+
"export {};",
|
|
60
|
+
"",
|
|
61
|
+
].join("\n");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* How a domain export may spell its members as a type: a type alias or
|
|
65
|
+
* enum, a const array, the values of a string enum, or a const object's keys.
|
|
66
|
+
*/
|
|
67
|
+
function membersTypeCandidates(exportName) {
|
|
68
|
+
const name = `domain.${exportName}`;
|
|
69
|
+
return [
|
|
70
|
+
name,
|
|
71
|
+
`(typeof ${name})[number]`,
|
|
72
|
+
`\`\${${name}}\``,
|
|
73
|
+
`keyof typeof ${name}`,
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
async function typecheckSetProblem(context, contract, obligation) {
|
|
77
|
+
const domainId = contract.domain_source?.symbol_id ?? "";
|
|
78
|
+
const domain = await loadSymbol(context, domainId);
|
|
79
|
+
if (!domain || domain.sourceFile === "")
|
|
80
|
+
return `the domain_source symbol ${domainId} has no source file`;
|
|
81
|
+
const exportName = contract.domain_source?.export ?? domain.title;
|
|
82
|
+
const directory = path.dirname(domain.sourceFile);
|
|
83
|
+
const base = path.basename(domain.sourceFile).replace(/\.[cm]?[jt]sx?$/, "");
|
|
84
|
+
const witnessPath = path.join(directory, `.kibi-claim-witness-${randomBytes(6).toString("hex")}.ts`);
|
|
85
|
+
const absolute = path.resolve(context.workspaceRoot, witnessPath);
|
|
86
|
+
let lastReason = "";
|
|
87
|
+
try {
|
|
88
|
+
for (const membersType of membersTypeCandidates(exportName)) {
|
|
89
|
+
writeFileSync(absolute, setEqualityWitness(`./${base}.js`, obligation.members, membersType), "utf8");
|
|
90
|
+
const compiled = compileWitness(context.workspaceRoot, witnessPath);
|
|
91
|
+
if (compiled.ok)
|
|
92
|
+
return null;
|
|
93
|
+
lastReason = compiled.reason;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
rmSync(absolute, { force: true });
|
|
98
|
+
}
|
|
99
|
+
return `${exportName} as a type is not exactly the fact's set {${obligation.members.join(", ")}}${lastReason ? ` (${lastReason.replace(/ the witness \S+/, " the set-equality witness")})` : ""}`;
|
|
100
|
+
}
|
|
101
|
+
function smtNegation(obligation) {
|
|
102
|
+
const assertion = smtAssertion(obligation.variable, obligation.value_type, {
|
|
103
|
+
operator: obligation.operator,
|
|
104
|
+
value: obligation.value,
|
|
105
|
+
});
|
|
106
|
+
// (assert X) -> (assert (not X))
|
|
107
|
+
return `(assert (not ${assertion.slice("(assert ".length, -1)}))`;
|
|
108
|
+
}
|
|
109
|
+
function constraintText(obligation) {
|
|
110
|
+
return `${obligation.variable} ${obligation.operator} ${obligation.value}`;
|
|
111
|
+
}
|
|
112
|
+
async function derivedProblem(context, contract, certificate, row, coveredBy) {
|
|
113
|
+
const obligation = record(row.obligation) ?? {};
|
|
114
|
+
const kind = contract.kind;
|
|
115
|
+
const factId = row.fact_id ?? "the grounding fact";
|
|
116
|
+
if (kind === "exhaustive" || kind === "typecheck") {
|
|
117
|
+
const set = obligation;
|
|
118
|
+
const domainId = contract.domain_source?.symbol_id ?? "";
|
|
119
|
+
if (!coveredBy.has(domainId))
|
|
120
|
+
return `the domain_source symbol ${domainId} is not in the receipt's code scope: link it covered_by the test so a change to the domain stales the proof`;
|
|
121
|
+
if (kind === "exhaustive") {
|
|
122
|
+
const members = record(certificate.domain)?.members;
|
|
123
|
+
const code = sorted(Array.isArray(members) ? members.map((member) => String(member)) : []);
|
|
124
|
+
const fact = sorted(set.members ?? []);
|
|
125
|
+
if (code.join("\u0000") !== fact.join("\u0000"))
|
|
126
|
+
return `the domain members Kibi read are not ${factId}'s set (${setDifference(code, fact)})`;
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return typecheckSetProblem(context, contract, set);
|
|
130
|
+
}
|
|
131
|
+
const numeric = obligation;
|
|
132
|
+
if (kind === "arithmetic") {
|
|
133
|
+
const claim = record(certificate.claim) ?? {};
|
|
134
|
+
if (text(certificate.variable) !== numeric.variable ||
|
|
135
|
+
text(certificate.value_type) !== numeric.value_type ||
|
|
136
|
+
text(claim.operator) !== numeric.operator ||
|
|
137
|
+
Number(claim.value) !== numeric.value)
|
|
138
|
+
return `the certificate's claim is not ${factId}'s constraint (${constraintText(numeric)})`;
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const query = text(certificate.query).replace(/\s+/g, " ");
|
|
142
|
+
const negation = smtNegation(numeric);
|
|
143
|
+
if (!query.includes(negation))
|
|
144
|
+
return `the query does not assert the negation of ${factId}'s constraint ${negation}`;
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* How a certificate binds to each claim its contract names in proves. Kibi
|
|
149
|
+
* derives what the certificate must establish from each claim's grounding
|
|
150
|
+
* fact (claim_obligations.pl) and checks the certificate against it; a claim
|
|
151
|
+
* whose fact has no derivation is only attested by the author. Returns
|
|
152
|
+
* undefined for a contract that names no claims.
|
|
153
|
+
*/
|
|
154
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
155
|
+
export async function judgeClaimBindings(context, input) {
|
|
156
|
+
const keys = input.contract.proves ?? [];
|
|
157
|
+
if (keys.length === 0 || input.contract.kind === undefined)
|
|
158
|
+
return undefined;
|
|
159
|
+
if (context.prolog === undefined)
|
|
160
|
+
return keys.map((key) => ({
|
|
161
|
+
claim_key: key,
|
|
162
|
+
binding: "rejected",
|
|
163
|
+
reason: "no Prolog runtime is attached to resolve the claim",
|
|
164
|
+
}));
|
|
165
|
+
const rows = await runOperationJsonQuery(context.prolog, "claim_obligations.pl", `claim_obligations:test_claim_obligations_json(${toPrologAtom(input.testId)}, ${toPrologAtom(JSON.stringify(keys))}, ${toPrologAtom(input.contract.kind)}, JsonString)`, "Claim obligations");
|
|
166
|
+
const coveredBy = new Set(input.coveredBySymbols);
|
|
167
|
+
const valueSourced = (input.contract.value_source ?? []).length > 0 &&
|
|
168
|
+
(input.contract.value_source ?? []).every((source) => coveredBy.has(source.symbol_id));
|
|
169
|
+
const certificate = record(input.verdict.certificate) ?? {};
|
|
170
|
+
const bindings = [];
|
|
171
|
+
for (const row of rows) {
|
|
172
|
+
const base = {
|
|
173
|
+
claim_key: row.claim_key,
|
|
174
|
+
...(row.requirement_id ? { requirement_id: row.requirement_id } : {}),
|
|
175
|
+
...(row.fact_id ? { fact_id: row.fact_id } : {}),
|
|
176
|
+
};
|
|
177
|
+
if (row.result === "unresolved" || row.result === "incompatible") {
|
|
178
|
+
bindings.push({
|
|
179
|
+
...base,
|
|
180
|
+
binding: "rejected",
|
|
181
|
+
reason: row.reason ?? "the claim cannot be proved by this certificate",
|
|
182
|
+
});
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (row.result === "attested") {
|
|
186
|
+
bindings.push({ ...base, binding: "attested", scope: "code" });
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const obligation = record(row.obligation) ?? {};
|
|
190
|
+
if (input.verdict.evidence_level !== "proved") {
|
|
191
|
+
bindings.push({
|
|
192
|
+
...base,
|
|
193
|
+
binding: "rejected",
|
|
194
|
+
obligation,
|
|
195
|
+
reason: `the certificate did not re-check${input.verdict.certificate_rejection ? `: ${input.verdict.certificate_rejection}` : ""}`,
|
|
196
|
+
});
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const problem = await derivedProblem(context, input.contract, certificate, row, coveredBy);
|
|
200
|
+
const numeric = text(obligation.kind) === "numeric_constraint";
|
|
201
|
+
bindings.push(problem === null
|
|
202
|
+
? {
|
|
203
|
+
...base,
|
|
204
|
+
binding: "derived",
|
|
205
|
+
scope: numeric && !valueSourced ? "intent" : "code",
|
|
206
|
+
obligation,
|
|
207
|
+
}
|
|
208
|
+
: { ...base, binding: "rejected", obligation, reason: problem });
|
|
209
|
+
}
|
|
210
|
+
return bindings;
|
|
211
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { OperationContext } from "../../public/operations/runtime-types.js";
|
|
2
|
+
import { type ProofContract, type ProofKind } from "../../public/proof-protocol.js";
|
|
3
|
+
/**
|
|
4
|
+
* What a receipt records about its contract's kind: the evidence level it
|
|
5
|
+
* supports and, for a certificate kind, the certificate and its re-check.
|
|
6
|
+
*/
|
|
7
|
+
export type CertificateVerdict = Readonly<{
|
|
8
|
+
kind: ProofKind;
|
|
9
|
+
evidence_level: "proved" | "tested";
|
|
10
|
+
certificate?: Readonly<Record<string, unknown>>;
|
|
11
|
+
certificate_digest?: string;
|
|
12
|
+
certificate_rejection?: string;
|
|
13
|
+
}>;
|
|
14
|
+
export type SymbolRow = Readonly<{
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
sourceFile: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function loadSymbol(context: OperationContext, symbolId: string): Promise<SymbolRow | null>;
|
|
20
|
+
export declare function readWorkspaceFile(workspaceRoot: string, relative: string): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Whether `source` (at `sourcePath`) imports `targetPath` and names
|
|
23
|
+
* `identifier`: the domain is read from the code, not hand-listed. A suite
|
|
24
|
+
* that tests compiled output imports the domain from the TypeScript
|
|
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`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function importsDomain(source: string, sourcePath: string, targetPath: string, identifier: string, workspaceRoot?: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Map a workspace-relative path inside a TypeScript project's `outDir` to the
|
|
31
|
+
* matching path under its `rootDir` (the tsconfig's directory when unset),
|
|
32
|
+
* using the nearest tsconfig.json above the path. Null when no tsconfig
|
|
33
|
+
* declares an `outDir` that contains it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function compiledToSourcePath(workspaceRoot: string, relativePath: string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* The Python interpreters a domain loads with, most specific first: the
|
|
38
|
+
* KIBI_PYTHON override, the active virtualenv, a project virtualenv (`.venv`
|
|
39
|
+
* or `venv`) between the domain file and the workspace root, then python3
|
|
40
|
+
* and python on PATH. The system interpreter usually cannot import the
|
|
41
|
+
* project's dependencies, so a project environment comes before it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function pythonDomainInterpreters(workspaceRoot: string, sourceFile: string, env?: NodeJS.ProcessEnv): string[];
|
|
44
|
+
/**
|
|
45
|
+
* The domain as the code defines it: Kibi imports the domain_source file
|
|
46
|
+
* itself and reads the named export's members, so a certificate cannot cover
|
|
47
|
+
* a hand-listed subset. A TypeScript or JavaScript domain loads with bun when
|
|
48
|
+
* it is on PATH, else with the workspace's tsx, else with node's type
|
|
49
|
+
* stripping (which retries extensionless relative imports as TypeScript
|
|
50
|
+
* files); a Python domain (`.py`) loads with the first interpreter
|
|
51
|
+
* pythonDomainInterpreters finds.
|
|
52
|
+
*/
|
|
53
|
+
export declare function evaluateDomain(workspaceRoot: string, sourceFile: string, exportName: string, options?: Readonly<{
|
|
54
|
+
/** The TypeScript runners to try, in order (default all three). */
|
|
55
|
+
runners?: readonly ("bun" | "tsx" | "node")[];
|
|
56
|
+
}>): {
|
|
57
|
+
ok: true;
|
|
58
|
+
count: number;
|
|
59
|
+
members: readonly string[] | null;
|
|
60
|
+
} | {
|
|
61
|
+
ok: false;
|
|
62
|
+
reason: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The number a value_source export holds, read the same way as a domain.
|
|
66
|
+
*/
|
|
67
|
+
export declare function evaluateScalar(workspaceRoot: string, sourceFile: string, exportName: string): {
|
|
68
|
+
ok: true;
|
|
69
|
+
value: number;
|
|
70
|
+
} | {
|
|
71
|
+
ok: false;
|
|
72
|
+
reason: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Whether an exhaustive certificate covers the domain Kibi evaluated: the
|
|
76
|
+
* same members when they are primitive values, else the same count.
|
|
77
|
+
*/
|
|
78
|
+
export declare function domainCoverageProblem(exportName: string, evaluated: Readonly<{
|
|
79
|
+
count: number;
|
|
80
|
+
members: readonly string[] | null;
|
|
81
|
+
}>, certified: readonly string[]): string | null;
|
|
82
|
+
/**
|
|
83
|
+
* Kibi compiles a typecheck witness itself, with the workspace's TypeScript
|
|
84
|
+
* and fixed strict options (a lax project tsconfig could make the never
|
|
85
|
+
* check vacuous), and accepts it only with no errors in the witness.
|
|
86
|
+
*/
|
|
87
|
+
export declare function compileWitness(workspaceRoot: string, witnessPath: string): {
|
|
88
|
+
ok: true;
|
|
89
|
+
version: string;
|
|
90
|
+
} | {
|
|
91
|
+
ok: false;
|
|
92
|
+
reason: string;
|
|
93
|
+
};
|
|
94
|
+
export type FactConstraint = Readonly<{
|
|
95
|
+
operator: string;
|
|
96
|
+
value: number;
|
|
97
|
+
}>;
|
|
98
|
+
/** The SMT-LIB assertion a fact constraint must appear as in the query. */
|
|
99
|
+
export declare function smtAssertion(property: string, valueType: "int" | "real", row: FactConstraint): string;
|
|
100
|
+
/**
|
|
101
|
+
* The values a contract's value_source exports hold, read from the code the
|
|
102
|
+
* same way as a domain, or why one cannot be read.
|
|
103
|
+
*/
|
|
104
|
+
export declare function valueSourceValues(context: OperationContext, contract: ProofContract): Promise<{
|
|
105
|
+
ok: true;
|
|
106
|
+
values: {
|
|
107
|
+
symbol_id: string;
|
|
108
|
+
value: number;
|
|
109
|
+
}[];
|
|
110
|
+
} | {
|
|
111
|
+
ok: false;
|
|
112
|
+
reason: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** The solver re-run behind an smt certificate; unsat is the only proof. */
|
|
115
|
+
export declare function rerunSmtQuery(solver: string, query: string): {
|
|
116
|
+
ok: true;
|
|
117
|
+
} | {
|
|
118
|
+
ok: false;
|
|
119
|
+
reason: string;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Re-check the certificate a certificate-kind run left for one test. A
|
|
123
|
+
* runner kind (e2e, example, property) supports tested evidence and needs
|
|
124
|
+
* no certificate; a certificate kind supports proved evidence only when the
|
|
125
|
+
* certificate re-checks: its structure and arithmetic in code_certificates.pl,
|
|
126
|
+
* and here that the proof read its domain from the code, that the witness is
|
|
127
|
+
* the workspace file, and that the solver still answers unsat.
|
|
128
|
+
*/
|
|
129
|
+
export declare function checkCodeCertificate(context: OperationContext, input: Readonly<{
|
|
130
|
+
testId: string;
|
|
131
|
+
contract: ProofContract;
|
|
132
|
+
outcome: string;
|
|
133
|
+
certificate: unknown;
|
|
134
|
+
}>): Promise<CertificateVerdict>;
|
|
135
|
+
//# sourceMappingURL=code-certificates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-certificates.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-certificates.ts"],"names":[],"mappings":"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"}
|