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
|
@@ -20,6 +20,7 @@ import { rmSync, writeFileSync } from "node:fs";
|
|
|
20
20
|
import path from "node:path";
|
|
21
21
|
import { runOperationJsonQuery, toPrologAtom, } from "../../public/operations/prolog-json.js";
|
|
22
22
|
import { compileWitness, loadSymbol, smtAssertion, } from "./code-certificates.js";
|
|
23
|
+
import { stringConstraintProblem } from "./code-models.js";
|
|
23
24
|
function record(value) {
|
|
24
25
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
25
26
|
? value
|
|
@@ -109,10 +110,128 @@ function smtNegation(obligation) {
|
|
|
109
110
|
function constraintText(obligation) {
|
|
110
111
|
return `${obligation.variable} ${obligation.operator} ${obligation.value}`;
|
|
111
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* The type-level witness Kibi writes for a required_fields claim binding: it
|
|
115
|
+
* compiles only when every field is a required key of the type whose value
|
|
116
|
+
* can be neither undefined nor null. Each field has its own two lines (`key<i>`
|
|
117
|
+
* that the field exists, `required<i>` that it is required and non-null), so
|
|
118
|
+
* a failed compile says which fields break the claim.
|
|
119
|
+
*/
|
|
120
|
+
// implements REQ-kibi-non-numeric-proof-kinds
|
|
121
|
+
export function requiredFieldsWitness(importPath, typeExpression, fields) {
|
|
122
|
+
return [
|
|
123
|
+
`import type * as domain from ${JSON.stringify(importPath)};`,
|
|
124
|
+
`type Shape = ${typeExpression};`,
|
|
125
|
+
"type HasKey<K extends PropertyKey> = K extends keyof Shape ? true : false;",
|
|
126
|
+
"type IsRequired<K extends PropertyKey> = K extends keyof Shape",
|
|
127
|
+
" ? {} extends Pick<Shape, K> ? false : undefined extends Shape[K] ? false : null extends Shape[K] ? false : true",
|
|
128
|
+
" : false;",
|
|
129
|
+
...fields.flatMap((field, index) => [
|
|
130
|
+
`const key${index}: HasKey<${JSON.stringify(field)}> = true;`,
|
|
131
|
+
`const required${index}: IsRequired<${JSON.stringify(field)}> = true;`,
|
|
132
|
+
]),
|
|
133
|
+
`void [${fields.map((_, index) => `key${index}, required${index}`).join(", ")}];`,
|
|
134
|
+
"export {};",
|
|
135
|
+
"",
|
|
136
|
+
].join("\n");
|
|
137
|
+
}
|
|
138
|
+
/** Which fields a failed required-fields witness rejected, and how. */
|
|
139
|
+
export function requiredFieldsFailures(witness, fields, errorLines) {
|
|
140
|
+
const lines = witness.split("\n");
|
|
141
|
+
const failing = new Set(errorLines);
|
|
142
|
+
const lineOf = (prefix) => lines.findIndex((line) => line.startsWith(prefix));
|
|
143
|
+
const failures = [];
|
|
144
|
+
fields.forEach((field, index) => {
|
|
145
|
+
if (failing.has(lineOf(`const key${index}:`)))
|
|
146
|
+
failures.push(`${field} is not a field`);
|
|
147
|
+
else if (failing.has(lineOf(`const required${index}:`)))
|
|
148
|
+
failures.push(`${field} is optional or nullable`);
|
|
149
|
+
});
|
|
150
|
+
return failures;
|
|
151
|
+
}
|
|
152
|
+
async function requiredFieldsProblem(context, contract, fields) {
|
|
153
|
+
const domainId = contract.domain_source?.symbol_id ?? "";
|
|
154
|
+
const domain = await loadSymbol(context, domainId);
|
|
155
|
+
if (!domain || domain.sourceFile === "")
|
|
156
|
+
return `the domain_source symbol ${domainId} has no source file`;
|
|
157
|
+
const exportName = contract.domain_source?.export ?? domain.title;
|
|
158
|
+
const directory = path.dirname(domain.sourceFile);
|
|
159
|
+
const base = path.basename(domain.sourceFile).replace(/\.[cm]?[jt]sx?$/, "");
|
|
160
|
+
const witnessPath = path.join(directory, `.kibi-claim-witness-${randomBytes(6).toString("hex")}.ts`);
|
|
161
|
+
const absolute = path.resolve(context.workspaceRoot, witnessPath);
|
|
162
|
+
let lastReason = "";
|
|
163
|
+
let failures = [];
|
|
164
|
+
try {
|
|
165
|
+
for (const typeExpression of [
|
|
166
|
+
`domain.${exportName}`,
|
|
167
|
+
`InstanceType<typeof domain.${exportName}>`,
|
|
168
|
+
]) {
|
|
169
|
+
const witness = requiredFieldsWitness(`./${base}.js`, typeExpression, fields);
|
|
170
|
+
writeFileSync(absolute, witness, "utf8");
|
|
171
|
+
const compiled = compileWitness(context.workspaceRoot, witnessPath);
|
|
172
|
+
if (compiled.ok)
|
|
173
|
+
return null;
|
|
174
|
+
lastReason = compiled.reason;
|
|
175
|
+
// The first type expression that names a real type decides which
|
|
176
|
+
// fields fail; the InstanceType form is only for classes.
|
|
177
|
+
const errorLines = compiled.errorLines ?? [];
|
|
178
|
+
const shapeLine = witness.split("\n").findIndex((line) => line.startsWith("type Shape"));
|
|
179
|
+
if (failures.length === 0 && !errorLines.includes(shapeLine))
|
|
180
|
+
failures = requiredFieldsFailures(witness, fields, errorLines);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
rmSync(absolute, { force: true });
|
|
185
|
+
}
|
|
186
|
+
if (failures.length > 0)
|
|
187
|
+
return `${exportName} does not have every field of {${fields.join(", ")}} as a required, non-nullable field: ${failures.join("; ")}`;
|
|
188
|
+
return `${exportName} does not have every field of {${fields.join(", ")}} as a required, non-nullable field${lastReason ? ` (${lastReason.replace(/ the witness \S+/, " the required-fields witness")})` : ""}`;
|
|
189
|
+
}
|
|
190
|
+
/** The symbols a non-numeric certificate read, which must be in code scope. */
|
|
191
|
+
function modelSymbols(contract) {
|
|
192
|
+
return [
|
|
193
|
+
contract.domain_source?.symbol_id,
|
|
194
|
+
contract.initial_source?.symbol_id,
|
|
195
|
+
contract.pattern_source?.symbol_id,
|
|
196
|
+
...Object.values(contract.domains ?? {}).map((row) => "symbol_id" in row ? row.symbol_id : undefined),
|
|
197
|
+
...Object.values(contract.predicate_source ?? {}).flatMap((row) => [
|
|
198
|
+
row.symbol_id,
|
|
199
|
+
...(row.harness_for ?? []),
|
|
200
|
+
]),
|
|
201
|
+
].filter((id) => typeof id === "string" && id !== "");
|
|
202
|
+
}
|
|
203
|
+
async function nonNumericProblem(context, contract, certificate, obligation, factId, coveredBy) {
|
|
204
|
+
const outside = modelSymbols(contract).find((id) => !coveredBy.has(id));
|
|
205
|
+
if (outside !== undefined)
|
|
206
|
+
return `the symbol ${outside} the certificate read is not in the receipt's code scope: link it covered_by the test so a change to it stales the proof`;
|
|
207
|
+
const obligationKind = text(obligation.kind);
|
|
208
|
+
if (obligationKind === "required_fields" && contract.kind === "typecheck")
|
|
209
|
+
return requiredFieldsProblem(context, contract, Array.isArray(obligation.members) ? obligation.members.map(String) : []);
|
|
210
|
+
if (obligationKind === "string_constraint")
|
|
211
|
+
return stringConstraintProblem(certificate, obligation, factId);
|
|
212
|
+
if (context.prolog === undefined)
|
|
213
|
+
return "no Prolog runtime is attached to model check the claim";
|
|
214
|
+
const checked = await runOperationJsonQuery(context.prolog, "claim_obligations.pl", `claim_obligations:claim_model_check_json(${toPrologAtom(contract.kind ?? "")}, ${toPrologAtom(JSON.stringify(obligation))}, ${toPrologAtom(JSON.stringify(certificate))}, JsonString)`, "Claim model check");
|
|
215
|
+
return checked.ok === true ? null : (checked.reason ?? "the model check failed");
|
|
216
|
+
}
|
|
217
|
+
const NON_NUMERIC_OBLIGATIONS = new Set([
|
|
218
|
+
"required_fields",
|
|
219
|
+
"string_constraint",
|
|
220
|
+
"rule_holds",
|
|
221
|
+
"predicate_holds",
|
|
222
|
+
"every_member",
|
|
223
|
+
"machine_set",
|
|
224
|
+
"machine_relation",
|
|
225
|
+
"set_relation",
|
|
226
|
+
"nullable_fields",
|
|
227
|
+
"route_middleware",
|
|
228
|
+
]);
|
|
112
229
|
async function derivedProblem(context, contract, certificate, row, coveredBy) {
|
|
113
230
|
const obligation = record(row.obligation) ?? {};
|
|
114
231
|
const kind = contract.kind;
|
|
115
232
|
const factId = row.fact_id ?? "the grounding fact";
|
|
233
|
+
if (NON_NUMERIC_OBLIGATIONS.has(text(obligation.kind)))
|
|
234
|
+
return nonNumericProblem(context, contract, certificate, obligation, factId, coveredBy);
|
|
116
235
|
if (kind === "exhaustive" || kind === "typecheck") {
|
|
117
236
|
const set = obligation;
|
|
118
237
|
const domainId = contract.domain_source?.symbol_id ?? "";
|
|
@@ -144,6 +263,21 @@ async function derivedProblem(context, contract, certificate, row, coveredBy) {
|
|
|
144
263
|
return `the query does not assert the negation of ${factId}'s constraint ${negation}`;
|
|
145
264
|
return null;
|
|
146
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* The evidence level a receipt records. A certificate that re-checks but
|
|
268
|
+
* derives none of the claims it names from the code proves nothing about
|
|
269
|
+
* the code, so the receipt supports tested, the level coverage reports. An
|
|
270
|
+
* intent-scope derivation rests on the knowledge base's own facts alone
|
|
271
|
+
* (the test read no value from the code), so it does not count either.
|
|
272
|
+
*/
|
|
273
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
274
|
+
export function receiptEvidenceLevel(level, bindings) {
|
|
275
|
+
if (level !== "proved" || bindings === undefined || bindings.length === 0)
|
|
276
|
+
return level;
|
|
277
|
+
return bindings.some((binding) => binding.binding === "derived" && binding.scope !== "intent")
|
|
278
|
+
? "proved"
|
|
279
|
+
: "tested";
|
|
280
|
+
}
|
|
147
281
|
/**
|
|
148
282
|
* How a certificate binds to each claim its contract names in proves. Kibi
|
|
149
283
|
* derives what the certificate must establish from each claim's grounding
|
|
@@ -151,7 +285,7 @@ async function derivedProblem(context, contract, certificate, row, coveredBy) {
|
|
|
151
285
|
* whose fact has no derivation is only attested by the author. Returns
|
|
152
286
|
* undefined for a contract that names no claims.
|
|
153
287
|
*/
|
|
154
|
-
// implements REQ-kibi-claim-bound-proofs
|
|
288
|
+
// implements REQ-kibi-claim-bound-proofs, REQ-kibi-non-numeric-proof-kinds
|
|
155
289
|
export async function judgeClaimBindings(context, input) {
|
|
156
290
|
const keys = input.contract.proves ?? [];
|
|
157
291
|
if (keys.length === 0 || input.contract.kind === undefined)
|
|
@@ -165,7 +299,11 @@ export async function judgeClaimBindings(context, input) {
|
|
|
165
299
|
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
300
|
const coveredBy = new Set(input.coveredBySymbols);
|
|
167
301
|
const valueSourced = (input.contract.value_source ?? []).length > 0 &&
|
|
168
|
-
(input.contract.value_source ?? []).every((source) => coveredBy.has(source.symbol_id));
|
|
302
|
+
(input.contract.value_source ?? []).every((source) => "source" in source || coveredBy.has(source.symbol_id));
|
|
303
|
+
// A rule decided by a test harness that drives the code is about the code
|
|
304
|
+
// through that harness, so its claims are bound with scope harness.
|
|
305
|
+
const harnessed = input.contract.kind === "rule" &&
|
|
306
|
+
Object.values(input.contract.predicate_source ?? {}).some((row) => (row.harness_for ?? []).length > 0);
|
|
169
307
|
const certificate = record(input.verdict.certificate) ?? {};
|
|
170
308
|
const bindings = [];
|
|
171
309
|
for (const row of rows) {
|
|
@@ -188,11 +326,20 @@ export async function judgeClaimBindings(context, input) {
|
|
|
188
326
|
}
|
|
189
327
|
const obligation = record(row.obligation) ?? {};
|
|
190
328
|
if (input.verdict.evidence_level !== "proved") {
|
|
329
|
+
const recheck = `the certificate did not re-check${input.verdict.certificate_rejection ? `: ${input.verdict.certificate_rejection}` : ""}`;
|
|
330
|
+
// A typecheck claim is decided from the code alone, so when the
|
|
331
|
+
// author's witness fails, lead with what the code breaks (the field
|
|
332
|
+
// that is nullable, the member that is missing) rather than only
|
|
333
|
+
// "the type checker did not accept the witness".
|
|
334
|
+
const codeProblem = input.contract.kind === "typecheck" &&
|
|
335
|
+
input.verdict.certificate !== undefined
|
|
336
|
+
? await derivedProblem(context, input.contract, certificate, row, coveredBy)
|
|
337
|
+
: null;
|
|
191
338
|
bindings.push({
|
|
192
339
|
...base,
|
|
193
340
|
binding: "rejected",
|
|
194
341
|
obligation,
|
|
195
|
-
reason:
|
|
342
|
+
reason: codeProblem === null ? recheck : `${codeProblem} (${recheck})`,
|
|
196
343
|
});
|
|
197
344
|
continue;
|
|
198
345
|
}
|
|
@@ -202,7 +349,13 @@ export async function judgeClaimBindings(context, input) {
|
|
|
202
349
|
? {
|
|
203
350
|
...base,
|
|
204
351
|
binding: "derived",
|
|
205
|
-
scope: numeric && !valueSourced
|
|
352
|
+
scope: numeric && !valueSourced
|
|
353
|
+
? "intent"
|
|
354
|
+
: harnessed
|
|
355
|
+
? "harness"
|
|
356
|
+
: input.contract.kind === "source"
|
|
357
|
+
? "source"
|
|
358
|
+
: "code",
|
|
206
359
|
obligation,
|
|
207
360
|
}
|
|
208
361
|
: { ...base, binding: "rejected", obligation, reason: problem });
|
|
@@ -33,14 +33,6 @@ export declare function importsDomain(source: string, sourcePath: string, target
|
|
|
33
33
|
* declares an `outDir` that contains it.
|
|
34
34
|
*/
|
|
35
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
36
|
/**
|
|
45
37
|
* The domain as the code defines it: Kibi imports the domain_source file
|
|
46
38
|
* itself and reads the named export's members, so a certificate cannot cover
|
|
@@ -80,16 +72,22 @@ export declare function domainCoverageProblem(exportName: string, evaluated: Rea
|
|
|
80
72
|
members: readonly string[] | null;
|
|
81
73
|
}>, certified: readonly string[]): string | null;
|
|
82
74
|
/**
|
|
83
|
-
* Kibi compiles a typecheck witness itself, with the workspace's TypeScript
|
|
84
|
-
*
|
|
85
|
-
*
|
|
75
|
+
* Kibi compiles a typecheck witness itself, with the workspace's TypeScript.
|
|
76
|
+
* Imports resolve the way the project's own tsconfig says (module,
|
|
77
|
+
* moduleResolution, paths, ...) and its declaration files are in the
|
|
78
|
+
* program, but the checking options stay fixed and
|
|
79
|
+
* strict, so a lax project tsconfig cannot make the never check vacuous. It
|
|
80
|
+
* accepts the witness only with no errors in it.
|
|
86
81
|
*/
|
|
87
|
-
export declare function compileWitness(workspaceRoot: string, witnessPath: string
|
|
82
|
+
export declare function compileWitness(workspaceRoot: string, witnessPath: string, options?: Readonly<{
|
|
83
|
+
requireExhaustiveness?: boolean;
|
|
84
|
+
}>): {
|
|
88
85
|
ok: true;
|
|
89
86
|
version: string;
|
|
90
87
|
} | {
|
|
91
88
|
ok: false;
|
|
92
89
|
reason: string;
|
|
90
|
+
errorLines?: number[];
|
|
93
91
|
};
|
|
94
92
|
export type FactConstraint = Readonly<{
|
|
95
93
|
operator: string;
|
|
@@ -99,7 +97,8 @@ export type FactConstraint = Readonly<{
|
|
|
99
97
|
export declare function smtAssertion(property: string, valueType: "int" | "real", row: FactConstraint): string;
|
|
100
98
|
/**
|
|
101
99
|
* The values a contract's value_source exports hold, read from the code the
|
|
102
|
-
* same way as a domain
|
|
100
|
+
* same way as a domain (a count measure is the collection's size), or why
|
|
101
|
+
* one cannot be read.
|
|
103
102
|
*/
|
|
104
103
|
export declare function valueSourceValues(context: OperationContext, contract: ProofContract): Promise<{
|
|
105
104
|
ok: true;
|
|
@@ -118,13 +117,34 @@ export declare function rerunSmtQuery(solver: string, query: string): {
|
|
|
118
117
|
ok: false;
|
|
119
118
|
reason: string;
|
|
120
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* The certificate of a source proof: the contract's source and what Kibi
|
|
122
|
+
* reads from it. A certificate the run left must name the same source, and
|
|
123
|
+
* a model it carries must be what Kibi reads; either way the stored model is
|
|
124
|
+
* Kibi's own read, so the proof never rests on members the test listed.
|
|
125
|
+
*/
|
|
126
|
+
export declare function completeSourceCertificate(context: OperationContext, testId: string, contract: ProofContract, left: unknown): Promise<{
|
|
127
|
+
ok: true;
|
|
128
|
+
certificate: Record<string, unknown>;
|
|
129
|
+
} | {
|
|
130
|
+
ok: false;
|
|
131
|
+
reason: string;
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* A typecheck certificate whose own outcome is failed says only that: add
|
|
135
|
+
* what Kibi's compile of the same witness reports, so the author sees the
|
|
136
|
+
* first error, or learns that the test compiled it differently.
|
|
137
|
+
*/
|
|
138
|
+
export declare function withWitnessDiagnosis(context: OperationContext, contract: ProofContract, reason: string): string;
|
|
139
|
+
export { pythonDomainInterpreters, runCodeEvaluator, TS_RESOLVE_HOOKS, } from "./code-runner.js";
|
|
121
140
|
/**
|
|
122
141
|
* Re-check the certificate a certificate-kind run left for one test. A
|
|
123
142
|
* runner kind (e2e, example, property) supports tested evidence and needs
|
|
124
143
|
* no certificate; a certificate kind supports proved evidence only when the
|
|
125
144
|
* certificate re-checks: its structure and arithmetic in code_certificates.pl,
|
|
126
145
|
* and here that the proof read its domain from the code, that the witness is
|
|
127
|
-
* the workspace file,
|
|
146
|
+
* the workspace file, that the solver still answers unsat, and that a rule
|
|
147
|
+
* table, state machine or pattern is what Kibi itself reads from the code.
|
|
128
148
|
*/
|
|
129
149
|
export declare function checkCodeCertificate(context: OperationContext, input: Readonly<{
|
|
130
150
|
testId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-certificates.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-certificates.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"code-certificates.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-certificates.ts"],"names":[],"mappings":"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"}
|