kibi-cli 2.38.0 → 2.40.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 (222) hide show
  1. package/dist/cli-json-command.d.ts.map +1 -1
  2. package/dist/cli-json-command.js +4 -0
  3. package/dist/cli-register-foundation.js +2 -2
  4. package/dist/cli-register-reporting.d.ts.map +1 -1
  5. package/dist/cli-register-reporting.js +1 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +3 -0
  8. package/dist/commands/check.d.ts.map +1 -1
  9. package/dist/commands/check.js +33 -9
  10. package/dist/commands/coverage.d.ts +1 -0
  11. package/dist/commands/coverage.d.ts.map +1 -1
  12. package/dist/commands/coverage.js +40 -0
  13. package/dist/commands/doctor.d.ts +5 -0
  14. package/dist/commands/doctor.d.ts.map +1 -1
  15. package/dist/commands/doctor.js +29 -0
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +4 -0
  18. package/dist/commands/migrate-plan-record.d.ts +18 -0
  19. package/dist/commands/migrate-plan-record.d.ts.map +1 -0
  20. package/dist/commands/migrate-plan-record.js +112 -0
  21. package/dist/commands/migrate.d.ts +11 -2
  22. package/dist/commands/migrate.d.ts.map +1 -1
  23. package/dist/commands/migrate.js +60 -8
  24. package/dist/commands/prove.d.ts.map +1 -1
  25. package/dist/commands/prove.js +18 -3
  26. package/dist/commands/sync/manifest.d.ts.map +1 -1
  27. package/dist/commands/sync/manifest.js +17 -4
  28. package/dist/commands/sync/persistence.d.ts.map +1 -1
  29. package/dist/commands/sync/persistence.js +6 -0
  30. package/dist/commands/sync.d.ts.map +1 -1
  31. package/dist/commands/sync.js +8 -0
  32. package/dist/commands/telemetry.d.ts.map +1 -1
  33. package/dist/commands/telemetry.js +12 -2
  34. package/dist/extractors/markdown.d.ts +6 -0
  35. package/dist/extractors/markdown.d.ts.map +1 -1
  36. package/dist/extractors/markdown.js +21 -0
  37. package/dist/extractors/symbol-title-match.d.ts +31 -0
  38. package/dist/extractors/symbol-title-match.d.ts.map +1 -0
  39. package/dist/extractors/symbol-title-match.js +133 -0
  40. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  41. package/dist/extractors/symbols-coordinator.js +81 -12
  42. package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
  43. package/dist/operations/bootstrap/discovery-evidence.js +44 -2
  44. package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
  45. package/dist/operations/bootstrap/discovery.js +1 -0
  46. package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
  47. package/dist/operations/bootstrap/guidance-actions.js +12 -1
  48. package/dist/operations/bootstrap/plugin-offers.d.ts +7 -1
  49. package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
  50. package/dist/operations/bootstrap/plugin-offers.js +73 -3
  51. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
  52. package/dist/operations/modeling/logic-modeling.js +2 -1
  53. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  54. package/dist/operations/modeling/model-requirement.js +2 -1
  55. package/dist/operations/mutation/symbol-refresh.d.ts +2 -0
  56. package/dist/operations/mutation/symbol-refresh.d.ts.map +1 -1
  57. package/dist/operations/mutation/symbol-refresh.js +6 -1
  58. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  59. package/dist/operations/mutation/upsert.js +7 -0
  60. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  61. package/dist/operations/planning/compile-intent.js +2 -1
  62. package/dist/operations/proof/claim-bindings.d.ts +11 -0
  63. package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
  64. package/dist/operations/proof/claim-bindings.js +144 -1
  65. package/dist/operations/proof/code-certificates.d.ts +10 -3
  66. package/dist/operations/proof/code-certificates.d.ts.map +1 -1
  67. package/dist/operations/proof/code-certificates.js +65 -13
  68. package/dist/operations/proof/code-languages.d.ts +104 -0
  69. package/dist/operations/proof/code-languages.d.ts.map +1 -0
  70. package/dist/operations/proof/code-languages.js +119 -0
  71. package/dist/operations/proof/code-models.d.ts +2 -0
  72. package/dist/operations/proof/code-models.d.ts.map +1 -1
  73. package/dist/operations/proof/code-models.js +11 -5
  74. package/dist/operations/proof/code-runner.d.ts +12 -9
  75. package/dist/operations/proof/code-runner.d.ts.map +1 -1
  76. package/dist/operations/proof/code-runner.js +81 -38
  77. package/dist/operations/proof/code-scope.d.ts +8 -0
  78. package/dist/operations/proof/code-scope.d.ts.map +1 -1
  79. package/dist/operations/proof/code-scope.js +30 -1
  80. package/dist/operations/proof/explain.d.ts +76 -0
  81. package/dist/operations/proof/explain.d.ts.map +1 -1
  82. package/dist/operations/proof/explain.js +228 -0
  83. package/dist/operations/proof/ingest-proof.d.ts +2 -0
  84. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  85. package/dist/operations/proof/ingest-proof.js +1 -0
  86. package/dist/operations/proof/java-package-shadow.d.ts +14 -0
  87. package/dist/operations/proof/java-package-shadow.d.ts.map +1 -0
  88. package/dist/operations/proof/java-package-shadow.js +389 -0
  89. package/dist/operations/proof/prolog-evaluator.d.ts +14 -0
  90. package/dist/operations/proof/prolog-evaluator.d.ts.map +1 -0
  91. package/dist/operations/proof/prolog-evaluator.js +247 -0
  92. package/dist/operations/proof/prolog-source-reader.d.ts +20 -0
  93. package/dist/operations/proof/prolog-source-reader.d.ts.map +1 -0
  94. package/dist/operations/proof/prolog-source-reader.js +1123 -0
  95. package/dist/operations/proof/source-code-readers.d.ts +6 -0
  96. package/dist/operations/proof/source-code-readers.d.ts.map +1 -1
  97. package/dist/operations/proof/source-code-readers.js +879 -75
  98. package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
  99. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  100. package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
  101. package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
  102. package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
  103. package/dist/operations/semantic-advisor/case-preview.js +216 -0
  104. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  105. package/dist/operations/semantic-advisor/shared.js +3 -0
  106. package/dist/operations/semantic-advisor/types.d.ts +23 -0
  107. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  108. package/dist/plugins/approved-source-analyzers.generated.d.ts +15 -34
  109. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
  110. package/dist/plugins/approved-source-analyzers.generated.js +15 -34
  111. package/dist/plugins/plugin-install-check.d.ts +21 -0
  112. package/dist/plugins/plugin-install-check.d.ts.map +1 -0
  113. package/dist/plugins/plugin-install-check.js +62 -0
  114. package/dist/plugins/proof-reference-extractors.d.ts +20 -0
  115. package/dist/plugins/proof-reference-extractors.d.ts.map +1 -0
  116. package/dist/plugins/proof-reference-extractors.js +104 -0
  117. package/dist/plugins/reference-language-suggestion.d.ts +51 -0
  118. package/dist/plugins/reference-language-suggestion.d.ts.map +1 -0
  119. package/dist/plugins/reference-language-suggestion.js +277 -0
  120. package/dist/plugins/registry.d.ts.map +1 -1
  121. package/dist/plugins/registry.js +3 -1
  122. package/dist/plugins/source-analysis-service.d.ts.map +1 -1
  123. package/dist/plugins/source-analysis-service.js +4 -0
  124. package/dist/plugins/source-change-analysis.d.ts +26 -1
  125. package/dist/plugins/source-change-analysis.d.ts.map +1 -1
  126. package/dist/plugins/source-change-analysis.js +77 -5
  127. package/dist/plugins/source-classification.d.ts +2 -2
  128. package/dist/plugins/source-classification.d.ts.map +1 -1
  129. package/dist/plugins/source-classification.js +45 -1
  130. package/dist/public/operations/catalog.d.ts +62 -7
  131. package/dist/public/operations/catalog.d.ts.map +1 -1
  132. package/dist/public/operations/check-executor.d.ts.map +1 -1
  133. package/dist/public/operations/check-executor.js +3 -0
  134. package/dist/public/operations/evidence-floor.d.ts +8 -0
  135. package/dist/public/operations/evidence-floor.d.ts.map +1 -1
  136. package/dist/public/operations/evidence-floor.js +19 -1
  137. package/dist/public/operations/repair-plan.d.ts +46 -0
  138. package/dist/public/operations/repair-plan.d.ts.map +1 -1
  139. package/dist/public/operations/repair-plan.js +110 -1
  140. package/dist/public/operations/schema6-check-actions.js +1 -1
  141. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  142. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  143. package/dist/public/operations/specs/check-rules.generated.js +3 -1
  144. package/dist/public/operations/specs/check.d.ts +1 -1
  145. package/dist/public/operations/specs/mutation-schemas.d.ts +61 -6
  146. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  147. package/dist/public/operations/specs/mutation-schemas.js +30 -0
  148. package/dist/public/operations/specs/reporting.d.ts +8 -0
  149. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  150. package/dist/public/operations/specs/reporting.js +26 -3
  151. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  152. package/dist/public/operations/specs/semantic.js +2 -1
  153. package/dist/public/operations/specs/upsert.d.ts +61 -6
  154. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  155. package/dist/public/operations/symbol-coordinates-check.d.ts +11 -0
  156. package/dist/public/operations/symbol-coordinates-check.d.ts.map +1 -0
  157. package/dist/public/operations/symbol-coordinates-check.js +66 -0
  158. package/dist/public/proof-protocol.d.ts +31 -6
  159. package/dist/public/proof-protocol.d.ts.map +1 -1
  160. package/dist/public/proof-protocol.js +45 -15
  161. package/dist/public/proof-sources.d.ts +4 -2
  162. package/dist/public/proof-sources.d.ts.map +1 -1
  163. package/dist/public/proof-sources.js +43 -4
  164. package/dist/public/schemas/entity.d.ts.map +1 -1
  165. package/dist/public/schemas/entity.js +59 -0
  166. package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
  167. package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
  168. package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  169. package/dist/public/skills/kibi-usage/SKILL.md +14 -3
  170. package/dist/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
  171. package/dist/public/skills/kibi-usage/resources/proof.md +44 -3
  172. package/dist/schemas/entity.schema.json +126 -6
  173. package/dist/search-answer.d.ts +3 -2
  174. package/dist/search-answer.d.ts.map +1 -1
  175. package/dist/search-answer.js +56 -3
  176. package/dist/traceability/analysis-gate.d.ts +3 -1
  177. package/dist/traceability/analysis-gate.d.ts.map +1 -1
  178. package/dist/traceability/analysis-gate.js +9 -1
  179. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  180. package/dist/traceability/impact-knowledge.js +2 -0
  181. package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
  182. package/dist/traceability/staged-file-coverage.js +7 -2
  183. package/dist/traceability/symbol-extract.d.ts +17 -0
  184. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  185. package/dist/traceability/symbol-extract.js +69 -15
  186. package/dist/traceability/temp-kb.d.ts.map +1 -1
  187. package/dist/traceability/temp-kb.js +11 -1
  188. package/dist/traceability/validate.d.ts.map +1 -1
  189. package/dist/traceability/validate.js +5 -7
  190. package/dist/types/entities.d.ts +12 -0
  191. package/dist/types/entities.d.ts.map +1 -1
  192. package/dist/usage-telemetry.d.ts +9 -0
  193. package/dist/usage-telemetry.d.ts.map +1 -1
  194. package/dist/usage-telemetry.js +50 -4
  195. package/dist/utils/first-sentence.d.ts +9 -0
  196. package/dist/utils/first-sentence.d.ts.map +1 -0
  197. package/dist/utils/first-sentence.js +52 -0
  198. package/dist/utils/rule-registry.generated.d.ts +11 -0
  199. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  200. package/dist/utils/rule-registry.generated.js +13 -0
  201. package/package.json +5 -5
  202. package/schema/entities.pl +12 -0
  203. package/src/public/operations/check-executor.ts +8 -0
  204. package/src/public/operations/evidence-floor.ts +29 -1
  205. package/src/public/operations/repair-plan.ts +152 -1
  206. package/src/public/operations/schema6-check-actions.ts +1 -1
  207. package/src/public/operations/specs/check-rules.generated.ts +3 -1
  208. package/src/public/operations/specs/mutation-schemas.ts +34 -0
  209. package/src/public/operations/specs/reporting.ts +38 -3
  210. package/src/public/operations/specs/semantic.ts +2 -1
  211. package/src/public/operations/symbol-coordinates-check.ts +79 -0
  212. package/src/public/proof-protocol-types.d.ts +22 -5
  213. package/src/public/proof-protocol.ts +78 -19
  214. package/src/public/proof-sources.ts +51 -3
  215. package/src/public/schemas/entity.ts +65 -0
  216. package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
  217. package/src/public/skills/kibi-decisions/SKILL.md +7 -2
  218. package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  219. package/src/public/skills/kibi-usage/SKILL.md +14 -3
  220. package/src/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
  221. package/src/public/skills/kibi-usage/resources/proof.md +44 -3
  222. package/src/schemas/entity.schema.json +126 -6
@@ -110,6 +110,40 @@ const REPAIR_PHASES = {
110
110
  validationRules: ["must-priority-coverage", "no-dangling-refs"],
111
111
  writePolicy: "sequential_upsert",
112
112
  },
113
+ dimension_grounding: {
114
+ order: 64,
115
+ objective:
116
+ "Ground each quantified claim (each, every, all, or a cardinality bound) on what varies: an integer count or bound, a set of members, a rule over a variable, or a state machine. If the quantifier ranges over nothing, record a dimension_waiver on the grounding fact for a person to approve, and record their approval in the same pull request.",
117
+ workflowSteps: [
118
+ "kb_model_requirement",
119
+ "kb_validate_upsert",
120
+ "kb_upsert",
121
+ "kb_check",
122
+ ],
123
+ validationRules: ["no-dangling-refs"],
124
+ writePolicy: "sequential_upsert",
125
+ },
126
+ case_scenarios: {
127
+ order: 66,
128
+ objective:
129
+ "Cover each uncovered rejection case: add a scenario whose assumes fact states the case's assumption (a value past the bound, a value outside the set), expects rejection or error, is linked with specified_by and is verified by a passing end-to-end test. Each repair lists caseSkeletons, upsert-ready draft scenarios and their assumed facts: fill in the placeholders, verify the scenario by a test, then set its status to active (a draft never covers a case). If a person accepts the cases as covered another way, record a case_waiver on the grounding fact for them to approve, and record their approval in the same pull request.",
130
+ workflowSteps: [
131
+ "kb_coverage",
132
+ "kb_validate_upsert",
133
+ "kb_upsert",
134
+ "kb_check",
135
+ ],
136
+ validationRules: ["scenario-outcome-mismatch", "no-dangling-refs"],
137
+ writePolicy: "sequential_upsert",
138
+ },
139
+ negative_scenarios: {
140
+ order: 65,
141
+ objective:
142
+ "Add a scenario that expects rejection or error and assumes a value the requirement forbids (see suggestedNegatives), link it with specified_by and verify it with a passing end-to-end test.",
143
+ workflowSteps: ["kb_query", "kb_validate_upsert", "kb_upsert", "kb_check"],
144
+ validationRules: ["scenario-outcome-mismatch", "no-dangling-refs"],
145
+ writePolicy: "sequential_upsert",
146
+ },
113
147
  scenario_tests: {
114
148
  order: 70,
115
149
  objective:
@@ -206,6 +240,9 @@ const GAP_PHASE: Readonly<Record<string, RepairPhase>> = {
206
240
  missing_scenario: "scenario_endpoints",
207
241
  infeasible_scenario: "scenario_endpoints",
208
242
  unknown_scenario_feasibility: "scenario_endpoints",
243
+ dimension_unrepresented: "dimension_grounding",
244
+ happy_path_only: "negative_scenarios",
245
+ uncovered_case: "case_scenarios",
209
246
  missing_scenario_test: "scenario_tests",
210
247
  proof_snapshot_unavailable: "snapshot_runtime",
211
248
  missing_passing_e2e: "proof_evidence",
@@ -235,6 +272,9 @@ const GAP_STAGE: Readonly<Record<string, string>> = {
235
272
  missing_scenario: "scenarios",
236
273
  infeasible_scenario: "scenarios",
237
274
  unknown_scenario_feasibility: "scenarios",
275
+ dimension_unrepresented: "dimension",
276
+ happy_path_only: "negative_path",
277
+ uncovered_case: "cases",
238
278
  missing_scenario_test: "scenario_tests",
239
279
  missing_passing_e2e: "passing_e2e",
240
280
  missing_proof_receipt: "passing_e2e",
@@ -255,6 +295,9 @@ const PROOF_STAGE_KEY: Readonly<Record<string, string>> = {
255
295
  contradictions: "contradictions",
256
296
  scenarios: "scenarios",
257
297
  scenario_tests: "scenarioTests",
298
+ negative_path: "negativePath",
299
+ dimension: "dimension",
300
+ cases: "cases",
258
301
  passing_e2e: "passingE2e",
259
302
  executable_symbols: "executableSymbols",
260
303
  production_symbols: "productionSymbols",
@@ -268,6 +311,34 @@ export type RepairPlanRepair = {
268
311
  readonly proofStage: string;
269
312
  readonly action: string;
270
313
  readonly evidence: Readonly<Record<string, unknown>>;
314
+ /** Draft scenarios for an uncovered_case repair, one per uncovered case. */
315
+ readonly caseSkeletons?: readonly CaseSkeleton[];
316
+ };
317
+
318
+ type SkeletonEntity = {
319
+ readonly type: "fact" | "scenario";
320
+ readonly id: string;
321
+ readonly properties: Readonly<Record<string, unknown>>;
322
+ readonly relationships: readonly {
323
+ readonly type: string;
324
+ readonly from: string;
325
+ readonly to: string;
326
+ }[];
327
+ };
328
+
329
+ // implements REQ-kibi-case-coverage
330
+ /**
331
+ * An upsert-ready draft scenario for one uncovered case: the fact it assumes
332
+ * (the case's value class) and the scenario that expects the predicted
333
+ * outcome. Drafts never count as coverage, so writing one changes no gap
334
+ * until it is verified and made active. placeholder is true when the value
335
+ * must be chosen by the author (a value outside a set).
336
+ */
337
+ export type CaseSkeleton = {
338
+ readonly caseId: string;
339
+ readonly constraint: string;
340
+ readonly placeholder: boolean;
341
+ readonly entities: readonly [SkeletonEntity, SkeletonEntity];
271
342
  };
272
343
 
273
344
  export type RepairPlanBatch = {
@@ -379,6 +450,82 @@ function stageEvidence(
379
450
  return isRecord(stable) ? stable : {};
380
451
  }
381
452
 
453
+ const VALUE_FIELD: Readonly<Record<string, string>> = {
454
+ int: "value_int",
455
+ number: "value_number",
456
+ set: "value_set",
457
+ string: "value_string",
458
+ };
459
+
460
+ function caseSkeleton(
461
+ requirementId: string,
462
+ row: Readonly<Record<string, unknown>>,
463
+ ): CaseSkeleton | undefined {
464
+ const caseId = typeof row.caseId === "string" ? row.caseId : undefined;
465
+ const assumption = isRecord(row.assumption) ? row.assumption : undefined;
466
+ const valueType =
467
+ typeof assumption?.value_type === "string" ? assumption.value_type : "";
468
+ const valueField = VALUE_FIELD[valueType];
469
+ if (caseId === undefined || assumption === undefined || !valueField)
470
+ return undefined;
471
+ const constraint = typeof row.constraint === "string" ? row.constraint : "";
472
+ const property =
473
+ typeof assumption.property_key === "string" ? assumption.property_key : "";
474
+ const expects = row.predicted === "rejection" ? "rejection" : "success";
475
+ const placeholder = JSON.stringify(assumption.value).includes("<");
476
+ const suffix = caseId.replace(/^CASE-/, "");
477
+ const factId = `FACT-CASE-${suffix}`;
478
+ const scenarioId = `SCEN-CASE-${suffix}`;
479
+ return {
480
+ caseId,
481
+ constraint,
482
+ placeholder,
483
+ entities: [
484
+ {
485
+ type: "fact",
486
+ id: factId,
487
+ properties: {
488
+ title: `${property} ${constraint}`,
489
+ status: "active",
490
+ fact_kind: "property_value",
491
+ subject_key: assumption.subject_key,
492
+ property_key: property,
493
+ operator: assumption.operator,
494
+ value_type: valueType,
495
+ [valueField]: assumption.value,
496
+ },
497
+ relationships: [],
498
+ },
499
+ {
500
+ type: "scenario",
501
+ id: scenarioId,
502
+ properties: {
503
+ title: `${property} ${constraint} is ${expects === "rejection" ? "refused" : "accepted"}`,
504
+ status: "draft",
505
+ expects,
506
+ },
507
+ relationships: [
508
+ { type: "assumes", from: scenarioId, to: factId },
509
+ { type: "specified_by", from: requirementId, to: scenarioId },
510
+ ],
511
+ },
512
+ ],
513
+ };
514
+ }
515
+
516
+ function caseSkeletons(
517
+ requirementId: string,
518
+ evidence: Readonly<Record<string, unknown>>,
519
+ ): CaseSkeleton[] {
520
+ const rows = Array.isArray(evidence.uncoveredCases)
521
+ ? evidence.uncoveredCases.filter(isRecord)
522
+ : [];
523
+ return rows.flatMap((row) => {
524
+ const skeleton = caseSkeleton(requirementId, row);
525
+ return skeleton === undefined ? [] : [skeleton];
526
+ });
527
+ }
528
+
382
529
  function batchId(requirementId: string, phase: RepairPhase): string {
383
530
  const order = String(REPAIR_PHASES[phase].order).padStart(3, "0");
384
531
  const safeRequirementId = requirementId.replace(/[^A-Za-z0-9_-]/g, "-");
@@ -408,6 +555,7 @@ function buildRequirementBatches(
408
555
  typeof sourceRepair?.stage === "string"
409
556
  ? sourceRepair.stage
410
557
  : (GAP_STAGE[gap] ?? "manual_review");
558
+ const evidence = stageEvidence(row, proofStage);
411
559
  const repair: RepairPlanRepair = {
412
560
  requirementId,
413
561
  gap,
@@ -417,7 +565,10 @@ function buildRequirementBatches(
417
565
  ),
418
566
  proofStage,
419
567
  action: actionForRepair(sourceRepair, phase),
420
- evidence: stageEvidence(row, proofStage),
568
+ evidence,
569
+ ...(gap === "uncovered_case"
570
+ ? { caseSkeletons: caseSkeletons(requirementId, evidence) }
571
+ : {}),
421
572
  };
422
573
  const phaseRepairs = byPhase.get(phase) ?? [];
423
574
  phaseRepairs.push(repair);
@@ -728,7 +728,7 @@ export function schema6ReviewActionsFromCheck(
728
728
  safety: "review",
729
729
  invocation: {
730
730
  kind: "review",
731
- instruction: `${total} agent-authored requirement(s) have no human approval${total > listed.length ? `; these ${listed.length} come first` : ""}: ${listed.join(", ")}. Have a person read each one; when it states the intended behavior, kb_upsert it with origin.approved_by set to the reviewer (keep kind: agent and the rest of origin). Rerun kb_check for the next page.`,
731
+ instruction: `${total} agent-authored requirement(s) have no human approval${total > listed.length ? `; these ${listed.length} come first` : ""}: ${listed.join(", ")}. Have a person read each one; when it states the intended behavior, kb_upsert it with origin.approved_by set to the reviewer (keep kind: agent and the rest of origin), in the same change and pull request as the requirement, not a separate one. Rerun kb_check for the next page.`,
732
732
  },
733
733
  affectedEntityIds: listed,
734
734
  affectedFiles: [...new Set(agentRequirementFiles)].sort(),
@@ -14,6 +14,7 @@ export const SELECTABLE_RULE_NAMES: readonly string[] = [
14
14
  "symbol-coverage",
15
15
  "symbol-traceability",
16
16
  "symbol-granularity",
17
+ "symbol-coordinates-missing",
17
18
  "no-dangling-refs",
18
19
  "source-relationship-parity",
19
20
  "branch-store-not-compiled",
@@ -24,6 +25,7 @@ export const SELECTABLE_RULE_NAMES: readonly string[] = [
24
25
  "superseded-requirement-open",
25
26
  "scenario-feasibility",
26
27
  "scenario-feasibility-unknown",
28
+ "scenario-outcome-mismatch",
27
29
  "exception-claim-keys",
28
30
  "numeric-string-value",
29
31
  "rule-key-arguments-missing",
@@ -72,4 +74,4 @@ export const SELECTABLE_RULE_NAMES: readonly string[] = [
72
74
  // implements REQ-006
73
75
  /** Comma-separated "Allowed:" fragment for the kb_check rules description. */
74
76
  export const SELECTABLE_RULES_ALLOWED =
75
- "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved, evidence-floor, proof-contract-claims";
77
+ "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, symbol-coordinates-missing, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, scenario-outcome-mismatch, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved, evidence-floor, proof-contract-claims";
@@ -126,6 +126,18 @@ export const ENTITY_PROPERTIES_SCHEMA = {
126
126
  description:
127
127
  "Requirement-only. Optional reference to the exception's approval decision record.",
128
128
  },
129
+ failure_side_waiver: {
130
+ type: "string",
131
+ minLength: 1,
132
+ description:
133
+ "Requirement-only. Why the requirement has no failure side to test (its claims state a capability or output shape). Waives happy_path_only once failure_side_waiver_approved_by is set.",
134
+ },
135
+ failure_side_waiver_approved_by: {
136
+ type: "string",
137
+ minLength: 1,
138
+ description:
139
+ "Requirement-only. The person who accepted failure_side_waiver.",
140
+ },
129
141
  firmness: {
130
142
  type: "string",
131
143
  enum: ["firm", "default", "exploratory"],
@@ -323,6 +335,28 @@ export const ENTITY_PROPERTIES_SCHEMA = {
323
335
  description:
324
336
  "Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.",
325
337
  },
338
+ dimension_waiver: {
339
+ type: "string",
340
+ minLength: 1,
341
+ description:
342
+ "Fact-only. Why the quantifier word in claim_text ranges over nothing, so the claim needs no count, set or rule. Waives dimension_unrepresented once dimension_waiver_approved_by is set.",
343
+ },
344
+ dimension_waiver_approved_by: {
345
+ type: "string",
346
+ minLength: 1,
347
+ description: "Fact-only. The person who accepted dimension_waiver.",
348
+ },
349
+ case_waiver: {
350
+ type: "string",
351
+ minLength: 1,
352
+ description:
353
+ "Fact-only. Why the edge cases derived from this fact are covered some other way or cannot occur. Waives uncovered_case once case_waiver_approved_by is set.",
354
+ },
355
+ case_waiver_approved_by: {
356
+ type: "string",
357
+ minLength: 1,
358
+ description: "Fact-only. The person who accepted case_waiver.",
359
+ },
326
360
  predicate_name: {
327
361
  type: "string",
328
362
  description:
@@ -37,6 +37,32 @@ const ENTITY_TYPES = [
37
37
  ] as const;
38
38
  const ENTITY_TYPE_SET: ReadonlySet<string> = new Set(ENTITY_TYPES);
39
39
 
40
+ /**
41
+ * The engine names the attached store by its directory key (a SHA-256 of the
42
+ * branch name); meta.branch carries the branch name, as kb_status does, and
43
+ * the key moves to meta.branchStoreKey.
44
+ */
45
+ // implements REQ-kibi-verification-evidence-contract
46
+ export function withBranchName<
47
+ T extends { readonly meta?: Readonly<Record<string, unknown>> },
48
+ >(payload: T, context: Pick<OperationContext, "branchAttachment">): T {
49
+ const meta = payload.meta;
50
+ const name = context.branchAttachment?.kbBranch;
51
+ if (meta === undefined || name === undefined || meta.branch === name)
52
+ return payload;
53
+ const key = typeof meta.branch === "string" ? meta.branch : undefined;
54
+ return {
55
+ ...payload,
56
+ meta: {
57
+ ...meta,
58
+ branch: name,
59
+ ...(key !== undefined && key !== "unknown"
60
+ ? { branchStoreKey: key }
61
+ : {}),
62
+ },
63
+ };
64
+ }
65
+
40
66
  export type FindGapsInput = {
41
67
  readonly type?: string;
42
68
  readonly missingRelationships?: readonly string[];
@@ -161,7 +187,10 @@ export async function executeFindGaps(
161
187
  : `Found ${payload.count ?? rows.length} gap rows. Showing ${rows.length}: ${rows.map((row) => row.id).join(", ")}.${stubNote}`,
162
188
  },
163
189
  ],
164
- structuredContent: confirmMetaFreshness(payload, context.workspaceRoot),
190
+ structuredContent: withBranchName(
191
+ confirmMetaFreshness(payload, context.workspaceRoot),
192
+ context,
193
+ ),
165
194
  };
166
195
  } catch (error) {
167
196
  const message = error instanceof Error ? error.message : String(error);
@@ -418,7 +447,10 @@ export async function executeCoverage(
418
447
  const migrationPlan = statusPlan
419
448
  ? mergeMigrationPlans([statusPlan, coveragePlan])
420
449
  : coveragePlan;
421
- const confirmed = confirmMetaFreshness(payload, context.workspaceRoot);
450
+ const confirmed = withBranchName(
451
+ confirmMetaFreshness(payload, context.workspaceRoot),
452
+ context,
453
+ );
422
454
  const enrichedPayload = {
423
455
  ...confirmed,
424
456
  rows,
@@ -581,7 +613,10 @@ export async function executeGraph(
581
613
  : `Graph traversal returned ${nodes.length} nodes and ${edges.length} edges from ${input.seedIds.join(", ")}.`,
582
614
  },
583
615
  ],
584
- structuredContent: confirmMetaFreshness(payload, context.workspaceRoot),
616
+ structuredContent: withBranchName(
617
+ confirmMetaFreshness(payload, context.workspaceRoot),
618
+ context,
619
+ ),
585
620
  };
586
621
  } catch (error) {
587
622
  const message = error instanceof Error ? error.message : String(error);
@@ -7,6 +7,7 @@ import type {
7
7
  SemanticAdvisorReceipt,
8
8
  } from "../../../operations/semantic-advisor/types.js";
9
9
  import { publicCapabilityStamp } from "../../../plugins/compose-semantic-classifier.js";
10
+ import { firstSentence } from "../../../utils/first-sentence.js";
10
11
  import type { OperationContext, PrologPort } from "../runtime-types.js";
11
12
  import type { OperationSpec } from "../types.js";
12
13
 
@@ -59,7 +60,7 @@ export async function executeSemanticAdvisor(
59
60
  ): Promise<SemanticAdvisorOperationResult> {
60
61
  const text = requiredText(args.text);
61
62
  const id = optionalString(args.id) ?? "REQ-SEMANTIC-ADVISOR-PREVIEW";
62
- const title = optionalString(args.title) ?? text.split(/[.!?]/, 1)[0] ?? text;
63
+ const title = optionalString(args.title) ?? (firstSentence(text) || text);
63
64
  const source = optionalString(args.source) ?? "mcp://kibi/semantic-advisor";
64
65
  const orchestrated = await analyzeSemanticAdvisorInputWithPlugins(
65
66
  {
@@ -0,0 +1,79 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import { existsSync, statSync } from "node:fs";
20
+ import * as path from "node:path";
21
+ import { parseEntityFromList, parseListOfLists } from "../../prolog/codec.js";
22
+ import type { Violation } from "../../utils/rule-registry.js";
23
+ import type { PrologPort } from "./runtime-types.js";
24
+
25
+ /**
26
+ * A symbol whose source file exists but which Kibi could not place in it is
27
+ * linked to no code: impact review, coverage and proofs never see it there.
28
+ * kibi sync names it in its refresh output only, so the check reports every
29
+ * such symbol as a warning (advisory, non-blocking).
30
+ */
31
+ // implements REQ-cli-check, REQ-generated-coordinate-persistence
32
+ export const SYMBOL_COORDINATES_MISSING_RULE = "symbol-coordinates-missing";
33
+
34
+ const SYMBOL_PLACEMENT_QUERY =
35
+ "findall([Id,symbol,Fields], (kb_entity(Id, symbol, Props), include([Key=_]>>memberchk(Key, [title,status,sourceFile,sourceLine]), Props, Fields)), Rows)";
36
+
37
+ const INACTIVE_STATUSES = new Set([
38
+ "deprecated",
39
+ "removed",
40
+ "retired",
41
+ "superseded",
42
+ ]);
43
+
44
+ // implements REQ-cli-check
45
+ export async function collectSymbolCoordinatesMissingViolations(
46
+ prolog: Pick<PrologPort, "query">,
47
+ workspaceRoot: string,
48
+ rules: ReadonlySet<string>,
49
+ ): Promise<Violation[]> {
50
+ if (!rules.has(SYMBOL_COORDINATES_MISSING_RULE)) return [];
51
+ const rows = await prolog.query(SYMBOL_PLACEMENT_QUERY);
52
+ if (!rows.success)
53
+ throw new Error(
54
+ `symbol-coordinates-missing symbol projection failed: ${rows.error ?? "unknown error"}`,
55
+ );
56
+ const violations: Violation[] = [];
57
+ for (const row of parseListOfLists(rows.bindings.Rows ?? "[]")) {
58
+ const entity = parseEntityFromList(row);
59
+ const id = typeof entity.id === "string" ? entity.id : "";
60
+ const sourceFile =
61
+ typeof entity.sourceFile === "string" ? entity.sourceFile : "";
62
+ const status = typeof entity.status === "string" ? entity.status : "";
63
+ if (id === "" || sourceFile === "" || INACTIVE_STATUSES.has(status))
64
+ continue;
65
+ if (entity.sourceLine !== undefined && entity.sourceLine !== null) continue;
66
+ const absolute = path.resolve(workspaceRoot, sourceFile);
67
+ if (!existsSync(absolute) || !statSync(absolute).isFile()) continue;
68
+ const title = typeof entity.title === "string" ? entity.title : id;
69
+ violations.push({
70
+ rule: SYMBOL_COORDINATES_MISSING_RULE,
71
+ entityId: id,
72
+ source: sourceFile,
73
+ description: `${id} (${title}) has no symbol coordinates in ${sourceFile}: Kibi could not place it, so its links are checked against no code`,
74
+ suggestion:
75
+ "Run kibi sync --refresh-symbol-coordinates and read its failed lines; use the name the extractor gives the declaration, install the plugins and grammar packs kibi doctor names, or add symbol_role and granularity_reason for a file-level link.",
76
+ });
77
+ }
78
+ return violations;
79
+ }
@@ -99,13 +99,21 @@ export type ProofContract = Readonly<{
99
99
  | "state_machine"
100
100
  | "regex"
101
101
  | "source";
102
- domain_source?: Readonly<{ symbol_id: string; export?: string; field?: string }>;
102
+ domain_source?: Readonly<{
103
+ symbol_id: string;
104
+ export?: string;
105
+ field?: string;
106
+ /** A SWI-Prolog predicate's argument (1-based) that names each member. */
107
+ arg?: number;
108
+ }>;
103
109
  witness?: Readonly<{ path: string }>;
104
110
  constraint_source?: Readonly<{ fact_ids: readonly string[] }>;
105
111
  value_source?: readonly (
106
112
  | Readonly<{
107
113
  symbol_id: string;
108
114
  export?: string;
115
+ /** A SWI-Prolog predicate's argument (1-based) that holds the value. */
116
+ arg?: number;
109
117
  /** value (default): the export is a number; count: the size of a list, set, map or object. */
110
118
  measure?: "value" | "count";
111
119
  }>
@@ -130,12 +138,20 @@ export type ProofContract = Readonly<{
130
138
  domains?: Readonly<
131
139
  Record<
132
140
  string,
133
- | Readonly<{ symbol_id: string; export?: string }>
141
+ | Readonly<{ symbol_id: string; export?: string; arg?: number }>
134
142
  | Readonly<{ source: ProofSourceSpec }>
135
143
  >
136
144
  >;
137
- initial_source?: Readonly<{ symbol_id: string; export?: string }>;
138
- pattern_source?: Readonly<{ symbol_id: string; export?: string }>;
145
+ initial_source?: Readonly<{
146
+ symbol_id: string;
147
+ export?: string;
148
+ arg?: number;
149
+ }>;
150
+ pattern_source?: Readonly<{
151
+ symbol_id: string;
152
+ export?: string;
153
+ arg?: number;
154
+ }>;
139
155
  /** kind source: the project source Kibi reads. */
140
156
  source?: ProofSourceSpec;
141
157
  }>;
@@ -151,7 +167,8 @@ export type ProofSourceSpec = Readonly<Record<string, unknown>> &
151
167
  | "references"
152
168
  | "schema"
153
169
  | "routes"
154
- | "validator";
170
+ | "validator"
171
+ | "prolog";
155
172
  }>;
156
173
 
157
174
  export type ProofBinding = Readonly<{