kibi-cli 2.31.1 → 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 +20 -1
- 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 +1 -1
- 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-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 +1 -1
- 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-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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-register-proof.d.ts","sourceRoot":"","sources":["../src/cli-register-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"cli-register-proof.d.ts","sourceRoot":"","sources":["../src/cli-register-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsO3D;AAED;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAwBnE"}
|
|
@@ -9,6 +9,8 @@ export function registerProofCommand(program) {
|
|
|
9
9
|
.option("--integration <ids>", "Prove only tests bound to these integrations (comma-separated)")
|
|
10
10
|
.option("--integration-except <ids>", "With --all (or another selector), skip tests bound to these integrations (comma-separated)")
|
|
11
11
|
.option("--all", "Prove every proof-bearing test in the knowledge base")
|
|
12
|
+
.option("--stale", "Prove only the selected tests (all by default) without a current passing receipt")
|
|
13
|
+
.option("--resume", "Skip integrations an interrupted run with the same selector already ingested at this snapshot")
|
|
12
14
|
.action(withExitCode(async (options) => {
|
|
13
15
|
const mode = [
|
|
14
16
|
options.test ? "test" : undefined,
|
|
@@ -32,6 +34,8 @@ export function registerProofCommand(program) {
|
|
|
32
34
|
? {}
|
|
33
35
|
: { integrationExcept: options.integrationExcept }),
|
|
34
36
|
all: mode === 0,
|
|
37
|
+
...(options.stale ? { stale: true } : {}),
|
|
38
|
+
...(options.resume ? { resume: true } : {}),
|
|
35
39
|
});
|
|
36
40
|
}));
|
|
37
41
|
const proof = program
|
|
@@ -58,6 +62,21 @@ export function registerProofCommand(program) {
|
|
|
58
62
|
process.stdout.write(renderInspection(result));
|
|
59
63
|
return undefined;
|
|
60
64
|
}));
|
|
65
|
+
proof
|
|
66
|
+
.command("run-steps")
|
|
67
|
+
.description("Run the declared steps of the proof-bearing tests kibi prove selected and write a per-test report, so a command integration fails only the tests whose own steps failed (use as the integration's command)")
|
|
68
|
+
.argument("[steps-file]", "JSON array of {test_id, steps: [[argv...]]}", "proof/steps.json")
|
|
69
|
+
.option("--test <id...>", "Run these tests' steps (default: KIBI_PROOF_TEST_IDS, else every test in the file)")
|
|
70
|
+
.action(withExitCode(async (stepsFile, options) => {
|
|
71
|
+
const { runProofSteps } = await import("./proof/step-runner.js");
|
|
72
|
+
return {
|
|
73
|
+
exitCode: await runProofSteps({
|
|
74
|
+
workspaceRoot: process.env.KIBI_PROOF_WORKSPACE ?? process.cwd(),
|
|
75
|
+
stepsPath: stepsFile,
|
|
76
|
+
...(options.test === undefined ? {} : { testIds: options.test }),
|
|
77
|
+
}),
|
|
78
|
+
};
|
|
79
|
+
}));
|
|
61
80
|
proof
|
|
62
81
|
.command("explain")
|
|
63
82
|
.description("Project one requirement or symbol proof, labeling required_proofs, executable_for, and covered_by separately")
|
|
@@ -75,13 +94,6 @@ export function registerProofCommand(program) {
|
|
|
75
94
|
json: options.json === true,
|
|
76
95
|
});
|
|
77
96
|
}));
|
|
78
|
-
proof
|
|
79
|
-
.command("impact")
|
|
80
|
-
.description("Compare current proof state to HEAD:proof/baseline.json")
|
|
81
|
-
.option("--json", "Emit structured JSON", false)
|
|
82
|
-
.action(withExitCode(async (options) => {
|
|
83
|
-
return await (await import("./commands/proof-impact.js")).proofImpactCommand({ json: options.json === true });
|
|
84
|
-
}));
|
|
85
97
|
proof
|
|
86
98
|
.command("prune")
|
|
87
99
|
.description("Shrink each test's proof_receipts history to its newest entries (re-proving the same snapshot appends duplicates; prune removes the superseded ones)")
|
|
@@ -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,CAuRhE"}
|
|
@@ -43,6 +43,7 @@ export function registerReportingCommands(program) {
|
|
|
43
43
|
.option("--open", "Open the generated report in the default browser", false)
|
|
44
44
|
.option("--tag <tags>", "Comma-separated tag filter")
|
|
45
45
|
.option("--limit <n>", "Maximum complete requirement rows (1-100000)", "10000")
|
|
46
|
+
.option("--certificates <file>", "Publish a kibi check --write-certificates bundle next to the report and link it")
|
|
46
47
|
.action(async (options) => {
|
|
47
48
|
await (await import("./commands/report.js")).reportCommand(options);
|
|
48
49
|
});
|
|
@@ -120,6 +121,7 @@ export function registerReportingCommands(program) {
|
|
|
120
121
|
.option("--min-links <n>", "Minimum number of links required for symbol coverage", "1")
|
|
121
122
|
.option("--dry-run", "Do not modify files; only print what would happen")
|
|
122
123
|
.option("--format <format>", "Output format: text|json", "text")
|
|
124
|
+
.option("--fresh-evidence", "evidence-floor judges receipts as they are (stale receipts fail) and needs a clean proof snapshot; run it after kibi prove")
|
|
123
125
|
.option("--write-certificates <file>", "Also save the kibi.certificates.v1 bundle the kb-consistency rule re-checked")
|
|
124
126
|
.option("--certificates <file>", "Only re-check a saved kibi.certificates.v1 bundle against the current KB with the independent checker")
|
|
125
127
|
.action(withExitCode(async (options, command) => {
|
package/dist/commands/check.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface CheckOptions {
|
|
|
9
9
|
minLinks?: string | number;
|
|
10
10
|
dryRun?: boolean;
|
|
11
11
|
format?: "text" | "json";
|
|
12
|
+
freshEvidence?: boolean;
|
|
12
13
|
}
|
|
13
14
|
export declare function requireActiveProlog<E, P>(engine: E | null | undefined, prolog: P | null | undefined): NonNullable<E | P>;
|
|
14
15
|
export declare function checkCommand(options: CheckOptions): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsF7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA6hBD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EACtC,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5B,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GAC3B,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAMpB;AAGD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAqsB/B;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAoDtB;AAID,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAkEtB;AAID,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAmGtB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,SAAS,EAAE,CAAC,CAyCtB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAgDtB;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CA0BtB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB"}
|
package/dist/commands/check.js
CHANGED
|
@@ -25,7 +25,8 @@ import { PrologProcess } from "../prolog.js";
|
|
|
25
25
|
import { escapeAtom, normalizeEntityId, parseTriples, parseViolationRows, } from "../prolog/codec.js";
|
|
26
26
|
import { createSemanticReviewDiagnostics, createSymbolGranularityDiagnostics, createSymbolQualityDiagnostics, hasBlockingImpactDiagnostics, } from "../public/impact-diagnostics.js";
|
|
27
27
|
import { executeCheck } from "../public/operations/check-executor.js";
|
|
28
|
-
import {
|
|
28
|
+
import { EVIDENCE_FLOOR_RULE } from "../public/operations/evidence-floor.js";
|
|
29
|
+
import { nodeFilesystem, nodeGit } from "../public/operations/node-ports.js";
|
|
29
30
|
import { refreshDetachedSnapshot } from "../runtime/detached-snapshot.js";
|
|
30
31
|
import { amendsRootCommit } from "../traceability/commit-amend.js";
|
|
31
32
|
import { KIBI_NO_IMPACT_DECLARATION, KIBI_SYMBOLS_MANIFEST_PATH, KIBI_SYMBOL_COORDINATES_PATH, } from "../traceability/evidence-model.js";
|
|
@@ -927,13 +928,18 @@ export async function checkCommand(options) {
|
|
|
927
928
|
?.split(",")
|
|
928
929
|
.map((rule) => rule.trim())
|
|
929
930
|
.filter((rule) => rule.length > 0);
|
|
930
|
-
const result = await executeCheck(
|
|
931
|
+
const result = await executeCheck({
|
|
932
|
+
...(rules === undefined ? {} : { rules }),
|
|
933
|
+
...(options.freshEvidence === true ? { freshEvidence: true } : {}),
|
|
934
|
+
}, {
|
|
931
935
|
workspaceRoot: process.cwd(),
|
|
932
936
|
signal: new AbortController().signal,
|
|
933
937
|
clock: () => new Date(),
|
|
934
|
-
// The workspace snapshot lets quality diagnostics
|
|
935
|
-
// proof receipt evidence as kibi coverage
|
|
938
|
+
// The workspace snapshot lets quality diagnostics and evidence-floor
|
|
939
|
+
// read the same proof receipt evidence as kibi coverage, with the
|
|
940
|
+
// same per-contract receipt binding.
|
|
936
941
|
git: nodeGit,
|
|
942
|
+
fs: nodeFilesystem,
|
|
937
943
|
prolog: {
|
|
938
944
|
query: (goal) => activeProlog.query(goal),
|
|
939
945
|
...(activeProlog instanceof EngineClient
|
|
@@ -975,7 +981,10 @@ export async function checkCommand(options) {
|
|
|
975
981
|
console.log(` Source: ${v.source}`);
|
|
976
982
|
}
|
|
977
983
|
console.log(` ${v.description}`);
|
|
978
|
-
|
|
984
|
+
// An evidence-floor finding names no fix in its description; its
|
|
985
|
+
// suggestion carries the proof gaps and the tests and symbols behind
|
|
986
|
+
// them, so it is always shown.
|
|
987
|
+
if (v.suggestion && (options.fix || v.rule === EVIDENCE_FLOOR_RULE)) {
|
|
979
988
|
console.log(` Suggestion: ${v.suggestion}`);
|
|
980
989
|
}
|
|
981
990
|
console.log();
|
|
@@ -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,CAyGR"}
|
|
@@ -89,8 +89,30 @@ export function renderCoverageTable(payload) {
|
|
|
89
89
|
colWidths: [24, 16],
|
|
90
90
|
wordWrap: true,
|
|
91
91
|
});
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
// Traceability counts (scenario/test links) and proof counts (receipt
|
|
93
|
+
// evidence) use similar names, e.g. notApplicable vs proofNotApplicable:
|
|
94
|
+
// group them so the two families read apart.
|
|
95
|
+
// Link coverage judges only priority: must requirements; say so in the
|
|
96
|
+
// heading rather than as a row.
|
|
97
|
+
const mustOnly = summary.linkCoverageScope === "priority_must";
|
|
98
|
+
const entries = Object.entries(summary).filter(([key]) => key !== "linkCoverageScope");
|
|
99
|
+
const isProofKey = (key) => key.startsWith("proof") ||
|
|
100
|
+
key === "evidenceLevels" ||
|
|
101
|
+
key === "evidenceFloors";
|
|
102
|
+
const groups = [
|
|
103
|
+
[
|
|
104
|
+
mustOnly ? "Links (priority: must)" : "Traceability (links)",
|
|
105
|
+
entries.filter(([key]) => !isProofKey(key)),
|
|
106
|
+
],
|
|
107
|
+
["Proof (evidence)", entries.filter(([key]) => isProofKey(key))],
|
|
108
|
+
];
|
|
109
|
+
const grouped = groups.every(([, members]) => members.length > 0);
|
|
110
|
+
for (const [label, members] of groups) {
|
|
111
|
+
if (grouped)
|
|
112
|
+
summaryTable.push([label, ""]);
|
|
113
|
+
for (const [key, value] of members) {
|
|
114
|
+
summaryTable.push([grouped ? ` ${key}` : key, summaryCell(value)]);
|
|
115
|
+
}
|
|
94
116
|
}
|
|
95
117
|
const firstRow = firstFields(rows);
|
|
96
118
|
const isRequirementCoverage = firstRow !== undefined && Object.hasOwn(firstRow, "scenarioCount");
|
|
@@ -104,13 +126,14 @@ export function renderCoverageTable(payload) {
|
|
|
104
126
|
"Depth",
|
|
105
127
|
"Proof",
|
|
106
128
|
"Evidence",
|
|
129
|
+
"Floor",
|
|
107
130
|
"Scen",
|
|
108
131
|
"Tests",
|
|
109
132
|
"Symbols",
|
|
110
133
|
"Structural gaps",
|
|
111
134
|
"Proof gaps",
|
|
112
135
|
],
|
|
113
|
-
colWidths: [20, 12, 12, 18, 36, 12, 12, 8, 8, 10, 24, 36],
|
|
136
|
+
colWidths: [20, 12, 12, 18, 36, 12, 12, 12, 8, 8, 10, 24, 36],
|
|
114
137
|
wordWrap: true,
|
|
115
138
|
})
|
|
116
139
|
: new Table({
|
|
@@ -128,7 +151,8 @@ export function renderCoverageTable(payload) {
|
|
|
128
151
|
stringifyCell(item.coverageStatus),
|
|
129
152
|
stringifyCell(item.coverageDepth),
|
|
130
153
|
stringifyCell(item.proofStatus),
|
|
131
|
-
|
|
154
|
+
evidenceCell(item),
|
|
155
|
+
floorCell(item),
|
|
132
156
|
stringifyCell(item.scenarioCount),
|
|
133
157
|
stringifyCell(item.testCount),
|
|
134
158
|
stringifyCell(item.transitiveSymbolCount),
|
|
@@ -290,6 +314,29 @@ function stringifyCell(value) {
|
|
|
290
314
|
}
|
|
291
315
|
return String(value);
|
|
292
316
|
}
|
|
317
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
318
|
+
// The evidence level, with how many applicable claims a certificate proves.
|
|
319
|
+
function evidenceCell(item) {
|
|
320
|
+
const level = stringifyCell(item.evidenceLevel);
|
|
321
|
+
const summary = item.claimSummary;
|
|
322
|
+
if (summary === null || typeof summary !== "object")
|
|
323
|
+
return level;
|
|
324
|
+
const { applicable, proved } = summary;
|
|
325
|
+
if (typeof applicable !== "number" || applicable === 0)
|
|
326
|
+
return level;
|
|
327
|
+
return `${level}\n${typeof proved === "number" ? proved : 0}/${applicable} claims proved`;
|
|
328
|
+
}
|
|
329
|
+
// implements REQ-kibi-evidence-floors
|
|
330
|
+
// The evidence floor and whether the level reaches it; empty without a floor.
|
|
331
|
+
function floorCell(item) {
|
|
332
|
+
const floor = item.evidenceFloor;
|
|
333
|
+
if (floor === null || typeof floor !== "object")
|
|
334
|
+
return "";
|
|
335
|
+
const { required, status } = floor;
|
|
336
|
+
if (typeof required !== "string" || required === "unverified")
|
|
337
|
+
return "";
|
|
338
|
+
return `${required} ${typeof status === "string" ? status.replaceAll("_", " ") : ""}`.trim();
|
|
339
|
+
}
|
|
293
340
|
// A nested summary count, such as evidenceLevels, reads as key=value pairs.
|
|
294
341
|
function summaryCell(value) {
|
|
295
342
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
package/dist/commands/doctor.js
CHANGED
|
@@ -30,7 +30,7 @@ import { branchStoreCompilation, inspectBranchStore, storeLockTakeoverReason, un
|
|
|
30
30
|
import { LEGACY_KB_MIGRATION_COMMAND, LEGACY_KB_MIGRATION_NOTE, } from "../utils/config.js";
|
|
31
31
|
import { resolveGitRepository, } from "../utils/git-repository-context.js";
|
|
32
32
|
import { readKbManifestStatus } from "../utils/kb-manifest.js";
|
|
33
|
-
import {
|
|
33
|
+
import { manifestMergeDriverGaps, mergeDriverSetup, } from "../utils/merge-driver-setup.js";
|
|
34
34
|
import { LATEST_KB_SCHEMA_VERSION } from "../utils/schema-version.js";
|
|
35
35
|
import { KIBI_HOOK_BEGIN, hasManagedHooks, outdatedManagedHooks, } from "./init-helpers.js";
|
|
36
36
|
import { planLegacyStorageMigration } from "./legacy-storage-migration.js";
|
|
@@ -447,14 +447,21 @@ function checkCapabilityPlugins() {
|
|
|
447
447
|
...new Set((config.plugins ?? []).map((plugin) => plugin.package)),
|
|
448
448
|
];
|
|
449
449
|
const missingSecrets = [];
|
|
450
|
+
// Secrets whose plugin only augments a builtin provider: without them the
|
|
451
|
+
// plugin is skipped and the builtin keeps working, so doctor warns.
|
|
452
|
+
const optionalMissingSecrets = [];
|
|
450
453
|
const legacySecrets = [];
|
|
451
454
|
for (const packageName of packages) {
|
|
452
455
|
const secrets = FIRST_PARTY_PLUGIN_SECRETS[packageName] ?? [];
|
|
453
456
|
for (const secret of secrets) {
|
|
454
457
|
const source = formatSecretSourcePart(secret, bootstrap);
|
|
455
458
|
parts.push(`${secret}=${source}`);
|
|
456
|
-
if (source === "missing")
|
|
457
|
-
|
|
459
|
+
if (source === "missing") {
|
|
460
|
+
const augmentOnly = rows
|
|
461
|
+
.filter((row) => row.package === packageName)
|
|
462
|
+
.every((row) => row.mode === "augment");
|
|
463
|
+
(augmentOnly ? optionalMissingSecrets : missingSecrets).push(secret);
|
|
464
|
+
}
|
|
458
465
|
if (source === "legacy_env")
|
|
459
466
|
legacySecrets.push(secret);
|
|
460
467
|
}
|
|
@@ -473,6 +480,14 @@ function checkCapabilityPlugins() {
|
|
|
473
480
|
: `Set missing plugin secret(s) (${missingSecrets.join(", ")}) in ~/.config/kibi/env or <workspace>/.env.kibi, then restart long-running Kibi MCP/host processes.`,
|
|
474
481
|
};
|
|
475
482
|
}
|
|
483
|
+
if (optionalMissingSecrets.length > 0) {
|
|
484
|
+
return {
|
|
485
|
+
passed: true,
|
|
486
|
+
warning: true,
|
|
487
|
+
message,
|
|
488
|
+
remediation: `${optionalMissingSecrets.join(", ")} is not set, so the augment-mode plugin is skipped and builtin providers answer alone. Set it in ~/.config/kibi/env or <workspace>/.env.kibi to enable the plugin, then restart long-running Kibi MCP/host processes.`,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
476
491
|
if (legacySecrets.length > 0) {
|
|
477
492
|
return {
|
|
478
493
|
passed: true,
|
|
@@ -709,7 +724,7 @@ function checkManifestMergeDriver() {
|
|
|
709
724
|
passed: true,
|
|
710
725
|
warning: true,
|
|
711
726
|
message: `Not configured: ${gaps.join("; ")}. Merges of .kb/symbols.yaml fall back to line conflicts.`,
|
|
712
|
-
remediation:
|
|
727
|
+
remediation: mergeDriverSetup(process.cwd()),
|
|
713
728
|
};
|
|
714
729
|
}
|
|
715
730
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAgEA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,wCAAwC,CAAC;AAwBhD,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB,EAAE,SAAS,GAAG,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC3E,MAAM,EAAE,SAAS,CAAC;IAClB,4BAA4B,EAAE,MAAM,CAAC;IACrC,8EAA8E;IAC9E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,4BAA4B,EAAE,MAAM,CAAC;IACrC,sEAAsE;IACtE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,4FAA4F;IAC5F,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wHAAwH;IACxH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,0EAA0E;IAC1E,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAkLD,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAwXD,wBAAgB,+BAA+B,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKtE;AAGD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAmiB9D;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAGzE;AA8YD;;;;;GAKG;AAEH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACpC,OAAO,CAOT"}
|
package/dist/commands/migrate.js
CHANGED
|
@@ -29,7 +29,7 @@ import { applySymbolLegacyLinks, planSymbolLegacyLinks, } from "../operations/mi
|
|
|
29
29
|
import { resolveBranchAttachment } from "../utils/branch-resolver.js";
|
|
30
30
|
import { defaultKbManifest, readKbManifest, readKbManifestStatus, writeKbManifest, } from "../utils/kb-manifest.js";
|
|
31
31
|
import { CANONICAL_ENTITY_PATHS } from "../utils/kb-paths.js";
|
|
32
|
-
import {
|
|
32
|
+
import { manifestMergeDriverGaps, mergeDriverSetup, } from "../utils/merge-driver-setup.js";
|
|
33
33
|
import { LATEST_KB_SCHEMA_VERSION, getSchemaVersionStatus, normalizeSchemaVersion, } from "../utils/schema-version.js";
|
|
34
34
|
import { updateGitIgnore } from "./init-helpers.js";
|
|
35
35
|
import { applyLegacyStorageMigration, planLegacyStorageMigration, } from "./legacy-storage-migration.js";
|
|
@@ -95,6 +95,18 @@ const SCHEMA_MIGRATION_STEPS = [
|
|
|
95
95
|
to: 10,
|
|
96
96
|
description: "Read a requirement or ADR without firmness as firm unless an agent wrote it, and acknowledge in the manifest the supersedes of such decisions recorded before; no source file is rewritten and no firmness is written.",
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
id: "evidence-floor-v11",
|
|
100
|
+
from: 10,
|
|
101
|
+
to: 11,
|
|
102
|
+
description: "Check every current requirement's evidence level against its floor (required_evidence, else tested when firm), and record required_evidence: asserted on current firm requirements that have no scenario verified by a test with a proof contract; front matter only.",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "claim-bound-proofs-v12",
|
|
106
|
+
from: 11,
|
|
107
|
+
to: 12,
|
|
108
|
+
description: "Require every certificate-kind proof contract to name the requirement claims it proves, and pin proves on contracts whose test reaches exactly one claim the proof kind can derive an obligation for; front matter only. Other contracts are listed for a person to bind.",
|
|
109
|
+
},
|
|
98
110
|
];
|
|
99
111
|
function migrationStepsFor(fromVersion) {
|
|
100
112
|
const start = Math.max(0, fromVersion ?? 0);
|
|
@@ -103,6 +115,17 @@ function migrationStepsFor(fromVersion) {
|
|
|
103
115
|
function printWarning(message) {
|
|
104
116
|
console.log(`Warning: ${message}`);
|
|
105
117
|
}
|
|
118
|
+
function printClaimBindingReview(plan, noStore, dryRun) {
|
|
119
|
+
const prefix = dryRun ? "dry run: " : "";
|
|
120
|
+
if (noStore)
|
|
121
|
+
console.log(`${prefix}no synced store could be read, so no proof_contract.proves was pinned; run kibi sync and rerun kibi migrate, or add proves by hand where kibi check --rules proof-contract-claims reports a contract.`);
|
|
122
|
+
for (const row of plan.review)
|
|
123
|
+
console.log(row.candidates.length === 0
|
|
124
|
+
? `${prefix}${row.id} (${row.kind}) reaches no claim ${/^[aeiou]/.test(row.kind) ? "an" : "a"} ${row.kind} certificate can derive an obligation for; add proves with the claim it establishes (it will be attested, not proved) or model the claim's fact as a ${row.kind === "exhaustive" || row.kind === "typecheck" ? "set" : "numeric"} fact.`
|
|
125
|
+
: `${prefix}${row.id} (${row.kind}) could prove any of ${row.candidates.join(", ")}; add proof_contract.proves with the ones its certificate establishes.`);
|
|
126
|
+
for (const skip of plan.skipped)
|
|
127
|
+
printWarning(`Cannot pin proves on ${skip.path}: ${skip.reason}.`);
|
|
128
|
+
}
|
|
106
129
|
function toRelativePath(cwd, filePath) {
|
|
107
130
|
const relativePath = path.relative(cwd, filePath);
|
|
108
131
|
return relativePath.length > 0 ? relativePath : path.basename(filePath);
|
|
@@ -540,6 +563,18 @@ export async function migrateCommand(options = {}) {
|
|
|
540
563
|
const bodyContextStep = migrationSteps.some((step) => step.id === "entity-body-context-v8");
|
|
541
564
|
const decisionFirmnessStep = migrationSteps.some((step) => step.id === "decision-firmness-v9");
|
|
542
565
|
const firmnessFromOriginStep = migrationSteps.some((step) => step.id === "firmness-from-origin-v10");
|
|
566
|
+
const evidenceFloorStep = migrationSteps.some((step) => step.id === "evidence-floor-v11");
|
|
567
|
+
const { applyEvidenceFloorPins, planEvidenceFloorPins, readLadderFloorVerdicts, } = await import("../operations/migration/evidence-floor.js");
|
|
568
|
+
// Read before any source rewrite: the store still holds the KB as it was,
|
|
569
|
+
// and the floors are judged by the same ladder kibi check applies.
|
|
570
|
+
const ladderFloors = evidenceFloorStep
|
|
571
|
+
? await readLadderFloorVerdicts(cwd)
|
|
572
|
+
: null;
|
|
573
|
+
const claimBindingStep = migrationSteps.some((step) => step.id === "claim-bound-proofs-v12");
|
|
574
|
+
const { applyProofContractClaimPins, planProofContractClaimPins, readProofContractClaimCandidates, } = await import("../operations/migration/proof-contract-claims.js");
|
|
575
|
+
const claimCandidates = claimBindingStep
|
|
576
|
+
? await readProofContractClaimCandidates(cwd)
|
|
577
|
+
: null;
|
|
543
578
|
const { mergeSupersedesAcknowledgements, planSupersedesReasonAcknowledgement, } = await import("../operations/migration/supersedes-reason.js");
|
|
544
579
|
const { mergeFirmSupersedeAcknowledgements, planFirmSupersedeAcknowledgement, } = await import("../operations/migration/firm-supersede.js");
|
|
545
580
|
const { acknowledgedContextIds, applyContextMissingTags, applySemanticTextPins, countByType, planContextMissingTags, planSemanticTextPins, } = await import("../operations/migration/entity-body-context.js");
|
|
@@ -568,6 +603,23 @@ export async function migrateCommand(options = {}) {
|
|
|
568
603
|
if (firmEdges.length > 0)
|
|
569
604
|
console.log(`dry run: would acknowledge ${firmEdges.length} supersede(s) of decisions that read as firm from schema 10 (manifest only; no firmness is written).`);
|
|
570
605
|
}
|
|
606
|
+
if (evidenceFloorStep) {
|
|
607
|
+
const floors = planEvidenceFloorPins(cwd, ladderFloors);
|
|
608
|
+
if (floors.targets.length > 0)
|
|
609
|
+
console.log(`dry run: would record required_evidence: asserted on ${floors.targets.length} current firm requirement(s) whose evidence is below tested (front matter only).`);
|
|
610
|
+
if (floors.kept.length > 0)
|
|
611
|
+
console.log(floors.decidedBy === "ladder"
|
|
612
|
+
? `dry run: ${floors.kept.length} firm requirement(s) keep the tested floor (${floors.kept.join(", ")}); the evidence ladder on the synced store accepts each, or needs only kibi prove re-run.`
|
|
613
|
+
: `dry run: ${floors.kept.length} firm requirement(s) keep the tested floor (${floors.kept.join(", ")}) because their latest end-to-end receipt passed; no synced store could be read, so other proof gaps were not judged. Run kibi sync and rerun the dry run for the ladder's verdict.`);
|
|
614
|
+
for (const skip of floors.skipped)
|
|
615
|
+
printWarning(`Cannot edit ${skip.path}: ${skip.reason}.`);
|
|
616
|
+
}
|
|
617
|
+
if (claimBindingStep) {
|
|
618
|
+
const claims = planProofContractClaimPins(cwd, claimCandidates);
|
|
619
|
+
if (claims.targets.length > 0)
|
|
620
|
+
console.log(`dry run: would pin proof_contract.proves on ${claims.targets.length} certificate test(s) whose test reaches exactly one provable claim (${claims.targets.map((target) => target.id).join(", ")}); front matter only.`);
|
|
621
|
+
printClaimBindingReview(claims, claimCandidates === null, true);
|
|
622
|
+
}
|
|
571
623
|
if (storagePlan.moves.length > 0) {
|
|
572
624
|
console.log(`dry run: would move ${storagePlan.moves.length} legacy knowledge file(s) into .kb/:`);
|
|
573
625
|
for (const move of storagePlan.moves) {
|
|
@@ -655,6 +707,15 @@ export async function migrateCommand(options = {}) {
|
|
|
655
707
|
const firmSupersedes = firmnessFromOriginStep
|
|
656
708
|
? planFirmSupersedeAcknowledgement(cwd)
|
|
657
709
|
: [];
|
|
710
|
+
const evidenceFloorPlan = evidenceFloorStep
|
|
711
|
+
? planEvidenceFloorPins(cwd, ladderFloors)
|
|
712
|
+
: null;
|
|
713
|
+
const evidenceFloorsPinned = evidenceFloorStep
|
|
714
|
+
? applyEvidenceFloorPins(cwd, ladderFloors)
|
|
715
|
+
: 0;
|
|
716
|
+
const claimPins = claimBindingStep
|
|
717
|
+
? applyProofContractClaimPins(cwd, claimCandidates)
|
|
718
|
+
: null;
|
|
658
719
|
const existingManifest = readKbManifest(cwd) ?? defaultKbManifest();
|
|
659
720
|
writeKbManifest(cwd, {
|
|
660
721
|
...existingManifest,
|
|
@@ -685,6 +746,19 @@ export async function migrateCommand(options = {}) {
|
|
|
685
746
|
console.log(`Acknowledged ${supersedesUnexplained.length} supersede(s) recorded without a 'Why this changed' section; new supersedes must explain themselves.`);
|
|
686
747
|
if (firmSupersedes.length > 0)
|
|
687
748
|
console.log(`Acknowledged ${firmSupersedes.length} supersede(s) of decisions without firmness that read as firm from schema 10; a new replacement of such a decision must be firm.`);
|
|
749
|
+
if (evidenceFloorsPinned > 0)
|
|
750
|
+
console.log(`Recorded required_evidence: asserted on ${evidenceFloorsPinned} current firm requirement(s) whose evidence is below tested; raise it to tested once the requirement has an end-to-end proof.`);
|
|
751
|
+
if ((evidenceFloorPlan?.kept.length ?? 0) > 0)
|
|
752
|
+
console.log(evidenceFloorPlan?.decidedBy === "ladder"
|
|
753
|
+
? `${evidenceFloorPlan?.kept.length} firm requirement(s) keep the tested floor; the evidence ladder accepts each, or needs only kibi prove re-run (kibi check --fresh-evidence lists those).`
|
|
754
|
+
: `${evidenceFloorPlan?.kept.length} firm requirement(s) keep the tested floor because their latest end-to-end receipt passed; no synced store could be read, so run kibi sync and kibi check --rules evidence-floor to list any whose proof has other gaps (kibi proof explain <id> names them).`);
|
|
755
|
+
for (const skip of evidenceFloorPlan?.skipped ?? [])
|
|
756
|
+
printWarning(`Cannot record required_evidence on ${skip.path}: ${skip.reason}.`);
|
|
757
|
+
if (claimPins !== null) {
|
|
758
|
+
if (claimPins.targets.length > 0)
|
|
759
|
+
console.log(`Pinned proof_contract.proves on ${claimPins.targets.length} certificate test(s) (${claimPins.targets.map((target) => target.id).join(", ")}); run kibi prove for them so their receipts bind the claim.`);
|
|
760
|
+
printClaimBindingReview(claimPins, claimCandidates === null, false);
|
|
761
|
+
}
|
|
688
762
|
await refreshMigratedSymbolCoordinates(cwd, generatedManifestsBefore);
|
|
689
763
|
const auditRecord = buildMigrationAuditRecord({
|
|
690
764
|
branch,
|
|
@@ -722,7 +796,7 @@ export async function migrateCommand(options = {}) {
|
|
|
722
796
|
console.log("Migration complete. Future 'kibi migrate' runs will be a no-op.");
|
|
723
797
|
const mergeDriverGaps = manifestMergeDriverGaps(cwd);
|
|
724
798
|
if (mergeDriverGaps !== null && mergeDriverGaps.length > 0) {
|
|
725
|
-
console.log(`Tip: kibi merge-driver resolves .kb/symbols.yaml merges by record id, but it is not wired up (${mergeDriverGaps.join("; ")}). ${
|
|
799
|
+
console.log(`Tip: kibi merge-driver resolves .kb/symbols.yaml merges by record id, but it is not wired up (${mergeDriverGaps.join("; ")}). ${mergeDriverSetup(cwd)}`);
|
|
726
800
|
}
|
|
727
801
|
const gitignoreUpdated = updateGitIgnore(cwd);
|
|
728
802
|
return {
|
|
@@ -770,9 +844,21 @@ async function buildWorkspaceMigrationPlan(workspaceRoot = process.cwd()) {
|
|
|
770
844
|
const currentSchemaVersion = status?.schemaStatus?.currentVersion ??
|
|
771
845
|
readKbManifest(workspaceRoot)?.schemaVersion ??
|
|
772
846
|
null;
|
|
847
|
+
const { EVIDENCE_FLOOR_SCHEMA_VERSION } = await import("../public/operations/evidence-floor.js");
|
|
848
|
+
const { readLadderFloorVerdicts } = await import("../operations/migration/evidence-floor.js");
|
|
849
|
+
const { CLAIM_BINDING_SCHEMA_VERSION } = await import("../public/operations/proof-contract-claims.js");
|
|
850
|
+
const { readProofContractClaimCandidates } = await import("../operations/migration/proof-contract-claims.js");
|
|
773
851
|
const fragment = buildSchema6MigrationFragment({
|
|
774
852
|
workspaceRoot,
|
|
775
853
|
currentSchemaVersion,
|
|
854
|
+
ladderFloors: currentSchemaVersion === null ||
|
|
855
|
+
currentSchemaVersion < EVIDENCE_FLOOR_SCHEMA_VERSION
|
|
856
|
+
? await readLadderFloorVerdicts(workspaceRoot)
|
|
857
|
+
: null,
|
|
858
|
+
claimCandidates: currentSchemaVersion === null ||
|
|
859
|
+
currentSchemaVersion < CLAIM_BINDING_SCHEMA_VERSION
|
|
860
|
+
? await readProofContractClaimCandidates(workspaceRoot)
|
|
861
|
+
: null,
|
|
776
862
|
});
|
|
777
863
|
const fragmentActions = [...fragment.actions];
|
|
778
864
|
const statusActions = status?.migrationPlan?.actions ?? [];
|
|
@@ -944,7 +1030,7 @@ function printApplySummary(content) {
|
|
|
944
1030
|
}
|
|
945
1031
|
const remaining = result.remainingPlan;
|
|
946
1032
|
if (remaining !== undefined) {
|
|
947
|
-
const ready = remaining.
|
|
1033
|
+
const ready = remaining.automaticSummary.ready;
|
|
948
1034
|
console.log(`Remaining plan ${remaining.planHash}: ${remaining.status}; actions: ${remaining.summary.actionCount}; automatic-ready: ${ready}`);
|
|
949
1035
|
}
|
|
950
1036
|
console.log("Run 'kibi migrate' for the remaining actions, or add --format json for the full result.");
|
package/dist/commands/prove.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { executeIngestProof } from "../operations/proof/ingest-proof.js";
|
|
2
2
|
import { type ProofRunAttribution } from "../proof/command-test-report.js";
|
|
3
3
|
import type { ProofIntegration } from "../proof/integrations.js";
|
|
4
|
-
import type { OperationRuntime } from "../public/operations/runtime-types.js";
|
|
4
|
+
import type { OperationContext, OperationRuntime } from "../public/operations/runtime-types.js";
|
|
5
5
|
import { readWorkspaceSnapshot } from "../public/operations/workspace-snapshot.js";
|
|
6
6
|
import { type ProofRunArtifact } from "../public/proof-protocol.js";
|
|
7
7
|
export type ProveCommandOptions = Readonly<{
|
|
@@ -10,6 +10,10 @@ export type ProveCommandOptions = Readonly<{
|
|
|
10
10
|
integration?: string;
|
|
11
11
|
integrationExcept?: string;
|
|
12
12
|
all?: boolean;
|
|
13
|
+
/** Keep only selected tests without a current passing receipt. */
|
|
14
|
+
stale?: boolean;
|
|
15
|
+
/** Skip integrations an interrupted run already ingested at this snapshot. */
|
|
16
|
+
resume?: boolean;
|
|
13
17
|
workspaceRoot?: string;
|
|
14
18
|
}>;
|
|
15
19
|
export type ProveCommandDependencies = Readonly<{
|
|
@@ -31,10 +35,53 @@ export declare function describeWorkspaceDrift(snapshot: Awaited<ReturnType<type
|
|
|
31
35
|
*/
|
|
32
36
|
export declare function parseIntegrationSelector(value: string | undefined, flagName: string): Set<string>;
|
|
33
37
|
export declare function testId(test: SelectedTest): string;
|
|
38
|
+
/** Run a proof integration's command and resolve with its exit code. */
|
|
39
|
+
export declare function runChild(commandArgv: readonly string[], cwd: string, env: NodeJS.ProcessEnv): Promise<number>;
|
|
34
40
|
export declare function commandEnvironment(integration: ProofIntegration, commandArgv: readonly string[], snapshot: string, workspaceRoot: string, testIds: readonly string[], outputPath: string): NodeJS.ProcessEnv;
|
|
41
|
+
/** Where `kibi prove` records which integrations it has ingested. */
|
|
42
|
+
export declare const PROVE_PROGRESS_FILE = "prove-progress.json";
|
|
43
|
+
type ProveProgress = {
|
|
44
|
+
version: "kibi.prove-progress.v1";
|
|
45
|
+
snapshot: string;
|
|
46
|
+
/** Integration id to the test ids whose receipts it wrote. */
|
|
47
|
+
ingested: Record<string, string[]>;
|
|
48
|
+
};
|
|
49
|
+
/** Read the progress file; anything unreadable counts as no progress. */
|
|
50
|
+
export declare function readProveProgress(runsDir: string): Promise<ProveProgress | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Integrations a resumed run can skip: ingested at the same snapshot, for
|
|
53
|
+
* every test this run selects for them.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resumableIntegrations(progress: ProveProgress | null, snapshot: string, groups: ReadonlyMap<string, readonly SelectedTest[]>): Set<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Narrow a Playwright integration's command to the spec files the selected
|
|
58
|
+
* tests are bound to, so `kibi prove --test X` runs X's specs instead of the
|
|
59
|
+
* whole suite. Only a direct `playwright test` invocation is narrowed, and
|
|
60
|
+
* only when every selected test names its `proof_bindings[].source_file`;
|
|
61
|
+
* otherwise the command runs unchanged and the reason says why.
|
|
62
|
+
*/
|
|
63
|
+
export declare function narrowedPlaywrightCommand(command: readonly string[], tests: readonly SelectedTest[]): {
|
|
64
|
+
argv: string[];
|
|
65
|
+
narrowed: boolean;
|
|
66
|
+
reason?: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Receipt state per proof-bearing test under the binding mode reports use.
|
|
70
|
+
* `passed` means the test already has a current passing receipt; anything
|
|
71
|
+
* else (missing, stale, contract_mismatch, invalid, failed) needs a run.
|
|
72
|
+
*/
|
|
73
|
+
export declare function readTestReceiptStates(context: OperationContext): Promise<ReadonlyMap<string, string>>;
|
|
35
74
|
export declare function proveCommand(options: ProveCommandOptions, deps?: ProveCommandDependencies): Promise<{
|
|
36
75
|
exitCode: number;
|
|
37
76
|
}>;
|
|
77
|
+
/** Read every certificate a run left in its certificate directory. */
|
|
78
|
+
export declare function readCertificateDir(directory: string): Promise<Record<string, unknown>[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Give each artifact the certificates of its own tests, so a partition is
|
|
81
|
+
* never evaluated against another test's certificate. A test may leave at
|
|
82
|
+
* most one certificate per run.
|
|
83
|
+
*/
|
|
84
|
+
export declare function attachCertificates(evaluated: EvaluatedRun, certificates: readonly Record<string, unknown>[]): EvaluatedRun;
|
|
38
85
|
/** The artifacts one integration run is evaluated through. */
|
|
39
86
|
export type EvaluatedRun = Readonly<{
|
|
40
87
|
/** Each artifact is ingested against exactly its own tests. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,EAIL,KAAK,mBAAmB,EAGzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"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"}
|