kibi-cli 2.15.0 → 2.16.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.
Files changed (60) hide show
  1. package/dist/cli-register-proof.d.ts.map +1 -1
  2. package/dist/cli-register-proof.js +16 -2
  3. package/dist/commands/check.d.ts.map +1 -1
  4. package/dist/commands/check.js +5 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +83 -4
  7. package/dist/commands/prove.js +1 -1
  8. package/dist/operations/modeling/model-requirement.d.ts +5 -0
  9. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  10. package/dist/operations/modeling/model-requirement.js +17 -5
  11. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  12. package/dist/operations/modeling/predicate-applyplan.js +16 -6
  13. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  14. package/dist/operations/planning/apply-plan.js +15 -0
  15. package/dist/proof/inspect.d.ts +18 -1
  16. package/dist/proof/inspect.d.ts.map +1 -1
  17. package/dist/proof/inspect.js +17 -8
  18. package/dist/proof/integration-plan.d.ts +57 -0
  19. package/dist/proof/integration-plan.d.ts.map +1 -0
  20. package/dist/proof/integration-plan.js +331 -0
  21. package/dist/proof/integrations.js +1 -1
  22. package/dist/public/operations/catalog.d.ts +2 -2
  23. package/dist/public/operations/check-executor.d.ts +16 -0
  24. package/dist/public/operations/check-executor.d.ts.map +1 -1
  25. package/dist/public/operations/check-executor.js +80 -0
  26. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  27. package/dist/public/operations/discovery-executors.js +13 -3
  28. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  29. package/dist/public/operations/migration-plan.js +28 -0
  30. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  31. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  32. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  33. package/dist/public/operations/specs/check.d.ts +1 -1
  34. package/dist/public/operations/specs/composite.d.ts +16 -3
  35. package/dist/public/operations/specs/composite.d.ts.map +1 -1
  36. package/dist/public/operations/specs/composite.js +79 -2
  37. package/dist/public/operations/specs/modeling.d.ts +1 -1
  38. package/dist/public/operations/specs/modeling.js +1 -1
  39. package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -1
  40. package/dist/public/skills/kibi-usage/SKILL.md +14 -6
  41. package/dist/public/skills/kibi-usage/resources/proof.md +15 -3
  42. package/dist/utils/branch-store.d.ts +32 -0
  43. package/dist/utils/branch-store.d.ts.map +1 -1
  44. package/dist/utils/branch-store.js +122 -1
  45. package/dist/utils/rule-registry.generated.d.ts +5 -0
  46. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  47. package/dist/utils/rule-registry.generated.js +6 -0
  48. package/dist/utils/strict-modeling.d.ts +12 -0
  49. package/dist/utils/strict-modeling.d.ts.map +1 -1
  50. package/dist/utils/strict-modeling.js +12 -1
  51. package/package.json +2 -2
  52. package/src/public/operations/check-executor.ts +105 -0
  53. package/src/public/operations/discovery-executors.ts +19 -2
  54. package/src/public/operations/migration-plan.ts +35 -0
  55. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  56. package/src/public/operations/specs/composite.ts +110 -11
  57. package/src/public/operations/specs/modeling.ts +1 -1
  58. package/src/public/skills/kibi-bootstrap/SKILL.md +2 -1
  59. package/src/public/skills/kibi-usage/SKILL.md +14 -6
  60. package/src/public/skills/kibi-usage/resources/proof.md +15 -3
@@ -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,CAsL3D"}
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,CA6L3D"}
@@ -39,10 +39,11 @@ export function registerProofCommand(program) {
39
39
  .description("Inspect proof integration and maintain proof evidence");
40
40
  proof
41
41
  .command("inspect")
42
- .description("Detect test infrastructure and recommend the strongest available proof integration")
42
+ .description("Detect test infrastructure, propose a proof integration and return the reviewed plan that writes .kb/proof/integrations.json")
43
+ .option("--update <id>", "Plan adding or replacing this integration in an existing .kb/proof/integrations.json")
43
44
  .option("--json", "Emit structured JSON", false)
44
45
  .action(withExitCode(async (options) => {
45
- const result = await (await import("./proof/inspect.js")).inspectProofEnvironment(process.cwd());
46
+ const result = await (await import("./proof/inspect.js")).inspectProofEnvironment(process.cwd(), options.update === undefined ? {} : { update: options.update });
46
47
  if (options.json) {
47
48
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
48
49
  return undefined;
@@ -136,5 +137,18 @@ function renderInspection(result) {
136
137
  for (const entry of inspection.missing)
137
138
  lines.push(` - ${entry}`);
138
139
  }
140
+ if (inspection.proposedIntegration) {
141
+ const proposed = inspection.proposedIntegration;
142
+ lines.push("");
143
+ lines.push(`Proposed integration: ${proposed.id} (${proposed.producer}: ${proposed.command.join(" ")})`);
144
+ }
145
+ if (inspection.integrationPlan) {
146
+ const plan = inspection.integrationPlan;
147
+ lines.push(`Integration plan: ${plan.planHash.slice(0, 12)} (actions: ${plan.actions.map((action) => action.id).join(", ")}); rerun with --json for the plan to pass to kb_apply_plan.`);
148
+ }
149
+ else if (inspection.integrationPlanReason) {
150
+ lines.push("");
151
+ lines.push(`Integration plan: none. ${inspection.integrationPlanReason}`);
152
+ }
139
153
  return `${lines.join("\n")}\n`;
140
154
  }
@@ -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;AA8E7C,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;CAC1B;AA8gBD,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,CA0nB/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;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CA+BtB"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA8E7C,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;CAC1B;AA8gBD,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,CA8nB/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;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CA+BtB"}
@@ -885,7 +885,11 @@ export async function checkCommand(options) {
885
885
  invalidateCache: () => activeProlog.invalidateCache(),
886
886
  save: () => activeProlog.query("kb_save"),
887
887
  },
888
- }, { collectFullQualityDiagnosticsForExplicitRules: true });
888
+ }, {
889
+ collectFullQualityDiagnosticsForExplicitRules: true,
890
+ // The engine reads the branch store; an explicit --kb-path does not.
891
+ branchStoreAttached: options.kbPath === undefined,
892
+ });
889
893
  const violations = result.structuredContent?.violations ?? [];
890
894
  const qualityDiagnostics = result.structuredContent?.qualityDiagnostics ?? [];
891
895
  if (options.format === "json") {
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAiFA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAoG/B;AAED,wBAAsB,4BAA4B,CAChD,IAAI,GAAE,MAAM,OAAO,CAAC;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,CACT,GACxC,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;;;MAkE3C;AAkGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGzE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAepB"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AA2FA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmH/B;AAED,wBAAsB,4BAA4B,CAChD,IAAI,GAAE,MAAM,OAAO,CAAC;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,CACT,GACxC,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;;;MAkE3C;AAkGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGzE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAepB"}
@@ -25,7 +25,8 @@ import { kibiPackageVersions } from "../package-versions.js";
25
25
  import { describeConfiguredCapabilityPlugins, readProjectKibiConfig, } from "../plugins/project-config.js";
26
26
  import { SwiplResolutionError, inspectSwiplBundle, probeRequiredLibraries, resolveSwipl, } from "../prolog/swipl-resolver.js";
27
27
  import { buildMigrationPlan, migrationAction, } from "../public/operations/migration-plan.js";
28
- import { resolveReadBranchAttachment } from "../utils/branch-resolver.js";
28
+ import { resolveBranchAttachment, resolveReadBranchAttachment, } from "../utils/branch-resolver.js";
29
+ import { branchStoreCompilation, inspectBranchStore, uncompiledBranchStoreReason, } from "../utils/branch-store.js";
29
30
  import { resolveGitRepository, } from "../utils/git-repository-context.js";
30
31
  import { readKbManifestStatus } from "../utils/kb-manifest.js";
31
32
  import { hasManagedHooks, outdatedManagedHooks } from "./init-helpers.js";
@@ -68,6 +69,10 @@ export async function doctorCommand(options = {}) {
68
69
  name: "Git repository",
69
70
  check: checkGitRepository,
70
71
  },
72
+ {
73
+ name: "Branch store",
74
+ check: checkBranchStore,
75
+ },
71
76
  {
72
77
  name: "Git hooks",
73
78
  check: checkGitHooks,
@@ -98,6 +103,7 @@ export async function doctorCommand(options = {}) {
98
103
  results.push({ name, ...(await check()) });
99
104
  }
100
105
  const allPassed = results.every((result) => result.passed);
106
+ const warnings = results.filter((result) => result.passed && result.warning === true).length;
101
107
  const runtime = await runtimeProvenance();
102
108
  const packageActions = await packageMigrationActions(runtime);
103
109
  const migrationPlan = buildMigrationPlan({
@@ -113,6 +119,7 @@ export async function doctorCommand(options = {}) {
113
119
  console.log(JSON.stringify({
114
120
  version: "kibi.doctor.v1",
115
121
  passed: allPassed,
122
+ warnings,
116
123
  runtime,
117
124
  checks: results,
118
125
  migrationPlan,
@@ -121,12 +128,17 @@ export async function doctorCommand(options = {}) {
121
128
  }
122
129
  console.log("Kibi Environment Diagnostics\n");
123
130
  for (const result of results) {
124
- const status = result.passed ? "✓" : "✗";
131
+ const warned = result.passed && result.warning === true;
132
+ const status = !result.passed ? "✗" : warned ? "!" : "✓";
125
133
  console.log(`${status} ${result.name}: ${result.message}`);
126
- if (!result.passed && result.remediation)
134
+ if ((!result.passed || warned) && result.remediation)
127
135
  console.log(` → ${result.remediation}`);
128
136
  }
129
137
  console.log();
138
+ if (allPassed && warnings > 0) {
139
+ console.log(`All required checks passed, with ${warnings} warning(s) above (marked !).`);
140
+ return { exitCode: 0 };
141
+ }
130
142
  if (allPassed) {
131
143
  console.log("All checks passed! Your environment is ready.");
132
144
  return { exitCode: 0 };
@@ -644,6 +656,68 @@ function checkGitRepository() {
644
656
  };
645
657
  }
646
658
  }
659
+ /**
660
+ * The current branch's KB store: it must exist and hold a compilation
661
+ * (journal sequence above 0) when .kb/ has authored sources. Kibi stores are
662
+ * per branch and never copied, so a branch created without the post-checkout
663
+ * hook starts empty until `kibi sync`.
664
+ */
665
+ // implements REQ-cli-doctor
666
+ function checkBranchStore() {
667
+ const workspaceRoot = process.cwd();
668
+ let attachment;
669
+ try {
670
+ attachment = resolveBranchAttachment(workspaceRoot);
671
+ }
672
+ catch (error) {
673
+ attachment = {
674
+ error: error instanceof Error ? error.message : String(error),
675
+ };
676
+ }
677
+ if ("error" in attachment) {
678
+ return {
679
+ passed: true,
680
+ message: `Not checked: no current Git branch (${attachment.error})`,
681
+ };
682
+ }
683
+ const branch = attachment.kbBranch;
684
+ const store = inspectBranchStore(workspaceRoot, branch);
685
+ const details = { branch, path: store.path, state: store.state };
686
+ if (store.state === "incomplete" || store.state === "unreadable") {
687
+ return {
688
+ passed: false,
689
+ message: `Store for ${branch} is ${store.state}: ${store.detail ?? store.errorCode ?? "requires recovery"}`,
690
+ remediation: "Run: kibi branch recover, then kibi branch recover --apply",
691
+ details,
692
+ };
693
+ }
694
+ const compilation = branchStoreCompilation(store);
695
+ if (compilation.compiled) {
696
+ return {
697
+ passed: true,
698
+ message: `Compiled for ${branch}${compilation.generation ? ` (${compilation.generation})` : ""}`,
699
+ details: { ...details, generation: compilation.generation },
700
+ };
701
+ }
702
+ const reason = uncompiledBranchStoreReason(workspaceRoot, store, branch);
703
+ if (reason === null) {
704
+ return {
705
+ passed: true,
706
+ message: `Not compiled yet for ${branch}; .kb/ holds no authored sources`,
707
+ details,
708
+ };
709
+ }
710
+ return {
711
+ passed: false,
712
+ message: String(reason.detail),
713
+ remediation: "Run: kibi sync",
714
+ details: {
715
+ ...details,
716
+ generation: compilation.generation,
717
+ authoredSources: reason.authoredSources,
718
+ },
719
+ };
720
+ }
647
721
  // Hook health must be diagnosed against the hooks directory Git actually
648
722
  // executes (resolved via git rev-parse --git-path hooks, honoring
649
723
  // core.hooksPath and linked worktrees), not against <cwd>/.git/hooks.
@@ -720,10 +794,15 @@ function checkGitHooks() {
720
794
  const postMergeExists = existsSync(postMergePath);
721
795
  // An existing pre-commit is hard enforcement; the companions being absent
722
796
  // must not downgrade the summary to "optional".
797
+ // implements REQ-cli-doctor
798
+ // Without the hooks kibi init installs, a new branch starts with an empty
799
+ // store (post-checkout compiles it) and commits skip kibi check --staged.
723
800
  if (!postCheckoutExists && !postMergeExists && !existsSync(preCommitPath)) {
724
801
  return {
725
802
  passed: true,
726
- message: `Not installed (optional)${hooksPathSuffix()}`,
803
+ warning: true,
804
+ message: `Not installed: a new branch is not compiled on checkout and commits skip 'kibi check --staged'${hooksPathSuffix()}`,
805
+ remediation: "Run: kibi init (installs the git hooks)",
727
806
  };
728
807
  }
729
808
  if (postCheckoutExists && postMergeExists) {
@@ -279,7 +279,7 @@ export async function proveCommand(options, deps = {}) {
279
279
  for (const [integrationId, tests] of groups) {
280
280
  const integration = resolveIntegration(integrations.integrations, integrationId);
281
281
  if (!integration) {
282
- failures.push(`integration '${integrationId}' (required by ${tests.map((t) => t.id).join(", ")}) is not configured in .kb/proof/integrations.json`);
282
+ failures.push(`integration '${integrationId}' (required by ${tests.map((t) => t.id).join(", ")}) is not configured in .kb/proof/integrations.json; plan it with kibi proof inspect --update ${integrationId} --json and apply the plan with kb_apply_plan`);
283
283
  continue;
284
284
  }
285
285
  const commandArgv = [...integration.command];
@@ -1,8 +1,13 @@
1
+ import { type StrictWriteSet } from "../../public/check-types.js";
1
2
  import type { OperationContext } from "../../public/operations/runtime-types.js";
2
3
  import { strictWriteSetToApplyPlan, writeSetPrimaryEntityId } from "./requirement-applyplan.js";
3
4
  import { estimateNormativeSignalConfidence, extractRequirementClaim } from "./requirement-modeler.js";
4
5
  import type { ModelRequirementArgs, ModelRequirementResult } from "./requirement-types.js";
5
6
  export type { ModelRequirementArgs, ModelRequirementResult, } from "./requirement-types.js";
7
+ export declare function reuseExistingSubject(writeSet: StrictWriteSet, existingFactId: string): {
8
+ writeSet: StrictWriteSet;
9
+ replacedSubjectId: string | null;
10
+ };
6
11
  export { estimateNormativeSignalConfidence, extractRequirementClaim, strictWriteSetToApplyPlan, writeSetPrimaryEntityId, };
7
12
  export declare function annotateModelRequirementStep(step: Record<string, unknown>, context: {
8
13
  claimKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAgBjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAUhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAkNhC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAIF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GACA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+CzB;AAwOD,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAgHjC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAajC"}
1
+ {"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAiBjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAUhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAuBhC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,MAAM,GACrB;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAuBhE;AA2KD,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAIF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GACA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+CzB;AAwOD,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAwHjC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAajC"}
@@ -1,6 +1,6 @@
1
1
  import { buildStrictWriteSet, } from "../../public/check-types.js";
2
2
  import { readKbManifestStatus } from "../../utils/kb-manifest.js";
3
- import { isConventionalSubjectKey, normalizeSubjectKey, } from "../../utils/strict-modeling.js";
3
+ import { factSourcePath, isConventionalSubjectKey, normalizeSubjectKey, } from "../../utils/strict-modeling.js";
4
4
  import { modeledClaimRole, normalizeSemanticClause, semanticClaimKey, } from "../semantic-advisor/clauses.js";
5
5
  import { detectConditionalRule } from "../semantic-advisor/conditional-rules.js";
6
6
  import { advisorPropositionRole } from "../semantic-advisor/proposition-role.js";
@@ -11,7 +11,10 @@ import { estimateNormativeSignalConfidence, extractRequirementClaim, } from "./r
11
11
  import { normalizeOptionalString, normalizeSourceFiles, } from "./requirement-utils.js";
12
12
  import { alignRequirementVocabulary, } from "./vocabulary-alignment.js";
13
13
  const NEW_SUBJECT_REVIEW_SCORE = 0.3;
14
- function reuseExistingSubject(writeSet, existingFactId) {
14
+ // implements REQ-kibi-subject-vocabulary
15
+ // The write set describes the existing subject fact, so its id and its source
16
+ // both name that fact; the minted fact (and its file) is never created.
17
+ export function reuseExistingSubject(writeSet, existingFactId) {
15
18
  if (!writeSet.isStrict)
16
19
  return { writeSet, replacedSubjectId: null };
17
20
  const replacedSubjectId = writeSet.subjectFact.id;
@@ -22,7 +25,11 @@ function reuseExistingSubject(writeSet, existingFactId) {
22
25
  subjectFact: {
23
26
  ...writeSet.subjectFact,
24
27
  id: existingFactId,
25
- properties: { ...writeSet.subjectFact.properties, id: existingFactId },
28
+ properties: {
29
+ ...writeSet.subjectFact.properties,
30
+ id: existingFactId,
31
+ source: factSourcePath(existingFactId),
32
+ },
26
33
  },
27
34
  relationships: writeSet.relationships.map((relationship) => relationship.type === "constrains"
28
35
  ? { ...relationship, to: existingFactId }
@@ -57,10 +64,11 @@ function possibleDuplicateObservation(claimKey, statement, source, candidates) {
57
64
  * when the keys match. Otherwise the plan explicitly declares a new subject.
58
65
  */
59
66
  // implements REQ-kibi-subject-vocabulary
60
- async function applyVocabularyAlignment(context, extracted, claimKey) {
67
+ async function applyVocabularyAlignment(context, extracted, claimKey, requirementId) {
61
68
  const initial = buildStrictWriteSet({
62
69
  claim: extracted.claim,
63
70
  statement: extracted.statement,
71
+ ...(requirementId !== undefined ? { requirementId } : {}),
64
72
  });
65
73
  const unchanged = {
66
74
  writeSet: initial,
@@ -90,6 +98,7 @@ async function applyVocabularyAlignment(context, extracted, claimKey) {
90
98
  const rebuilt = buildStrictWriteSet({
91
99
  claim: { ...extracted.claim, subjectKey: subject.subjectKey },
92
100
  statement: extracted.statement,
101
+ ...(requirementId !== undefined ? { requirementId } : {}),
93
102
  });
94
103
  ({ writeSet, replacedSubjectId } = reuseExistingSubject(rebuilt, subject.existingFactId));
95
104
  }
@@ -431,7 +440,10 @@ export async function handleKbModelRequirement(_prolog, args, workspaceRoot, con
431
440
  if (conditional?.kind === "unparsed")
432
441
  return unresolvedConditionalResult(args, extracted, conditional.reason, workspaceRoot);
433
442
  const claimKey = semanticClaimKey(extracted.statement);
434
- const aligned = await applyVocabularyAlignment(context, extracted, claimKey);
443
+ // implements REQ-kibi-subject-vocabulary
444
+ // A caller-named requirement keeps its id: the strict write set updates it
445
+ // instead of minting REQ-AUTO-<hash>.
446
+ const aligned = await applyVocabularyAlignment(context, extracted, claimKey, normalizeOptionalString(args.requirementId));
435
447
  const writeSet = aligned.writeSet;
436
448
  const logicClaims = Array.from(new Set([...(args.existingLogicClaims ?? []), claimKey]));
437
449
  const plan = aligned.adjustPlan(strictWriteSetToApplyPlan(writeSet));
@@ -1 +1 @@
1
- {"version":3,"file":"predicate-applyplan.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/predicate-applyplan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAEV,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAQ9B,wBAAgB,eAAe,CAC7B,MAAM,EAAE,wBAAwB,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,gBAAgB,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EACvD,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,EAChC,WAAW,CAAC,EAAE;IACZ,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,GACA,mBAAmB,CAgKrB;AAGD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,mBAAmB,EAC/B,IAAI,EAAE,qBAAqB,GAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0ChC;AAGD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,SAAS,CAAC,EAAE,MAAM,EAClB,mBAAmB,GAAE,SAAS,MAAM,EAAO,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAuBhC;AAoBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,qBAAqB,GAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwBhC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,0BAA0B,CAoE5B"}
1
+ {"version":3,"file":"predicate-applyplan.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/predicate-applyplan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAEV,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAQ9B,wBAAgB,eAAe,CAC7B,MAAM,EAAE,wBAAwB,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,gBAAgB,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EACvD,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,EAChC,WAAW,CAAC,EAAE;IACZ,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,GACA,mBAAmB,CA2KrB;AAGD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,mBAAmB,EAC/B,IAAI,EAAE,qBAAqB,GAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0ChC;AAGD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,SAAS,CAAC,EAAE,MAAM,EAClB,mBAAmB,GAAE,SAAS,MAAM,EAAO,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAuBhC;AAoBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,qBAAqB,GAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwBhC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,0BAA0B,CAoE5B"}
@@ -74,17 +74,27 @@ export function buildSuggestion(schema, text, subject, score, argumentBindings =
74
74
  constrainedSubjects,
75
75
  }),
76
76
  ]));
77
- // The subject the planned predicate fact is about, when the requirement
78
- // constrains subjects: the `subject` argument's value, or for a schema
79
- // without one the reviewed subject, recorded as the fact's subject_key.
80
- const subjectKey = constrainedSubjects.length === 0
77
+ // The subjects the planned predicate must be about: those the requirement
78
+ // constrains, or, for a requirement that is not written yet or constrains
79
+ // nothing, the explicit subjectHint. The hint is then the subject fact the
80
+ // agent is about to link, so the planned fact carries its subject_key and
81
+ // kb_check pairs the two once the requirement is written.
82
+ const plannedSubjects = constrainedSubjects.length > 0
83
+ ? constrainedSubjects
84
+ : explicitSubject
85
+ ? [subject]
86
+ : [];
87
+ // The subject the planned predicate fact is about: the `subject`
88
+ // argument's value, or for a schema without one the reviewed subject,
89
+ // recorded as the fact's subject_key.
90
+ const subjectKey = plannedSubjects.length === 0
81
91
  ? null
82
92
  : subjectArgument >= 0
83
93
  ? (predicateArgs[subjectArgument] ?? null)
84
94
  : (reviewedSubject ?? null);
85
- const subjectPairing = constrainedSubjects.length === 0
95
+ const subjectPairing = plannedSubjects.length === 0
86
96
  ? "not_required"
87
- : subjectKey !== null && constrainedSubjects.includes(subjectKey)
97
+ : subjectKey !== null && plannedSubjects.includes(subjectKey)
88
98
  ? "paired"
89
99
  : "unpaired";
90
100
  const bindingProvenance = aggregateBindingProvenance(Object.values(bindingProvenanceByArgument));
@@ -1 +1 @@
1
- {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/apply-plan.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAEV,gBAAgB,EAGjB,MAAM,0CAA0C,CAAC;AAQlD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AA+D/B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAGhB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,yBAAyB,EAAG,2BAAoC,CAAC;AA6G9E,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAMN;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,EACnE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,IAAI,CAaN;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,SAAS,cAAoB,GAC5B,eAAe,EAAE,CA2CnB;AA8zBD;;;;;;GAMG;AAEH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAyqDD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,eAAe,CAAC;CACpC,CAAC,CAkDD"}
1
+ {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/apply-plan.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAEV,gBAAgB,EAGjB,MAAM,0CAA0C,CAAC;AASlD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AA+D/B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAGhB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,yBAAyB,EAAG,2BAAoC,CAAC;AA6G9E,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAMN;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,EACnE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,IAAI,CAaN;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,SAAS,cAAoB,GAC5B,eAAe,EAAE,CA2CnB;AA8zBD;;;;;;GAMG;AAEH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAyqDD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,eAAe,CAAC;CACpC,CAAC,CAkDD"}
@@ -4,12 +4,14 @@ import { OperationError } from "../../cli-errors.js";
4
4
  import { branchEnsureCommand, branchMigrateCommand, branchRecoverCommand, } from "../../commands/branch.js";
5
5
  import { migrateCommand } from "../../commands/migrate.js";
6
6
  import { syncCommand } from "../../commands/sync.js";
7
+ import { PROOF_INTEGRATION_CONFIGURE, applyProofIntegrationAction, } from "../../proof/integration-plan.js";
7
8
  import { loadEntities } from "../../public/operations/discovery-entities.js";
8
9
  import { executeStatus } from "../../public/operations/discovery-executors.js";
9
10
  import { PREDICATE_SCHEMA_ALIGNMENT_CODE, migrationPlanHash, } from "../../public/operations/migration-plan.js";
10
11
  import { readMigrationConfigStatus } from "../../public/operations/migration-plan.js";
11
12
  import { readWorkspaceSnapshot } from "../../public/operations/workspace-snapshot.js";
12
13
  import { computeShardPath, renderShardWithRelationship, } from "../../relationships/shards.js";
14
+ import { BRANCH_STORE_NOT_COMPILED } from "../../utils/branch-store.js";
13
15
  import { canonicalFilesystemPath } from "../../utils/canonical-path.js";
14
16
  import { isDerivedKbPath } from "../../utils/kb-paths.js";
15
17
  import { bootstrapEmptyKbSnapshotId, bootstrapPlanHash, } from "../bootstrap/types.js";
@@ -2278,6 +2280,15 @@ async function applyMigrationAction(action, context) {
2278
2280
  case "missing_exact_branch_store":
2279
2281
  await branchEnsureCommand({ workspaceRoot: context.workspaceRoot });
2280
2282
  return;
2283
+ // implements REQ-cli-status-pre-first-sync
2284
+ case BRANCH_STORE_NOT_COMPILED: {
2285
+ const result = await syncCommand({
2286
+ workspaceRoot: context.workspaceRoot,
2287
+ });
2288
+ if (!result.success)
2289
+ throw new Error("Compiling the branch store (kibi sync) did not complete successfully.");
2290
+ return;
2291
+ }
2281
2292
  case "damaged_exact_branch_store":
2282
2293
  await branchRecoverCommand({
2283
2294
  apply: true,
@@ -2307,6 +2318,10 @@ async function applyMigrationAction(action, context) {
2307
2318
  case PREDICATE_SCHEMA_ALIGNMENT_CODE:
2308
2319
  await applyPredicateSchemaAlignment(action, context);
2309
2320
  return;
2321
+ // implements REQ-kibi-verification-evidence-contract
2322
+ case PROOF_INTEGRATION_CONFIGURE:
2323
+ applyProofIntegrationAction(action, context.workspaceRoot);
2324
+ return;
2310
2325
  default:
2311
2326
  if (SCHEMA6_AUTOMATIC_CODES.has(action.code)) {
2312
2327
  await applySchema6MigrationAction(action, context);
@@ -1,3 +1,5 @@
1
+ import type { MigrationPlan } from "../public/operations/migration-plan.js";
2
+ import { type ProposedIntegration } from "./integration-plan.js";
1
3
  export type ProofInspection = Readonly<{
2
4
  languages: readonly string[];
3
5
  buildSystems: readonly string[];
@@ -6,7 +8,22 @@ export type ProofInspection = Readonly<{
6
8
  currentIntegration: string | null;
7
9
  recommendation: string;
8
10
  missing: readonly string[];
11
+ /** The integration Kibi proposes for the detected runner, if any. */
12
+ proposedIntegration: ProposedIntegration["integration"] | null;
13
+ /** What a proof-bearing test's proof_contract names for that integration. */
14
+ contractDefaults: ProposedIntegration["contractDefaults"] | null;
15
+ /**
16
+ * Hash-bound kibi.migration-plan.v2 that writes the integrations file;
17
+ * review it, then apply it with kb_apply_plan / `kibi apply-plan`.
18
+ */
19
+ integrationPlan: MigrationPlan | null;
20
+ /** Why there is no plan, or what applying it does. */
21
+ integrationPlanReason: string;
22
+ }>;
23
+ export type ProofInspectionOptions = Readonly<{
24
+ /** Plan a replacement of this existing integration id. */
25
+ update?: string;
9
26
  }>;
10
27
  export declare function directoryEntriesMatch(directory: string, regex: RegExp): boolean;
11
- export declare function inspectProofEnvironment(root: string): ProofInspection;
28
+ export declare function inspectProofEnvironment(root: string, options?: ProofInspectionOptions): ProofInspection;
12
29
  //# sourceMappingURL=inspect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/proof/inspect.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAwIH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAMT;AA2BD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAoFrE"}
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/proof/inspect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,EAAE,mBAAmB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAC/D,6EAA6E;IAC7E,gBAAgB,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IACjE;;;OAGG;IACH,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,sDAAsD;IACtD,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAwIH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAMT;AA2BD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,eAAe,CAgGjB"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync, readdirSync } from "node:fs";
2
2
  import path from "node:path";
3
- import { loadProofIntegrations } from "./integrations.js";
3
+ import { buildProofIntegrationPlan, } from "./integration-plan.js";
4
+ import { PROOF_INTEGRATIONS_PATH, loadProofIntegrations, } from "./integrations.js";
4
5
  /**
5
6
  * Declarative detection manifests. Deterministic CLI logic consumes these;
6
7
  * agents consume the inspection output and never reinvent runner discovery.
@@ -149,7 +150,7 @@ function directoryExists(root, relative) {
149
150
  }
150
151
  }
151
152
  // implements REQ-kibi-verification-evidence-contract
152
- export function inspectProofEnvironment(root) {
153
+ export function inspectProofEnvironment(root, options = {}) {
153
154
  const languages = new Set();
154
155
  const buildSystems = new Set();
155
156
  const runners = [];
@@ -207,17 +208,21 @@ export function inspectProofEnvironment(root) {
207
208
  const currentIntegration = integrations.available
208
209
  ? integrations.integrations.integrations.map((entry) => entry.id).join(", ")
209
210
  : null;
211
+ const planned = buildProofIntegrationPlan(root, options);
212
+ const applyHint = "review integrationPlan, then apply it with kb_apply_plan (or `kibi apply-plan --input -`) passing plan, approvedPlanHash = plan.planHash and approvedActionIds";
210
213
  let recommendation;
211
- if (!integrations.available) {
212
- if (runners.length === 0) {
214
+ if (planned.plan !== null && options.update !== undefined) {
215
+ recommendation = `To replace integration '${options.update}', ${applyHint}.`;
216
+ }
217
+ else if (!integrations.available) {
218
+ if (planned.plan === null) {
213
219
  recommendation =
214
220
  "No test harness detected. Proof integration is deferred until the first proof-bearing test introduces one; command proof can prove any command.";
215
- missing.push(".kb/proof/integrations.json (created by bootstrap)");
221
+ missing.push(`${PROOF_INTEGRATIONS_PATH} (written by applying the plan from kibi proof inspect --json)`);
216
222
  }
217
223
  else {
218
- recommendation =
219
- "Run bootstrap to configure proof integrations: native producers or standard-format adapters for detected runners, or command proof as the universal fallback.";
220
- missing.push(".kb/proof/integrations.json (created by bootstrap)");
224
+ recommendation = `Kibi proposes a command integration for the detected runner. To configure it, ${applyHint}. Proof-bearing tests then name it in proof_contract.integration and kibi prove runs it.`;
225
+ missing.push(`${PROOF_INTEGRATIONS_PATH} (written by applying integrationPlan)`);
221
226
  }
222
227
  }
223
228
  else {
@@ -232,5 +237,9 @@ export function inspectProofEnvironment(root) {
232
237
  currentIntegration,
233
238
  recommendation,
234
239
  missing,
240
+ proposedIntegration: planned.proposal?.integration ?? null,
241
+ contractDefaults: planned.proposal?.contractDefaults ?? null,
242
+ integrationPlan: planned.plan,
243
+ integrationPlanReason: planned.reason,
235
244
  };
236
245
  }
@@ -0,0 +1,57 @@
1
+ import { type MigrationAction, type MigrationPlan } from "../public/operations/migration-plan.js";
2
+ import { PROOF_CONTRACT_VERSION } from "../public/proof-protocol.js";
3
+ import { type ProofIntegration } from "./integrations.js";
4
+ /** Migration action code of a reviewed proof integration write. */
5
+ export declare const PROOF_INTEGRATION_CONFIGURE = "proof_integration_configure";
6
+ export type ProposedIntegration = Readonly<{
7
+ integration: ProofIntegration;
8
+ /** The runner the proposal was derived from (for the review summary). */
9
+ runner: string;
10
+ /** What a proof-bearing test's proof_contract names for this integration. */
11
+ contractDefaults: Readonly<{
12
+ version: typeof PROOF_CONTRACT_VERSION;
13
+ integration: string;
14
+ required_proofs: ReadonlyArray<{
15
+ symbol_id: string;
16
+ target: string;
17
+ }>;
18
+ success_policy: "all_required_first_attempt";
19
+ }>;
20
+ }>;
21
+ export type ProofIntegrationPlanResult = Readonly<{
22
+ /** The hash-bound plan to review and apply with kb_apply_plan, if any. */
23
+ plan: MigrationPlan | null;
24
+ proposal: ProposedIntegration | null;
25
+ /** Why no plan was produced, or what applying it does. */
26
+ reason: string;
27
+ }>;
28
+ /**
29
+ * The command-producer integration Kibi proposes for the repository's test
30
+ * runner: the package.json `test` script when there is one (it is what the
31
+ * project already runs), otherwise the first detected runner. A command
32
+ * integration is the universal floor: Kibi judges the run by its exit code
33
+ * (aggregate-run provenance), so it works for every runner without a
34
+ * reporter; a native producer can replace it later through an update plan.
35
+ */
36
+ export declare function proposeProofIntegration(root: string, overrideId?: string): ProposedIntegration | null;
37
+ /**
38
+ * Build the hash-bound `kibi.migration-plan.v2` that writes
39
+ * `.kb/proof/integrations.json` through Kibi. Without `update`, a plan is
40
+ * produced only while the file does not exist; with `update` it adds or
41
+ * replaces the named integration of an existing, valid file. The plan carries the file's
42
+ * current hash and the hashes of the files the proposal was derived from;
43
+ * `kb_apply_plan` refuses it once either changed.
44
+ */
45
+ export declare function buildProofIntegrationPlan(root: string, options?: Readonly<{
46
+ update?: string;
47
+ }>): ProofIntegrationPlanResult;
48
+ /**
49
+ * Apply one reviewed `proof_integration_configure` action: write
50
+ * `.kb/proof/integrations.json` (`kibi.proof-integration.v1`). A create is
51
+ * refused when the file exists; an update is refused unless the file still
52
+ * has the hash the plan was built against, and it adds or replaces only the
53
+ * named integration. Either is refused when
54
+ * a file the proposal was derived from changed since planning.
55
+ */
56
+ export declare function applyProofIntegrationAction(action: MigrationAction, root: string): void;
57
+ //# sourceMappingURL=integration-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-plan.d.ts","sourceRoot":"","sources":["../../src/proof/integration-plan.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAGnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,mBAAmB,CAAC;AAE3B,mEAAmE;AACnE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAqCzE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,gBAAgB,EAAE,QAAQ,CAAC;QACzB,OAAO,EAAE,OAAO,sBAAsB,CAAC;QACvC,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,aAAa,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACtE,cAAc,EAAE,4BAA4B,CAAC;KAC9C,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,0EAA0E;IAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAyGH;;;;;;;GAOG;AAEH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,mBAAmB,GAAG,IAAI,CA8B5B;AAsCD;;;;;;;GAOG;AAEH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GAC1C,0BAA0B,CAiE5B;AAMD;;;;;;;GAOG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,IAAI,CAyDN"}