kibi-cli 2.30.0 → 2.31.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-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +23 -2
- package/dist/commands/check-certificates.d.ts +52 -0
- package/dist/commands/check-certificates.d.ts.map +1 -0
- package/dist/commands/check-certificates.js +163 -0
- package/dist/commands/discovery-table.d.ts.map +1 -1
- package/dist/commands/discovery-table.js +14 -2
- package/dist/commands/report.js +3 -3
- package/dist/commands/signoff.d.ts.map +1 -1
- package/dist/commands/signoff.js +4 -1
- package/dist/operations/planning/apply-plan.js +5 -5
- package/dist/operations/proof/baseline-diff.d.ts +1 -1
- package/dist/operations/proof/baseline-diff.js +1 -1
- package/dist/operations/proof/impact.d.ts +10 -4
- package/dist/operations/proof/impact.d.ts.map +1 -1
- package/dist/operations/proof/impact.js +27 -7
- package/dist/public/diagnostic-usage.js +2 -2
- package/dist/public/operations/catalog.d.ts +4 -4
- 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/reporting.d.ts +4 -4
- package/dist/public/operations/specs/reporting.js +7 -7
- package/dist/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/dist/public/skills/kibi-decisions/SKILL.md +1 -1
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/dist/public/skills/kibi-freshness/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/resources/proof.md +36 -4
- package/dist/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/dist/report/html-report.css +11 -4
- package/dist/report/html-report.d.ts +2 -2
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +27 -21
- package/dist/report/report-view.d.ts +2 -2
- package/dist/report/report-view.js +2 -2
- package/dist/signoff/collect.d.ts.map +1 -1
- package/dist/signoff/collect.js +5 -1
- package/dist/signoff/html.js +3 -3
- package/dist/signoff/model.d.ts +7 -2
- package/dist/signoff/model.d.ts.map +1 -1
- package/dist/signoff/model.js +6 -2
- package/dist/traceability/staged-consistency.d.ts.map +1 -1
- package/dist/traceability/staged-consistency.js +3 -1
- 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/package.json +2 -2
- package/src/public/diagnostic-usage.ts +3 -3
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/reporting.ts +7 -7
- package/src/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/src/public/skills/kibi-decisions/SKILL.md +1 -1
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/src/public/skills/kibi-freshness/SKILL.md +2 -2
- package/src/public/skills/kibi-usage/SKILL.md +2 -2
- package/src/public/skills/kibi-usage/resources/proof.md +36 -4
- package/src/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/templates/github/kibi-badge.yml +1 -1
|
@@ -39,7 +39,7 @@ export declare const CLI_OPERATION_METADATA: readonly [{
|
|
|
39
39
|
}, {
|
|
40
40
|
readonly name: "kb_coverage";
|
|
41
41
|
readonly cliName: "coverage";
|
|
42
|
-
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are
|
|
42
|
+
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are tested end to end, how strong each requirement's evidence is (evidenceLevel: proved, tested, asserted or unverified), and what blocks the rest; use kb_find_gaps for a plain list of missing links and kb_check for rule violations. Reports include the compatible repair plan plus typed kibi.migration-plan.v2 actions; semantic and E2E actions remain review/execution work. Paginated plans identify incomplete scope and no mutation occurs.";
|
|
43
43
|
}, {
|
|
44
44
|
readonly name: "kb_graph";
|
|
45
45
|
readonly cliName: "graph";
|
|
@@ -45,7 +45,7 @@ export const CLI_OPERATION_METADATA = [
|
|
|
45
45
|
{
|
|
46
46
|
name: "kb_coverage",
|
|
47
47
|
cliName: "coverage",
|
|
48
|
-
description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are
|
|
48
|
+
description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are tested end to end, how strong each requirement's evidence is (evidenceLevel: proved, tested, asserted or unverified), and what blocks the rest; use kb_find_gaps for a plain list of missing links and kb_check for rule violations. Reports include the compatible repair plan plus typed kibi.migration-plan.v2 actions; semantic and E2E actions remain review/execution work. Paginated plans identify incomplete scope and no mutation occurs.",
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
name: "kb_graph",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-register-reporting.d.ts","sourceRoot":"","sources":["../src/cli-register-reporting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"cli-register-reporting.d.ts","sourceRoot":"","sources":["../src/cli-register-reporting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+QhE"}
|
|
@@ -65,7 +65,7 @@ export function registerReportingCommands(program) {
|
|
|
65
65
|
.option("--by <group>", "Coverage mode: req|symbol|type", "req")
|
|
66
66
|
.option("--tag <tags>", "Comma-separated tag filter")
|
|
67
67
|
.option("--include-passing", "Include passing rows", false)
|
|
68
|
-
.option("--status <statuses>", "Comma-separated requirement proof-status filter (
|
|
68
|
+
.option("--status <statuses>", "Comma-separated requirement proof-status filter (tested, missing, unresolved, not_applicable); implies include-passing")
|
|
69
69
|
.option("--no-include-transitive", "Disable transitive symbol coverage")
|
|
70
70
|
.option("--limit <n>", "Limit results", "100")
|
|
71
71
|
.option("--offset <n>", "Skip results", "0")
|
|
@@ -120,6 +120,8 @@ export function registerReportingCommands(program) {
|
|
|
120
120
|
.option("--min-links <n>", "Minimum number of links required for symbol coverage", "1")
|
|
121
121
|
.option("--dry-run", "Do not modify files; only print what would happen")
|
|
122
122
|
.option("--format <format>", "Output format: text|json", "text")
|
|
123
|
+
.option("--write-certificates <file>", "Also save the kibi.certificates.v1 bundle the kb-consistency rule re-checked")
|
|
124
|
+
.option("--certificates <file>", "Only re-check a saved kibi.certificates.v1 bundle against the current KB with the independent checker")
|
|
123
125
|
.action(withExitCode(async (options, command) => {
|
|
124
126
|
if (options.input !== undefined) {
|
|
125
127
|
await runJsonInvocation({
|
|
@@ -129,7 +131,26 @@ export function registerReportingCommands(program) {
|
|
|
129
131
|
});
|
|
130
132
|
return undefined;
|
|
131
133
|
}
|
|
132
|
-
|
|
134
|
+
// implements REQ-kibi-kb-certificates
|
|
135
|
+
if (options.certificates !== undefined) {
|
|
136
|
+
if (options.writeCertificates !== undefined ||
|
|
137
|
+
options.staged ||
|
|
138
|
+
options.rules !== undefined)
|
|
139
|
+
throw new Error("check: --certificates only re-checks a saved bundle; it cannot be combined with --write-certificates, --staged or --rules");
|
|
140
|
+
return (await import("./commands/check-certificates.js")).checkCertificatesCommand({
|
|
141
|
+
certificates: options.certificates,
|
|
142
|
+
json: options.format === "json",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (options.writeCertificates !== undefined && options.staged)
|
|
146
|
+
throw new Error("check: --write-certificates saves the full KB's bundle; it cannot be combined with --staged");
|
|
147
|
+
const { writeCertificates, ...checkOptions } = options;
|
|
148
|
+
const result = await (await import("./commands/check.js")).checkCommand(checkOptions);
|
|
149
|
+
if (writeCertificates !== undefined) {
|
|
150
|
+
const saved = await (await import("./commands/check-certificates.js")).writeCertificates(writeCertificates);
|
|
151
|
+
process.stderr.write(`Saved ${saved.certificates} certificate(s) to ${saved.path}\n`);
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
133
154
|
}));
|
|
134
155
|
program
|
|
135
156
|
.command("check-diff")
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { OperationContext } from "../public/operations/runtime-types.js";
|
|
2
|
+
type TheoremReport = Readonly<{
|
|
3
|
+
theorem: string;
|
|
4
|
+
verdict: "proved" | "disproved" | "unresolved";
|
|
5
|
+
groups?: number;
|
|
6
|
+
models?: number;
|
|
7
|
+
contradictions?: readonly unknown[];
|
|
8
|
+
unresolved?: readonly unknown[];
|
|
9
|
+
predicates?: number;
|
|
10
|
+
edges?: number;
|
|
11
|
+
}>;
|
|
12
|
+
type RejectedCertificate = Readonly<{
|
|
13
|
+
certificate: number;
|
|
14
|
+
kind: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
group?: unknown;
|
|
17
|
+
}>;
|
|
18
|
+
export type VerificationReport = Readonly<{
|
|
19
|
+
version: string;
|
|
20
|
+
status: "verified" | "rejected";
|
|
21
|
+
certificates: number;
|
|
22
|
+
verified: number;
|
|
23
|
+
rejected: readonly RejectedCertificate[];
|
|
24
|
+
theorems: readonly TheoremReport[];
|
|
25
|
+
notCovered: readonly string[];
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* The exit code for re-checking a saved bundle: 0 only when every certificate
|
|
29
|
+
* re-verifies and no theorem is disproved. An unresolved theorem does not
|
|
30
|
+
* fail the run; it is reported and never counts as proved.
|
|
31
|
+
*/
|
|
32
|
+
export declare function certificatesExitCode(report: VerificationReport): 0 | 1;
|
|
33
|
+
export declare function renderVerification(report: VerificationReport): string;
|
|
34
|
+
/** Re-check a saved kibi.certificates.v1 bundle against the current KB. */
|
|
35
|
+
export declare function recheckCertificates(bundlePath: string, context: OperationContext): Promise<VerificationReport>;
|
|
36
|
+
/** `kibi check --certificates <file>`: print the re-check report. */
|
|
37
|
+
export declare function checkCertificatesCommand(options: {
|
|
38
|
+
certificates: string;
|
|
39
|
+
json?: boolean;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
exitCode: number;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* `kibi check --write-certificates <file>`: save the bundle the
|
|
45
|
+
* kb-consistency rule re-checked, so another checker can re-check it.
|
|
46
|
+
*/
|
|
47
|
+
export declare function writeCertificates(bundlePath: string): Promise<{
|
|
48
|
+
path: string;
|
|
49
|
+
certificates: number;
|
|
50
|
+
}>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=check-certificates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-certificates.d.ts","sourceRoot":"","sources":["../../src/commands/check-certificates.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAG9E,KAAK,aAAa,GAAG,QAAQ,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,QAAQ,GAAG,WAAW,GAAG,YAAY,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,KAAK,mBAAmB,GAAG,QAAQ,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC,CAAC;AA+BH;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAKtE;AA4BD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA4CrE;AAsCD,2EAA2E;AAC3E,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAQ7B;AAGD,qEAAqE;AACrE,wBAAsB,wBAAwB,CAAC,OAAO,EAAE;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAUhC;AAGD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAUD"}
|
|
@@ -0,0 +1,163 @@
|
|
|
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
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { escapeAtom } from "../prolog/codec.js";
|
|
13
|
+
import { runOperationJsonQuery } from "../public/operations/prolog-json.js";
|
|
14
|
+
import { createCliRuntime } from "../runtime/cli-runtime.js";
|
|
15
|
+
const THEOREM_LABELS = {
|
|
16
|
+
properties_consistent: "Property facts are consistent",
|
|
17
|
+
predicates_consistent: "Predicate facts are consistent",
|
|
18
|
+
decisions_consistent: "Allow/deny decisions are consistent",
|
|
19
|
+
rules_stratified: "Stored rules are stratified",
|
|
20
|
+
};
|
|
21
|
+
const NOT_COVERED_LABELS = {
|
|
22
|
+
rule_conflicts: "opposing rule pairs (kibi check domain-contradictions)",
|
|
23
|
+
scenario_feasibility: "scenario feasibility (kibi check scenario-feasibility)",
|
|
24
|
+
};
|
|
25
|
+
function assertReadableBundle(filePath) {
|
|
26
|
+
if (!existsSync(filePath)) {
|
|
27
|
+
throw new Error(`check: no certificate bundle at ${filePath}`);
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
JSON.parse(readFileSync(filePath, "utf8"));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error(`check: ${filePath} is not valid JSON`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function prologPath(filePath) {
|
|
37
|
+
return escapeAtom(path.resolve(filePath).replaceAll("\\", "/"));
|
|
38
|
+
}
|
|
39
|
+
// implements REQ-kibi-kb-certificates
|
|
40
|
+
/**
|
|
41
|
+
* The exit code for re-checking a saved bundle: 0 only when every certificate
|
|
42
|
+
* re-verifies and no theorem is disproved. An unresolved theorem does not
|
|
43
|
+
* fail the run; it is reported and never counts as proved.
|
|
44
|
+
*/
|
|
45
|
+
export function certificatesExitCode(report) {
|
|
46
|
+
if (report.status !== "verified")
|
|
47
|
+
return 1;
|
|
48
|
+
return report.theorems.some((theorem) => theorem.verdict === "disproved")
|
|
49
|
+
? 1
|
|
50
|
+
: 0;
|
|
51
|
+
}
|
|
52
|
+
function describeGroup(entry) {
|
|
53
|
+
if (entry === null || typeof entry !== "object")
|
|
54
|
+
return String(entry);
|
|
55
|
+
const record = entry;
|
|
56
|
+
if (typeof record.subjectKey === "string") {
|
|
57
|
+
const scope = typeof record.scope === "string" && record.scope !== ""
|
|
58
|
+
? ` (scope ${record.scope})`
|
|
59
|
+
: "";
|
|
60
|
+
const reason = typeof record.reason === "string" ? `: ${record.reason}` : "";
|
|
61
|
+
return `${record.subjectKey}.${String(record.propertyKey)}${scope}${reason}`;
|
|
62
|
+
}
|
|
63
|
+
if (typeof record.name === "string") {
|
|
64
|
+
const args = Array.isArray(record.args)
|
|
65
|
+
? record.args
|
|
66
|
+
: Array.isArray(record.key)
|
|
67
|
+
? record.key
|
|
68
|
+
: [];
|
|
69
|
+
const reason = typeof record.reason === "string" ? `: ${record.reason}` : "";
|
|
70
|
+
return `${String(record.namespace)}:${record.name}(${args.join(", ")})${reason}`;
|
|
71
|
+
}
|
|
72
|
+
return JSON.stringify(entry);
|
|
73
|
+
}
|
|
74
|
+
// implements REQ-kibi-kb-certificates
|
|
75
|
+
export function renderVerification(report) {
|
|
76
|
+
const lines = [];
|
|
77
|
+
lines.push(report.status === "verified"
|
|
78
|
+
? `Kibi certificates: all ${report.certificates} re-verified`
|
|
79
|
+
: `Kibi certificates: ${report.rejected.length} problem(s); ${report.verified} of ${report.certificates} certificates re-verified`);
|
|
80
|
+
lines.push("");
|
|
81
|
+
for (const theorem of report.theorems) {
|
|
82
|
+
const label = THEOREM_LABELS[theorem.theorem] ?? theorem.theorem;
|
|
83
|
+
const detail = theorem.theorem === "rules_stratified"
|
|
84
|
+
? `${theorem.predicates ?? 0} predicates, ${theorem.edges ?? 0} dependencies`
|
|
85
|
+
: (theorem.groups ?? 0) === 0
|
|
86
|
+
? "no facts of this kind"
|
|
87
|
+
: `${theorem.models ?? 0} of ${theorem.groups ?? 0} groups have a model`;
|
|
88
|
+
lines.push(`- ${label}: ${theorem.verdict} (${detail})`);
|
|
89
|
+
for (const contradiction of theorem.contradictions ?? []) {
|
|
90
|
+
lines.push(` contradiction: ${describeGroup(contradiction)}`);
|
|
91
|
+
}
|
|
92
|
+
for (const unresolved of theorem.unresolved ?? []) {
|
|
93
|
+
lines.push(` unresolved: ${describeGroup(unresolved)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (report.rejected.length > 0) {
|
|
97
|
+
lines.push("");
|
|
98
|
+
lines.push("Rejected:");
|
|
99
|
+
for (const rejected of report.rejected) {
|
|
100
|
+
const where = rejected.certificate > 0
|
|
101
|
+
? `certificate ${rejected.certificate} (${rejected.kind})`
|
|
102
|
+
: describeGroup(rejected.group ?? rejected.kind);
|
|
103
|
+
lines.push(`- ${where}: ${rejected.reason}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (report.notCovered.length > 0) {
|
|
107
|
+
lines.push("");
|
|
108
|
+
lines.push(`Not certified yet: ${report.notCovered
|
|
109
|
+
.map((name) => NOT_COVERED_LABELS[name] ?? name)
|
|
110
|
+
.join("; ")}`);
|
|
111
|
+
}
|
|
112
|
+
return `${lines.join("\n")}\n`;
|
|
113
|
+
}
|
|
114
|
+
async function withEngine(run) {
|
|
115
|
+
const runtime = createCliRuntime();
|
|
116
|
+
const context = await runtime.open({
|
|
117
|
+
name: "kibi_check_certificates",
|
|
118
|
+
effects: [],
|
|
119
|
+
requiresProlog: true,
|
|
120
|
+
execute: async () => undefined,
|
|
121
|
+
}, {});
|
|
122
|
+
let completed = false;
|
|
123
|
+
try {
|
|
124
|
+
const result = await run(context);
|
|
125
|
+
completed = true;
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
await runtime.close(context, completed
|
|
130
|
+
? { status: "success", result: 0 }
|
|
131
|
+
: { status: "error", error: 1 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function prologOf(context) {
|
|
135
|
+
if (context.prolog === undefined) {
|
|
136
|
+
throw new Error("check: the Kibi engine is not available");
|
|
137
|
+
}
|
|
138
|
+
return context.prolog;
|
|
139
|
+
}
|
|
140
|
+
// implements REQ-kibi-kb-certificates
|
|
141
|
+
/** Re-check a saved kibi.certificates.v1 bundle against the current KB. */
|
|
142
|
+
export async function recheckCertificates(bundlePath, context) {
|
|
143
|
+
assertReadableBundle(bundlePath);
|
|
144
|
+
return await runOperationJsonQuery(prologOf(context), "certificate_check.pl", `certificate_check:kb_verify_certificates_file('${prologPath(bundlePath)}', JsonString)`, "Certificate verification");
|
|
145
|
+
}
|
|
146
|
+
// implements REQ-kibi-kb-certificates
|
|
147
|
+
/** `kibi check --certificates <file>`: print the re-check report. */
|
|
148
|
+
export async function checkCertificatesCommand(options) {
|
|
149
|
+
const report = await withEngine((context) => recheckCertificates(options.certificates, context));
|
|
150
|
+
process.stdout.write(options.json
|
|
151
|
+
? `${JSON.stringify(report, null, 2)}\n`
|
|
152
|
+
: renderVerification(report));
|
|
153
|
+
return { exitCode: certificatesExitCode(report) };
|
|
154
|
+
}
|
|
155
|
+
// implements REQ-kibi-kb-certificates
|
|
156
|
+
/**
|
|
157
|
+
* `kibi check --write-certificates <file>`: save the bundle the
|
|
158
|
+
* kb-consistency rule re-checked, so another checker can re-check it.
|
|
159
|
+
*/
|
|
160
|
+
export async function writeCertificates(bundlePath) {
|
|
161
|
+
const target = path.resolve(bundlePath);
|
|
162
|
+
return await withEngine((context) => runOperationJsonQuery(prologOf(context), "certificates.pl", `certificates:kb_write_certificates('${prologPath(target)}', JsonString)`, "Certificate generation"));
|
|
163
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-table.d.ts","sourceRoot":"","sources":["../../src/commands/discovery-table.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAmCvE;AA4ED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,MAAM,
|
|
1
|
+
{"version":3,"file":"discovery-table.d.ts","sourceRoot":"","sources":["../../src/commands/discovery-table.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAmCvE;AA4ED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,MAAM,CA+ER"}
|
|
@@ -87,9 +87,10 @@ export function renderCoverageTable(payload) {
|
|
|
87
87
|
const summaryTable = new Table({
|
|
88
88
|
head: ["Metric", "Value"],
|
|
89
89
|
colWidths: [24, 16],
|
|
90
|
+
wordWrap: true,
|
|
90
91
|
});
|
|
91
92
|
for (const [key, value] of Object.entries(summary)) {
|
|
92
|
-
summaryTable.push([key,
|
|
93
|
+
summaryTable.push([key, summaryCell(value)]);
|
|
93
94
|
}
|
|
94
95
|
const firstRow = firstFields(rows);
|
|
95
96
|
const isRequirementCoverage = firstRow !== undefined && Object.hasOwn(firstRow, "scenarioCount");
|
|
@@ -102,13 +103,14 @@ export function renderCoverageTable(payload) {
|
|
|
102
103
|
"Coverage",
|
|
103
104
|
"Depth",
|
|
104
105
|
"Proof",
|
|
106
|
+
"Evidence",
|
|
105
107
|
"Scen",
|
|
106
108
|
"Tests",
|
|
107
109
|
"Symbols",
|
|
108
110
|
"Structural gaps",
|
|
109
111
|
"Proof gaps",
|
|
110
112
|
],
|
|
111
|
-
colWidths: [20, 12, 12, 18, 36, 12, 8, 8, 10, 24, 36],
|
|
113
|
+
colWidths: [20, 12, 12, 18, 36, 12, 12, 8, 8, 10, 24, 36],
|
|
112
114
|
wordWrap: true,
|
|
113
115
|
})
|
|
114
116
|
: new Table({
|
|
@@ -126,6 +128,7 @@ export function renderCoverageTable(payload) {
|
|
|
126
128
|
stringifyCell(item.coverageStatus),
|
|
127
129
|
stringifyCell(item.coverageDepth),
|
|
128
130
|
stringifyCell(item.proofStatus),
|
|
131
|
+
stringifyCell(item.evidenceLevel),
|
|
129
132
|
stringifyCell(item.scenarioCount),
|
|
130
133
|
stringifyCell(item.testCount),
|
|
131
134
|
stringifyCell(item.transitiveSymbolCount),
|
|
@@ -287,6 +290,15 @@ function stringifyCell(value) {
|
|
|
287
290
|
}
|
|
288
291
|
return String(value);
|
|
289
292
|
}
|
|
293
|
+
// A nested summary count, such as evidenceLevels, reads as key=value pairs.
|
|
294
|
+
function summaryCell(value) {
|
|
295
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
296
|
+
return Object.entries(value)
|
|
297
|
+
.map(([key, count]) => `${key}=${stringifyCell(count)}`)
|
|
298
|
+
.join(" ");
|
|
299
|
+
}
|
|
300
|
+
return stringifyCell(value);
|
|
301
|
+
}
|
|
290
302
|
function joinCells(value) {
|
|
291
303
|
if (!Array.isArray(value) || value.length === 0) {
|
|
292
304
|
return "-";
|
package/dist/commands/report.js
CHANGED
|
@@ -170,16 +170,16 @@ export async function reportCommand(options, deps = {}) {
|
|
|
170
170
|
const summary = coverage.requirements.summary;
|
|
171
171
|
const total = Number(summary.total ?? 0);
|
|
172
172
|
const notApplicable = Number(summary.proofNotApplicable ?? 0);
|
|
173
|
-
const
|
|
173
|
+
const tested = Number(summary.proofTested ?? 0);
|
|
174
174
|
const currentRequirements = Math.max(0, total - notApplicable);
|
|
175
175
|
const proofPercent = currentRequirements === 0
|
|
176
176
|
? 0
|
|
177
|
-
: Math.round((
|
|
177
|
+
: Math.round((tested / currentRequirements) * 100);
|
|
178
178
|
const hasContradiction = coverage.requirements.rows.some((row) => Array.isArray(row.proofGaps) &&
|
|
179
179
|
row.proofGaps.includes("blocking_contradiction"));
|
|
180
180
|
const snapshotStale = coverage.requirements.meta?.dirty === true ||
|
|
181
181
|
coverage.requirements.meta?.proofSnapshotDirty === true;
|
|
182
|
-
const badgeMessage = currentRequirements === 0 ? "no requirements" : `${proofPercent}%
|
|
182
|
+
const badgeMessage = currentRequirements === 0 ? "no requirements" : `${proofPercent}% tested`;
|
|
183
183
|
const badgeColor = currentRequirements === 0
|
|
184
184
|
? KIBI_BRAND.rail
|
|
185
185
|
: hasContradiction
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signoff.d.ts","sourceRoot":"","sources":["../../src/commands/signoff.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GACjD,QAAQ,CAAC;IACP,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD,CAAC,CAAC;AAKL,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AAGxD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAGnE;
|
|
1
|
+
{"version":3,"file":"signoff.d.ts","sourceRoot":"","sources":["../../src/commands/signoff.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GACjD,QAAQ,CAAC;IACP,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD,CAAC,CAAC;AAKL,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AAGxD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAGnE;AAuFD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,WAAW,CAAC,CA4EtB"}
|
package/dist/commands/signoff.js
CHANGED
|
@@ -75,6 +75,9 @@ async function loadProof() {
|
|
|
75
75
|
status: typeof row.proofStatus === "string" ? row.proofStatus : "missing",
|
|
76
76
|
gate: earliestUnmetGate(row),
|
|
77
77
|
testCount: typeof row.testCount === "number" ? row.testCount : 0,
|
|
78
|
+
...(typeof row.evidenceLevel === "string"
|
|
79
|
+
? { evidenceLevel: row.evidenceLevel }
|
|
80
|
+
: {}),
|
|
78
81
|
contradictions: conflicts
|
|
79
82
|
.map(record)
|
|
80
83
|
.filter((conflict) => conflict.status === "contradiction")
|
|
@@ -133,7 +136,7 @@ export async function signoffCommand(options, deps = {}) {
|
|
|
133
136
|
else if (format === "chat") {
|
|
134
137
|
write(`${renderSignoffChatMarkdown(view)}\n`);
|
|
135
138
|
// The page path goes to stderr so stdout stays pasteable as the reply.
|
|
136
|
-
(deps.writeNote ?? ((text) => process.stderr.write(text)))(`Kibi signoff page: ${path.join(cwd, SIGNOFF_LATEST_HTML)} (
|
|
139
|
+
(deps.writeNote ?? ((text) => process.stderr.write(text)))(`Kibi signoff page: ${path.join(cwd, SIGNOFF_LATEST_HTML)} (publish it as a rendered page, such as a Claude Artifact, when the host has a page tool; an attached .html file shows as raw source in chat apps)\n`);
|
|
137
140
|
}
|
|
138
141
|
else {
|
|
139
142
|
const target = options.output?.trim()
|
|
@@ -2265,13 +2265,13 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
|
|
|
2265
2265
|
: finalStatus.proofSnapshotDirty === false
|
|
2266
2266
|
? "fresh"
|
|
2267
2267
|
: "not_evaluated";
|
|
2268
|
-
const
|
|
2268
|
+
const tested = coverageSummary?.proofTested;
|
|
2269
2269
|
const missing = coverageSummary?.proofMissing;
|
|
2270
|
-
const proofState = typeof
|
|
2270
|
+
const proofState = typeof tested !== "number" || typeof missing !== "number"
|
|
2271
2271
|
? "not_evaluated"
|
|
2272
|
-
:
|
|
2273
|
-
? "
|
|
2274
|
-
:
|
|
2272
|
+
: tested > 0 && missing === 0
|
|
2273
|
+
? "tested"
|
|
2274
|
+
: tested > 0
|
|
2275
2275
|
? "mixed"
|
|
2276
2276
|
: "unresolved";
|
|
2277
2277
|
const payload = {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
(at your option) any later version.
|
|
9
9
|
*/
|
|
10
10
|
// implements REQ-kibi-verification-evidence-contract
|
|
11
|
-
export const PROOF_BASELINE_VERSION = "kibi.proof-baseline.
|
|
11
|
+
export const PROOF_BASELINE_VERSION = "kibi.proof-baseline.v3";
|
|
12
12
|
function asStringArray(value) {
|
|
13
13
|
if (!Array.isArray(value))
|
|
14
14
|
return [];
|
|
@@ -5,8 +5,8 @@ export type ProofBaselineFile = {
|
|
|
5
5
|
readonly version?: string;
|
|
6
6
|
readonly mode?: string;
|
|
7
7
|
readonly currentRequirements?: number;
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
8
|
+
readonly proofTested?: number;
|
|
9
|
+
readonly currentUntested?: number;
|
|
10
10
|
readonly trackedGaps?: Record<string, number>;
|
|
11
11
|
readonly requirements?: RequirementFingerprints;
|
|
12
12
|
};
|
|
@@ -14,8 +14,8 @@ export type ProofImpactResult = {
|
|
|
14
14
|
readonly comparisonTarget: typeof COMMITTED_BASELINE_PATH;
|
|
15
15
|
readonly baselineVersion: string;
|
|
16
16
|
readonly currentRequirements: number;
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
17
|
+
readonly proofTested: number;
|
|
18
|
+
readonly currentUntested: number;
|
|
19
19
|
readonly changes: ReturnType<typeof diffFingerprints>;
|
|
20
20
|
};
|
|
21
21
|
export type ReadCommittedFile = (workspaceRoot: string, relativePath: string) => string | Promise<string>;
|
|
@@ -27,6 +27,12 @@ export type ProofImpactExecuteOptions = {
|
|
|
27
27
|
};
|
|
28
28
|
export declare function readCommittedHeadFile(workspaceRoot: string, relativePath: string): string;
|
|
29
29
|
export declare function loadCommittedBaseline(workspaceRoot: string, readCommittedFile?: ReadCommittedFile): Promise<ProofBaselineFile>;
|
|
30
|
+
/**
|
|
31
|
+
* A baseline committed before kibi.proof-baseline.v3 records a fully tested
|
|
32
|
+
* requirement as `proven`. Read it as `tested`, so the comparison shows real
|
|
33
|
+
* changes instead of a rename on every row.
|
|
34
|
+
*/
|
|
35
|
+
export declare function upgradeBaselineStatuses(baseline: ProofBaselineFile): ProofBaselineFile;
|
|
30
36
|
/** Diagnostic only: successful evaluation always exits 0. Ratchet lives in check-proof-baseline.mjs. */
|
|
31
37
|
export declare function proofImpactExitCode(_result: ProofImpactResult): 0;
|
|
32
38
|
export declare function buildProofImpact(baseline: ProofBaselineFile, coverage: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/impact.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EACL,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/impact.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,uBAAuB,EAC5B,gBAAgB,EAGjB,MAAM,oBAAoB,CAAC;AAG5B,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,YAAY,CAAC,EAAE,uBAAuB,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,uBAAuB,CAAC;IAC1D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,KACjB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9B,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC;QAAE,iBAAiB,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC9C,CAAC;AAgDF,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,MAAM,CAcR;AAGD,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,iBAAiB,GAAE,iBAAyC,GAC3D,OAAO,CAAC,iBAAiB,CAAC,CAW5B;AAED;;;;GAIG;AAEH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,GAC1B,iBAAiB,CAUnB;AAED,wGAAwG;AACxG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,CAAC,CAEjE;AAGD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,eAAe,EAAE,CAAA;CAAE,CAuBxD;AAGD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,SAAS,eAAe,EAAE,GAC/B,MAAM,CAYR;AAGD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAmBD"}
|
|
@@ -58,12 +58,32 @@ export function readCommittedHeadFile(workspaceRoot, relativePath) {
|
|
|
58
58
|
// implements REQ-kibi-verification-evidence-contract
|
|
59
59
|
export async function loadCommittedBaseline(workspaceRoot, readCommittedFile = readCommittedHeadFile) {
|
|
60
60
|
const raw = await readCommittedFile(workspaceRoot, COMMITTED_BASELINE_PATH);
|
|
61
|
+
let parsed;
|
|
61
62
|
try {
|
|
62
|
-
|
|
63
|
+
parsed = JSON.parse(raw);
|
|
63
64
|
}
|
|
64
65
|
catch {
|
|
65
66
|
throw new Error(`proof impact: HEAD:${COMMITTED_BASELINE_PATH} is not valid JSON`);
|
|
66
67
|
}
|
|
68
|
+
return upgradeBaselineStatuses(parsed);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A baseline committed before kibi.proof-baseline.v3 records a fully tested
|
|
72
|
+
* requirement as `proven`. Read it as `tested`, so the comparison shows real
|
|
73
|
+
* changes instead of a rename on every row.
|
|
74
|
+
*/
|
|
75
|
+
// implements REQ-kibi-evidence-levels
|
|
76
|
+
export function upgradeBaselineStatuses(baseline) {
|
|
77
|
+
if (baseline.requirements === undefined)
|
|
78
|
+
return baseline;
|
|
79
|
+
const requirements = {};
|
|
80
|
+
for (const [id, entry] of Object.entries(baseline.requirements)) {
|
|
81
|
+
requirements[id] =
|
|
82
|
+
entry?.proofStatus === "proven"
|
|
83
|
+
? { ...entry, proofStatus: "tested" }
|
|
84
|
+
: entry;
|
|
85
|
+
}
|
|
86
|
+
return { ...baseline, requirements };
|
|
67
87
|
}
|
|
68
88
|
/** Diagnostic only: successful evaluation always exits 0. Ratchet lives in check-proof-baseline.mjs. */
|
|
69
89
|
export function proofImpactExitCode(_result) {
|
|
@@ -77,8 +97,8 @@ export function buildProofImpact(baseline, coverage) {
|
|
|
77
97
|
const summary = coverage.summary ?? {};
|
|
78
98
|
const proofNotApplicable = asNumber(summary.proofNotApplicable);
|
|
79
99
|
const total = asNumber(summary.total);
|
|
80
|
-
const
|
|
81
|
-
const
|
|
100
|
+
const proofTested = asNumber(summary.proofTested);
|
|
101
|
+
const currentUntested = asNumber(summary.proofMissing) + asNumber(summary.proofUnresolved);
|
|
82
102
|
const current = fingerprintRequirements(rows);
|
|
83
103
|
const changes = diffFingerprints(baseline.requirements, current);
|
|
84
104
|
return {
|
|
@@ -87,8 +107,8 @@ export function buildProofImpact(baseline, coverage) {
|
|
|
87
107
|
comparisonTarget: COMMITTED_BASELINE_PATH,
|
|
88
108
|
baselineVersion: baseline.version ?? "unknown",
|
|
89
109
|
currentRequirements: total - proofNotApplicable,
|
|
90
|
-
|
|
91
|
-
|
|
110
|
+
proofTested,
|
|
111
|
+
currentUntested,
|
|
92
112
|
changes,
|
|
93
113
|
},
|
|
94
114
|
};
|
|
@@ -99,8 +119,8 @@ export function renderProofImpact(result, rows) {
|
|
|
99
119
|
`Proof impact compared to committed ${result.comparisonTarget}`,
|
|
100
120
|
`baseline version: ${result.baselineVersion}`,
|
|
101
121
|
`current requirements: ${result.currentRequirements}`,
|
|
102
|
-
`
|
|
103
|
-
`
|
|
122
|
+
`proofTested: ${result.proofTested}`,
|
|
123
|
+
`currentUntested: ${result.currentUntested}`,
|
|
104
124
|
`changed requirements: ${result.changes.length}`,
|
|
105
125
|
"",
|
|
106
126
|
];
|
|
@@ -103,7 +103,7 @@ function appendCoverageFields(fields, args, result) {
|
|
|
103
103
|
const scope = isRecord(repairPlan?.scope) ? repairPlan.scope : undefined;
|
|
104
104
|
fields.coverage_by = typeof args.by === "string" ? args.by : "req";
|
|
105
105
|
fields.coverage_requirement_count = Number(summary.total ?? rows.length);
|
|
106
|
-
fields.
|
|
106
|
+
fields.coverage_tested_count = Number(summary.proofTested ?? 0);
|
|
107
107
|
fields.coverage_proof_missing_count = Number(summary.proofMissing ?? 0);
|
|
108
108
|
fields.coverage_proof_gap_count = gapCodes.length;
|
|
109
109
|
fields.coverage_gap_codes = [...new Set(gapCodes)].sort();
|
|
@@ -160,7 +160,7 @@ export function deriveDiagnosticUsageFields(tool, args, telemetry, result) {
|
|
|
160
160
|
}
|
|
161
161
|
if (tool === "kb_coverage" && structured) {
|
|
162
162
|
appendCoverageFields(fields, args, structured);
|
|
163
|
-
fields.result_summary = `${String(fields.
|
|
163
|
+
fields.result_summary = `${String(fields.coverage_tested_count)} tested; ${String(fields.coverage_proof_gap_count)} proof gaps`;
|
|
164
164
|
}
|
|
165
165
|
if (tool === "kb_semantic_advisor" && structured) {
|
|
166
166
|
appendSemanticFields(fields, structured.receipt);
|
|
@@ -372,7 +372,7 @@ export declare const OPERATION_CATALOG: readonly [{
|
|
|
372
372
|
}, {
|
|
373
373
|
readonly name: "kb_coverage";
|
|
374
374
|
readonly cliName: "coverage";
|
|
375
|
-
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are
|
|
375
|
+
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are tested end to end, how strong each requirement's evidence is (evidenceLevel: proved, tested, asserted or unverified), and what blocks the rest; use kb_find_gaps for a plain list of missing links and kb_check for rule violations. Reports include the compatible repair plan plus typed kibi.migration-plan.v2 actions; semantic and E2E actions remain review/execution work. Paginated plans identify incomplete scope and no mutation occurs.";
|
|
376
376
|
readonly businessInputSchema: {
|
|
377
377
|
readonly type: "object";
|
|
378
378
|
readonly properties: {
|
|
@@ -392,13 +392,13 @@ export declare const OPERATION_CATALOG: readonly [{
|
|
|
392
392
|
readonly includePassing: {
|
|
393
393
|
readonly type: "boolean";
|
|
394
394
|
readonly default: false;
|
|
395
|
-
readonly description: "Also return rows that are already
|
|
395
|
+
readonly description: "Also return rows that are already tested or not applicable. By default only rows that still need repair are returned.";
|
|
396
396
|
};
|
|
397
397
|
readonly statuses: {
|
|
398
398
|
readonly type: "array";
|
|
399
399
|
readonly items: {
|
|
400
400
|
readonly type: "string";
|
|
401
|
-
readonly enum: readonly ["
|
|
401
|
+
readonly enum: readonly ["tested", "missing", "unresolved", "not_applicable"];
|
|
402
402
|
};
|
|
403
403
|
readonly description: "Requirement proof-status filter (req mode): include only rows whose proofStatus is listed. Selecting statuses implies include-passing; not_applicable rows carry their typed applicability reason in proofStages.applicability.reason. The summary always reflects the whole KB.";
|
|
404
404
|
};
|
|
@@ -1859,7 +1859,7 @@ export declare const OPERATION_CATALOG: readonly [{
|
|
|
1859
1859
|
readonly type: "string";
|
|
1860
1860
|
readonly enum: readonly string[];
|
|
1861
1861
|
};
|
|
1862
|
-
readonly description: "Optional rule subset. Allowed: must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers. If omitted, server runs canonical and advisory rules plus the full-KB qualityDiagnostics audit scan, including usage telemetry acceptance when evidence exists; migration rules run only when explicitly selected. Advisory and migration findings are non-blocking qualityDiagnostics. If supplied, server preserves scoped validation and skips the full-KB advisory scan.";
|
|
1862
|
+
readonly description: "Optional rule subset. Allowed: must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved. If omitted, server runs canonical and advisory rules plus the full-KB qualityDiagnostics audit scan, including usage telemetry acceptance when evidence exists; migration rules run only when explicitly selected. Advisory and migration findings are non-blocking qualityDiagnostics. If supplied, server preserves scoped validation and skips the full-KB advisory scan.";
|
|
1863
1863
|
};
|
|
1864
1864
|
readonly sourceFiles: {
|
|
1865
1865
|
readonly type: "array";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Every selectable kb_check rule name, registry order. */
|
|
2
2
|
export declare const SELECTABLE_RULE_NAMES: readonly string[];
|
|
3
3
|
/** Comma-separated "Allowed:" fragment for the kb_check rules description. */
|
|
4
|
-
export declare const SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers";
|
|
4
|
+
export declare const SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved";
|
|
5
5
|
//# sourceMappingURL=check-rules.generated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-rules.generated.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/check-rules.generated.ts"],"names":[],"mappings":"AAUA,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,
|
|
1
|
+
{"version":3,"file":"check-rules.generated.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/check-rules.generated.ts"],"names":[],"mappings":"AAUA,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAwDlD,CAAC;AAGF,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,iuCAC2rC,CAAC"}
|