kibi-cli 2.39.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 (163) hide show
  1. package/dist/cli-register-foundation.js +2 -2
  2. package/dist/commands/check.d.ts.map +1 -1
  3. package/dist/commands/check.js +33 -9
  4. package/dist/commands/doctor.d.ts.map +1 -1
  5. package/dist/commands/doctor.js +15 -0
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +4 -0
  8. package/dist/commands/migrate-plan-record.d.ts +18 -0
  9. package/dist/commands/migrate-plan-record.d.ts.map +1 -0
  10. package/dist/commands/migrate-plan-record.js +112 -0
  11. package/dist/commands/migrate.d.ts +11 -2
  12. package/dist/commands/migrate.d.ts.map +1 -1
  13. package/dist/commands/migrate.js +53 -7
  14. package/dist/commands/prove.d.ts.map +1 -1
  15. package/dist/commands/prove.js +18 -3
  16. package/dist/commands/sync/manifest.d.ts.map +1 -1
  17. package/dist/commands/sync/manifest.js +17 -4
  18. package/dist/commands/sync.d.ts.map +1 -1
  19. package/dist/commands/sync.js +8 -0
  20. package/dist/commands/telemetry.d.ts.map +1 -1
  21. package/dist/commands/telemetry.js +12 -2
  22. package/dist/extractors/symbol-title-match.d.ts +31 -0
  23. package/dist/extractors/symbol-title-match.d.ts.map +1 -0
  24. package/dist/extractors/symbol-title-match.js +133 -0
  25. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  26. package/dist/extractors/symbols-coordinator.js +81 -12
  27. package/dist/operations/bootstrap/discovery-evidence.js +2 -2
  28. package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
  29. package/dist/operations/bootstrap/guidance-actions.js +12 -1
  30. package/dist/operations/bootstrap/plugin-offers.d.ts +7 -1
  31. package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
  32. package/dist/operations/bootstrap/plugin-offers.js +73 -3
  33. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
  34. package/dist/operations/modeling/logic-modeling.js +2 -1
  35. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  36. package/dist/operations/modeling/model-requirement.js +2 -1
  37. package/dist/operations/mutation/symbol-refresh.d.ts +2 -0
  38. package/dist/operations/mutation/symbol-refresh.d.ts.map +1 -1
  39. package/dist/operations/mutation/symbol-refresh.js +6 -1
  40. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  41. package/dist/operations/mutation/upsert.js +7 -0
  42. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  43. package/dist/operations/planning/compile-intent.js +2 -1
  44. package/dist/operations/proof/claim-bindings.d.ts +11 -0
  45. package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
  46. package/dist/operations/proof/claim-bindings.js +144 -1
  47. package/dist/operations/proof/code-certificates.d.ts +10 -3
  48. package/dist/operations/proof/code-certificates.d.ts.map +1 -1
  49. package/dist/operations/proof/code-certificates.js +65 -13
  50. package/dist/operations/proof/code-languages.d.ts +104 -0
  51. package/dist/operations/proof/code-languages.d.ts.map +1 -0
  52. package/dist/operations/proof/code-languages.js +119 -0
  53. package/dist/operations/proof/code-models.d.ts +2 -0
  54. package/dist/operations/proof/code-models.d.ts.map +1 -1
  55. package/dist/operations/proof/code-models.js +11 -5
  56. package/dist/operations/proof/code-runner.d.ts +12 -9
  57. package/dist/operations/proof/code-runner.d.ts.map +1 -1
  58. package/dist/operations/proof/code-runner.js +81 -38
  59. package/dist/operations/proof/code-scope.d.ts +8 -0
  60. package/dist/operations/proof/code-scope.d.ts.map +1 -1
  61. package/dist/operations/proof/code-scope.js +30 -1
  62. package/dist/operations/proof/explain.d.ts +13 -0
  63. package/dist/operations/proof/explain.d.ts.map +1 -1
  64. package/dist/operations/proof/explain.js +66 -0
  65. package/dist/operations/proof/ingest-proof.d.ts +2 -0
  66. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  67. package/dist/operations/proof/ingest-proof.js +1 -0
  68. package/dist/operations/proof/java-package-shadow.d.ts +14 -0
  69. package/dist/operations/proof/java-package-shadow.d.ts.map +1 -0
  70. package/dist/operations/proof/java-package-shadow.js +389 -0
  71. package/dist/operations/proof/prolog-evaluator.d.ts +14 -0
  72. package/dist/operations/proof/prolog-evaluator.d.ts.map +1 -0
  73. package/dist/operations/proof/prolog-evaluator.js +247 -0
  74. package/dist/operations/proof/prolog-source-reader.d.ts +20 -0
  75. package/dist/operations/proof/prolog-source-reader.d.ts.map +1 -0
  76. package/dist/operations/proof/prolog-source-reader.js +1123 -0
  77. package/dist/operations/proof/source-code-readers.d.ts +6 -0
  78. package/dist/operations/proof/source-code-readers.d.ts.map +1 -1
  79. package/dist/operations/proof/source-code-readers.js +879 -75
  80. package/dist/plugins/approved-source-analyzers.generated.d.ts +13 -35
  81. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
  82. package/dist/plugins/approved-source-analyzers.generated.js +13 -35
  83. package/dist/plugins/plugin-install-check.d.ts +21 -0
  84. package/dist/plugins/plugin-install-check.d.ts.map +1 -0
  85. package/dist/plugins/plugin-install-check.js +62 -0
  86. package/dist/plugins/proof-reference-extractors.d.ts +20 -0
  87. package/dist/plugins/proof-reference-extractors.d.ts.map +1 -0
  88. package/dist/plugins/proof-reference-extractors.js +104 -0
  89. package/dist/plugins/reference-language-suggestion.d.ts +51 -0
  90. package/dist/plugins/reference-language-suggestion.d.ts.map +1 -0
  91. package/dist/plugins/reference-language-suggestion.js +277 -0
  92. package/dist/plugins/registry.d.ts.map +1 -1
  93. package/dist/plugins/registry.js +3 -1
  94. package/dist/plugins/source-analysis-service.d.ts.map +1 -1
  95. package/dist/plugins/source-analysis-service.js +4 -0
  96. package/dist/plugins/source-change-analysis.d.ts +26 -1
  97. package/dist/plugins/source-change-analysis.d.ts.map +1 -1
  98. package/dist/plugins/source-change-analysis.js +77 -5
  99. package/dist/plugins/source-classification.d.ts.map +1 -1
  100. package/dist/plugins/source-classification.js +23 -3
  101. package/dist/public/operations/catalog.d.ts +32 -7
  102. package/dist/public/operations/catalog.d.ts.map +1 -1
  103. package/dist/public/operations/check-executor.d.ts.map +1 -1
  104. package/dist/public/operations/check-executor.js +3 -0
  105. package/dist/public/operations/evidence-floor.d.ts +8 -0
  106. package/dist/public/operations/evidence-floor.d.ts.map +1 -1
  107. package/dist/public/operations/evidence-floor.js +19 -1
  108. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  109. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  110. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  111. package/dist/public/operations/specs/check.d.ts +1 -1
  112. package/dist/public/operations/specs/mutation-schemas.d.ts +31 -6
  113. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  114. package/dist/public/operations/specs/reporting.d.ts +8 -0
  115. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  116. package/dist/public/operations/specs/reporting.js +26 -3
  117. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  118. package/dist/public/operations/specs/semantic.js +2 -1
  119. package/dist/public/operations/specs/upsert.d.ts +31 -6
  120. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  121. package/dist/public/operations/symbol-coordinates-check.d.ts +11 -0
  122. package/dist/public/operations/symbol-coordinates-check.d.ts.map +1 -0
  123. package/dist/public/operations/symbol-coordinates-check.js +66 -0
  124. package/dist/public/proof-protocol.d.ts +31 -6
  125. package/dist/public/proof-protocol.d.ts.map +1 -1
  126. package/dist/public/proof-protocol.js +45 -15
  127. package/dist/public/proof-sources.d.ts +4 -2
  128. package/dist/public/proof-sources.d.ts.map +1 -1
  129. package/dist/public/proof-sources.js +43 -4
  130. package/dist/public/skills/kibi-usage/SKILL.md +6 -3
  131. package/dist/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
  132. package/dist/public/skills/kibi-usage/resources/proof.md +44 -3
  133. package/dist/schemas/entity.schema.json +34 -6
  134. package/dist/traceability/analysis-gate.d.ts +3 -1
  135. package/dist/traceability/analysis-gate.d.ts.map +1 -1
  136. package/dist/traceability/analysis-gate.js +9 -1
  137. package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
  138. package/dist/traceability/staged-file-coverage.js +7 -2
  139. package/dist/traceability/symbol-extract.d.ts +17 -0
  140. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  141. package/dist/traceability/symbol-extract.js +69 -15
  142. package/dist/traceability/validate.d.ts.map +1 -1
  143. package/dist/traceability/validate.js +5 -7
  144. package/dist/utils/first-sentence.d.ts +9 -0
  145. package/dist/utils/first-sentence.d.ts.map +1 -0
  146. package/dist/utils/first-sentence.js +52 -0
  147. package/dist/utils/rule-registry.generated.d.ts +6 -0
  148. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  149. package/dist/utils/rule-registry.generated.js +7 -0
  150. package/package.json +5 -5
  151. package/src/public/operations/check-executor.ts +8 -0
  152. package/src/public/operations/evidence-floor.ts +29 -1
  153. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  154. package/src/public/operations/specs/reporting.ts +38 -3
  155. package/src/public/operations/specs/semantic.ts +2 -1
  156. package/src/public/operations/symbol-coordinates-check.ts +79 -0
  157. package/src/public/proof-protocol-types.d.ts +22 -5
  158. package/src/public/proof-protocol.ts +78 -19
  159. package/src/public/proof-sources.ts +51 -3
  160. package/src/public/skills/kibi-usage/SKILL.md +6 -3
  161. package/src/public/skills/kibi-usage/resources/prolog-proofs.md +207 -0
  162. package/src/public/skills/kibi-usage/resources/proof.md +44 -3
  163. package/src/schemas/entity.schema.json +34 -6
@@ -21,8 +21,8 @@ export function registerFoundationCommands(program) {
21
21
  .option("--dry-run", "Preview migration changes without writing files")
22
22
  .option("--yes", "Apply migration changes without prompting")
23
23
  .option("--format <format>", "Output format: json|table", "table")
24
- .option("--apply-safe", "Apply only explicitly approved deterministic migration actions")
25
- .option("--approved-plan-hash <sha256>", "Exact migration plan hash approved for --apply-safe")
24
+ .option("--apply-safe [sha256]", "Apply only explicitly approved deterministic migration actions of the plan with this hash")
25
+ .option("--approved-plan-hash <sha256>", "Exact migration plan hash approved for --apply-safe (same as --apply-safe <sha256>)")
26
26
  .option("--backlog", "List every quality and coverage backlog action instead of counts per code")
27
27
  .option("--approved-action <id>", "Approve one migration action (repeatable through comma-separated IDs)", (value, previous = []) => [
28
28
  ...previous,
@@ -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;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"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAuF7C,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,CAyuB/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"}
@@ -20,7 +20,7 @@ import { EngineClient } from "../engine.js";
20
20
  import { extractFromManifestString } from "../extractors/manifest.js";
21
21
  import { extractFromMarkdownString, } from "../extractors/markdown.js";
22
22
  import { createMaintenanceSourceAnalysisService, fingerprintMaintenanceSourceSet, readSnapshotSourceConfig, } from "../plugins/maintenance-source-analysis.js";
23
- import { analyzeSourceChanges, assertSourceAnalysisGate, } from "../plugins/source-change-analysis.js";
23
+ import { analyzeSourceChanges, assertSourceAnalysisGate, partialAnalysisReviews, } from "../plugins/source-change-analysis.js";
24
24
  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";
@@ -45,7 +45,7 @@ import { classifyKibiImpactEvidence, isBehaviorSourceEdit, parseKibiImpactOverri
45
45
  import { stagedInventoryDriftViolations } from "../traceability/staged-inventory-drift.js";
46
46
  import { stagedCommitCarriesMigration } from "../traceability/staged-migration.js";
47
47
  import { assessStagedSymbolsManifest, collectStagedAuthoredSymbolsManifestEvidence, } from "../traceability/staged-symbols-manifest.js";
48
- import { createManifestLookupSentinelKey, extractSymbolsFromStagedFileAsync, } from "../traceability/symbol-extract.js";
48
+ import { createManifestLookupSentinelKey, extractSymbolsFromStagedFileAsync, partialAnalysisSymbolsUsable, } from "../traceability/symbol-extract.js";
49
49
  import { cleanupTempKb, consultOverlay, createOverlayFacts, createTempKb, projectStagedEntities, } from "../traceability/temp-kb.js";
50
50
  import { formatCoverageViolations, formatViolations as formatStagedViolations, validateStagedSymbolCoverage, validateStagedSymbols, } from "../traceability/validate.js";
51
51
  import { resolveReadBranchAttachment } from "../utils/branch-resolver.js";
@@ -321,7 +321,7 @@ function noValidatedSymbolsMessage(sourceAnalysis) {
321
321
  return [`${analysis.path}${provider}`];
322
322
  });
323
323
  if (partialFiles.length > 0) {
324
- return `Partial source analysis was reviewed for ${partialFiles.join(", ")}; no fully analyzed exported symbols or staged entities were available for symbol validation.`;
324
+ return `Partial source analysis was reviewed for ${partialFiles.join(", ")}; the staged change touches no declaration the analyzer placed and no staged entity.`;
325
325
  }
326
326
  return "No exported symbols or staged entities found in staged files.";
327
327
  }
@@ -480,12 +480,30 @@ export async function checkCommand(options) {
480
480
  const trustedSourceConfig = readSnapshotSourceConfig(snapshot, snapshot.baseTree);
481
481
  const sourceService = createMaintenanceSourceAnalysisService(process.cwd(), trustedSourceConfig);
482
482
  const sourceAnalysis = await analyzeSourceChanges(stagedInventory, sourceService);
483
+ // A partial result still places its declarations: they are checked
484
+ // like fully analyzed ones, and only a staged line in a gap outside
485
+ // them keeps the file at file-level review.
486
+ const partialReviews = partialAnalysisReviews(stagedInventory, sourceAnalysis);
487
+ const partialReviewPaths = new Set(partialReviews.map((review) => review.path));
488
+ const impactPolicyEnabled = stagedInventory.length > 0 && hasValidBaseImpactPolicy(snapshot);
489
+ const partialSymbolPaths = new Set();
483
490
  for (const file of stagedInventory) {
484
- const analysis = sourceAnalysis.get(file.path);
485
- if (analysis?.after?.status === "ok") {
491
+ const after = sourceAnalysis.get(file.path)?.after;
492
+ if (after?.status === "ok") {
486
493
  file.analysisDepth = "symbol";
487
494
  file.disposition = "checked";
488
495
  }
496
+ else if (after &&
497
+ file.status !== "D" &&
498
+ !file.skipReason &&
499
+ partialAnalysisSymbolsUsable(after)) {
500
+ partialSymbolPaths.add(file.path);
501
+ // An impact review binds the classified depth; keep it there.
502
+ if (!impactPolicyEnabled && !partialReviewPaths.has(file.path)) {
503
+ file.analysisDepth = "symbol";
504
+ file.disposition = "checked";
505
+ }
506
+ }
489
507
  }
490
508
  const mergeInherited = snapshot.mergeInherited ?? [];
491
509
  const mergeNote = mergeInherited.length > 0
@@ -495,7 +513,11 @@ export async function checkCommand(options) {
495
513
  const renameNote = renameResolved.length > 0
496
514
  ? `Baseline: HEAD with ${renameResolved.length} staged knowledge rename(s) into .kb/ resolved; renamed files are judged only on what this commit changed in them. Run kibi check for the full report.`
497
515
  : undefined;
498
- const baselineNotes = [mergeNote, renameNote].filter((note) => note !== undefined);
516
+ const baselineNotes = [
517
+ mergeNote,
518
+ renameNote,
519
+ ...partialReviews.map((review) => `Partial source analysis: staged line(s) ${review.lines.map((range) => (range.startLine === range.endLine ? `${range.startLine}` : `${range.startLine}-${range.endLine}`)).join(", ")} of ${review.path} fall outside every declaration the analyzer placed (${review.detail}); review that change at file level.`),
520
+ ].filter((note) => note !== undefined);
499
521
  const printNotedResult = (input) => {
500
522
  printStagedResult(baselineNotes.length === 0
501
523
  ? input
@@ -535,7 +557,6 @@ export async function checkCommand(options) {
535
557
  record.providerId =
536
558
  analysis.after?.providerId ?? analysis.before?.providerId ?? null;
537
559
  }
538
- const impactPolicyEnabled = stagedInventory.length > 0 && hasValidBaseImpactPolicy(snapshot);
539
560
  // One rule decides which analysis gaps block (see analysis-gate): the
540
561
  // committed side never blocks, and an after-side local gap blocks only
541
562
  // where it overlaps the staged lines. With a policy, the impact review
@@ -568,9 +589,12 @@ export async function checkCommand(options) {
568
589
  return { exitCode: 0 };
569
590
  }
570
591
  const symbolPaths = new Set(stagedInventory
571
- .filter((file) => file.analysisDepth === "symbol")
592
+ .filter((file) => file.analysisDepth === "symbol" ||
593
+ partialSymbolPaths.has(file.path))
572
594
  .map((file) => file.path));
573
- const sourceFiles = stagedFiles.filter((file) => symbolPaths.has(file.path));
595
+ const sourceFiles = supportedStagedFiles(stagedInventory.map((file) => partialSymbolPaths.has(file.path)
596
+ ? { ...file, analysisDepth: "symbol" }
597
+ : file)).filter((file) => symbolPaths.has(file.path));
574
598
  const markdownFiles = stagedFiles.filter((file) => file.path.endsWith(".md") && isEntityLanePath(file.path));
575
599
  const markdownErrors = [];
576
600
  for (const f of markdownFiles) {
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAiHA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wEAAwE;AACxE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,GACpD,MAAM,GAAG,SAAS,CAUpB;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyH/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":"AAmHA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wEAAwE;AACxE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,GACpD,MAAM,GAAG,SAAS,CAUpB;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyH/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"}
@@ -22,7 +22,9 @@ import * as path from "node:path";
22
22
  import { fileURLToPath } from "node:url";
23
23
  import { bootstrapKibiEnvironment, secretSourceFromBootstrap, } from "../env/bootstrap.js";
24
24
  import { kibiPackageVersions } from "../package-versions.js";
25
+ import { pluginInstallProblems } from "../plugins/plugin-install-check.js";
25
26
  import { describeConfiguredCapabilityPlugins, readProjectKibiConfig, } from "../plugins/project-config.js";
27
+ import { workspaceReferenceLanguageNote } from "../plugins/reference-language-suggestion.js";
26
28
  import { SwiplResolutionError, inspectSwiplBundle, probeRequiredLibraries, resolveSwipl, } from "../prolog/swipl-resolver.js";
27
29
  import { buildMigrationPlan, migrationAction, } from "../public/operations/migration-plan.js";
28
30
  import { noteCliErrorCategory } from "../usage-telemetry.js";
@@ -443,10 +445,14 @@ function checkCapabilityPlugins() {
443
445
  const bootstrap = bootstrapKibiEnvironment();
444
446
  const workspaceRoot = bootstrap.workspaceRoot;
445
447
  const rows = describeConfiguredCapabilityPlugins(workspaceRoot);
448
+ const languages = workspaceReferenceLanguageNote(workspaceRoot);
446
449
  if (rows.length === 0) {
447
450
  return {
448
451
  passed: true,
449
452
  message: "None configured; builtin providers only",
453
+ ...(languages === null
454
+ ? {}
455
+ : { warning: true, remediation: languages }),
450
456
  };
451
457
  }
452
458
  const parts = rows.map((row) => `${row.package} ${row.capability} ${row.mode} declared=${row.declared ? "yes" : "no"}`);
@@ -461,6 +467,14 @@ function checkCapabilityPlugins() {
461
467
  const packages = [
462
468
  ...new Set((config.plugins ?? []).map((plugin) => plugin.package)),
463
469
  ];
470
+ const installProblems = pluginInstallProblems(workspaceRoot, packages);
471
+ if (installProblems.length > 0) {
472
+ return {
473
+ passed: false,
474
+ message: `${parts.join("; ")}; ${installProblems.map((row) => row.problem).join("; ")}`,
475
+ remediation: installProblems.map((row) => row.fix).join(" "),
476
+ };
477
+ }
464
478
  const missingSecrets = [];
465
479
  // Secrets whose plugin only augments a builtin provider: without them the
466
480
  // plugin is skipped and the builtin keeps working, so doctor warns.
@@ -513,6 +527,7 @@ function checkCapabilityPlugins() {
513
527
  return {
514
528
  passed: true,
515
529
  message,
530
+ ...(languages === null ? {} : { warning: true, remediation: languages }),
516
531
  };
517
532
  }
518
533
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA8GA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkFD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0L/B"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA+GA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkFD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA4L/B"}
@@ -19,6 +19,7 @@ import { existsSync, lstatSync, realpathSync } from "node:fs";
19
19
  import * as path from "node:path";
20
20
  import { fileURLToPath } from "node:url";
21
21
  import { classifyActivation } from "../operations/bootstrap/activation.js";
22
+ import { workspaceReferenceLanguageNote } from "../plugins/reference-language-suggestion.js";
22
23
  import { nodeFilesystem } from "../public/operations/node-ports.js";
23
24
  import { resolveBranchAttachment } from "../utils/branch-resolver.js";
24
25
  import { readLegacyKbConfig } from "../utils/config.js";
@@ -268,6 +269,9 @@ export async function initCommand(options) {
268
269
  console.log(legacyConfig
269
270
  ? " Next: run 'kibi migrate --yes' to move the legacy knowledge into .kb/."
270
271
  : (await initNextAction(projectRoot)).message);
272
+ const plugins = workspaceReferenceLanguageNote(projectRoot);
273
+ if (plugins !== null)
274
+ console.log(` Suggested plugin: ${plugins}`);
271
275
  console.log(" Optional diagnostic: run 'kibi doctor' if setup appears degraded.");
272
276
  if (options.github === true) {
273
277
  scaffoldGitHubIntegration({
@@ -0,0 +1,18 @@
1
+ import type { MigrationPlan } from "../public/operations/migration-plan.js";
2
+ export type PrintedPlan = Readonly<{
3
+ planHash: string;
4
+ printedAt: string;
5
+ expected: MigrationPlan["expected"];
6
+ actions: readonly Readonly<{
7
+ id: string;
8
+ code: string;
9
+ state: string;
10
+ }>[];
11
+ }>;
12
+ /** Remember a plan `kibi migrate` printed; a write failure is ignored. */
13
+ export declare function recordPrintedPlan(workspaceRoot: string, plan: MigrationPlan, now?: Date): void;
14
+ /** The printed plan with this hash, if `kibi migrate` printed it here. */
15
+ export declare function findPrintedPlan(workspaceRoot: string, planHash: string): PrintedPlan | undefined;
16
+ /** What differs between a printed plan and the current one, one line each. */
17
+ export declare function describePlanChange(printed: PrintedPlan, current: MigrationPlan): string[];
18
+ //# sourceMappingURL=migrate-plan-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-plan-record.d.ts","sourceRoot":"","sources":["../../src/commands/migrate-plan-record.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAY5E,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,OAAO,EAAE,SAAS,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CAC3E,CAAC,CAAC;AA0BH,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,aAAa,EACnB,GAAG,GAAE,IAAiB,GACrB,IAAI,CA0BN;AAGD,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,WAAW,GAAG,SAAS,CAIzB;AAmBD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,aAAa,GACrB,MAAM,EAAE,CA0BV"}
@@ -0,0 +1,112 @@
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
+ import * as fs from "node:fs";
19
+ import * as path from "node:path";
20
+ /**
21
+ * The migration plans `kibi migrate` printed recently, so an approval of a
22
+ * plan that has since changed can say what changed. The file lives in the
23
+ * gitignored `.kb/migrations/` and is only a reading aid: a plan applies only
24
+ * with its current hash whatever this file says.
25
+ */
26
+ const RECORD_FILE = "printed-plans.json";
27
+ const MAX_RECORDS = 8;
28
+ function recordPath(workspaceRoot) {
29
+ return path.join(workspaceRoot, ".kb", "migrations", RECORD_FILE);
30
+ }
31
+ function readRecords(workspaceRoot) {
32
+ try {
33
+ const parsed = JSON.parse(fs.readFileSync(recordPath(workspaceRoot), "utf8"));
34
+ return Array.isArray(parsed)
35
+ ? parsed.filter((entry) => typeof entry === "object" &&
36
+ entry !== null &&
37
+ typeof entry.planHash === "string" &&
38
+ Array.isArray(entry.actions))
39
+ : [];
40
+ }
41
+ catch {
42
+ return [];
43
+ }
44
+ }
45
+ // implements REQ-cli-schema-migration
46
+ /** Remember a plan `kibi migrate` printed; a write failure is ignored. */
47
+ export function recordPrintedPlan(workspaceRoot, plan, now = new Date()) {
48
+ const entry = {
49
+ planHash: plan.planHash,
50
+ printedAt: now.toISOString(),
51
+ expected: plan.expected,
52
+ actions: plan.actions.map((action) => ({
53
+ id: action.id,
54
+ code: action.code,
55
+ state: action.state,
56
+ })),
57
+ };
58
+ const records = [
59
+ entry,
60
+ ...readRecords(workspaceRoot).filter((record) => record.planHash !== plan.planHash),
61
+ ].slice(0, MAX_RECORDS);
62
+ try {
63
+ fs.mkdirSync(path.dirname(recordPath(workspaceRoot)), { recursive: true });
64
+ fs.writeFileSync(recordPath(workspaceRoot), `${JSON.stringify(records, null, 2)}\n`);
65
+ }
66
+ catch {
67
+ // The record only explains a changed plan; never fail a preview on it.
68
+ }
69
+ }
70
+ // implements REQ-cli-schema-migration
71
+ /** The printed plan with this hash, if `kibi migrate` printed it here. */
72
+ export function findPrintedPlan(workspaceRoot, planHash) {
73
+ return readRecords(workspaceRoot).find((record) => record.planHash === planHash);
74
+ }
75
+ const EXPECTED_LABELS = {
76
+ branch: "the Git branch",
77
+ kbBranch: "the KB branch",
78
+ kbSnapshotId: "the KB snapshot",
79
+ workspaceSnapshot: "the workspace files",
80
+ configHash: "the KB config",
81
+ };
82
+ /** A long hash cut to its first 12 characters; other values as they are. */
83
+ function short(value) {
84
+ if (value === null)
85
+ return "none";
86
+ return /^[0-9a-f]{20,}$/i.test(value) ? value.slice(0, 12) : value;
87
+ }
88
+ // implements REQ-cli-schema-migration
89
+ /** What differs between a printed plan and the current one, one line each. */
90
+ export function describePlanChange(printed, current) {
91
+ const lines = [];
92
+ const before = new Map(printed.actions.map((action) => [action.id, action]));
93
+ const after = new Map(current.actions.map((action) => [action.id, action]));
94
+ for (const action of current.actions) {
95
+ const old = before.get(action.id);
96
+ if (old === undefined)
97
+ lines.push(`added ${action.state} ${action.code}: ${action.id}`);
98
+ else if (old.state !== action.state)
99
+ lines.push(`${action.id} went from ${old.state} to ${action.state}`);
100
+ }
101
+ for (const action of printed.actions) {
102
+ if (!after.has(action.id))
103
+ lines.push(`removed ${action.state} ${action.code}: ${action.id}`);
104
+ }
105
+ for (const key of Object.keys(EXPECTED_LABELS)) {
106
+ const was = printed.expected?.[key] ?? null;
107
+ const now = current.expected[key];
108
+ if (was !== now)
109
+ lines.push(`${EXPECTED_LABELS[key]} changed (${short(was)} -> ${short(now)})`);
110
+ }
111
+ return lines;
112
+ }
@@ -1,9 +1,10 @@
1
- import type { MigrationAction } from "../public/operations/migration-plan.js";
1
+ import type { MigrationAction, MigrationPlan } from "../public/operations/migration-plan.js";
2
2
  interface MigrateOptions {
3
3
  dryRun?: boolean;
4
4
  yes?: boolean;
5
5
  format?: "json" | "table";
6
- applySafe?: boolean;
6
+ /** `--apply-safe [sha256]`: true, or the approved plan hash given with it. */
7
+ applySafe?: boolean | string;
7
8
  approvedPlanHash?: string;
8
9
  approvedActionIds?: string[];
9
10
  /** `--approved-action <id>` as the CLI parser spells it; same as approvedActionIds. */
@@ -60,6 +61,14 @@ export declare function migrateCommand(options?: MigrateOptions): Promise<{
60
61
  * (for example legacy links an earlier plan action already marked).
61
62
  */
62
63
  export declare function describeMigrationRun(summary: MigrationRunSummary): string;
64
+ /** The exact command that applies the plan with this hash. */
65
+ export declare function applyPlanCommand(planHash: string): string;
66
+ /**
67
+ * Why an approved hash is not the current plan's: what changed since that
68
+ * plan was printed here, when Kibi recorded it, and the command for the
69
+ * current plan.
70
+ */
71
+ export declare function planChangedMessage(workspaceRoot: string, approvedPlanHash: string, plan: MigrationPlan): string;
63
72
  /**
64
73
  * Review findings `kibi check` and `kb_status` report at any schema version:
65
74
  * quality and coverage work, not steps of the migration. A plan lists them
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAmEA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,wCAAwC,CAAC;AAyBhD,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;AAqLD,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,CAgkB9D;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAGzE;AAoZD;;;;;GAKG;AAEH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACpC,OAAO,CAOT"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAmEA,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EAEd,MAAM,wCAAwC,CAAC;AA8BhD,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,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;AAqLD,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,CAgkB9D;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAGzE;AAoUD,8DAA8D;AAE9D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,aAAa,GAClB,MAAM,CAeR;AAuGD;;;;;GAKG;AAEH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACpC,OAAO,CAOT"}
@@ -35,6 +35,7 @@ import { manifestMergeDriverGaps, mergeDriverSetup, } from "../utils/merge-drive
35
35
  import { LATEST_KB_SCHEMA_VERSION, getSchemaVersionStatus, normalizeSchemaVersion, } from "../utils/schema-version.js";
36
36
  import { updateGitIgnore } from "./init-helpers.js";
37
37
  import { applyLegacyStorageMigration, planLegacyStorageMigration, } from "./legacy-storage-migration.js";
38
+ import { describePlanChange, findPrintedPlan, recordPrintedPlan, } from "./migrate-plan-record.js";
38
39
  const MIGRATION_AUDIT_VERSION = 1;
39
40
  const SCHEMA_MIGRATION_STEPS = [
40
41
  {
@@ -441,7 +442,7 @@ export function warnMigrationRequiredWithoutYes() {
441
442
  }
442
443
  // implements REQ-003
443
444
  export async function migrateCommand(options = {}) {
444
- if (options.applySafe === true ||
445
+ if (applySafeRequested(options) ||
445
446
  options.format === "json" ||
446
447
  (options.yes !== true && options.dryRun !== true)) {
447
448
  return migratePlanCommand(options);
@@ -1054,27 +1055,68 @@ function printApplySummary(content) {
1054
1055
  }
1055
1056
  console.log("Run 'kibi migrate' for the remaining actions, or add --format json for the full result.");
1056
1057
  }
1058
+ /** True for `--apply-safe`, with or without the hash it may carry. */
1059
+ function applySafeRequested(options) {
1060
+ return (options.applySafe === true ||
1061
+ (typeof options.applySafe === "string" && options.applySafe !== ""));
1062
+ }
1063
+ /** The exact command that applies the plan with this hash. */
1064
+ // implements REQ-cli-schema-migration
1065
+ export function applyPlanCommand(planHash) {
1066
+ return `kibi migrate --apply-safe ${planHash}`;
1067
+ }
1068
+ /**
1069
+ * Why an approved hash is not the current plan's: what changed since that
1070
+ * plan was printed here, when Kibi recorded it, and the command for the
1071
+ * current plan.
1072
+ */
1073
+ // implements REQ-cli-schema-migration
1074
+ export function planChangedMessage(workspaceRoot, approvedPlanHash, plan) {
1075
+ const printed = findPrintedPlan(workspaceRoot, approvedPlanHash);
1076
+ const changes = printed ? describePlanChange(printed, plan) : [];
1077
+ const lines = [
1078
+ printed
1079
+ ? `The migration plan changed since ${approvedPlanHash} was printed (${printed.printedAt}); its hash is now ${plan.planHash}. Nothing was applied.`
1080
+ : `${approvedPlanHash} is not the current migration plan; its hash is now ${plan.planHash}. Kibi has no record of printing ${approvedPlanHash} here, so it cannot say what changed. Nothing was applied.`,
1081
+ ...(printed
1082
+ ? changes.length > 0
1083
+ ? ["What changed:", ...changes.map((change) => `- ${change}`)]
1084
+ : ["Its actions and inputs are the same; only their details changed."]
1085
+ : []),
1086
+ `Review the current plan with 'kibi migrate', then apply it with: ${applyPlanCommand(plan.planHash)}`,
1087
+ ];
1088
+ return lines.join("\n");
1089
+ }
1057
1090
  async function migratePlanCommand(options) {
1058
1091
  const workspaceRoot = path.resolve(options.workspaceRoot ?? process.cwd());
1059
1092
  const plan = await buildWorkspaceMigrationPlan(workspaceRoot);
1093
+ const applySafe = applySafeRequested(options);
1060
1094
  // `--yes` with JSON output applies every ready automatic action of the plan
1061
1095
  // it would otherwise only print; `--dry-run` still only prints it.
1062
- const approveWholePlan = options.applySafe !== true &&
1096
+ const approveWholePlan = !applySafe &&
1063
1097
  options.yes === true &&
1064
1098
  options.dryRun !== true &&
1065
1099
  options.format === "json";
1066
- if (options.applySafe === true || approveWholePlan) {
1100
+ if (applySafe || approveWholePlan) {
1101
+ const inlineHash = typeof options.applySafe === "string" ? options.applySafe : undefined;
1102
+ if (inlineHash !== undefined &&
1103
+ options.approvedPlanHash !== undefined &&
1104
+ inlineHash !== options.approvedPlanHash) {
1105
+ noteCliErrorCategory("migrate:approved_plan_hash_conflict");
1106
+ console.error(`--apply-safe ${inlineHash} and --approved-plan-hash ${options.approvedPlanHash} name different plans; give one hash. The current plan applies with: ${applyPlanCommand(plan.planHash)}`);
1107
+ return { exitCode: 2 };
1108
+ }
1067
1109
  const approvedPlanHash = approveWholePlan
1068
1110
  ? plan.planHash
1069
- : options.approvedPlanHash;
1111
+ : (inlineHash ?? options.approvedPlanHash);
1070
1112
  if (!approvedPlanHash) {
1071
1113
  noteCliErrorCategory("migrate:approved_plan_hash_missing");
1072
- console.error(`--apply-safe requires --approved-plan-hash <sha256>. Review the plan with 'kibi migrate', then approve its current hash: kibi migrate --apply-safe --approved-plan-hash ${plan.planHash}`);
1114
+ console.error(`--apply-safe needs the hash of the plan you reviewed. Review the plan with 'kibi migrate', then apply its current hash: ${applyPlanCommand(plan.planHash)}`);
1073
1115
  return { exitCode: 2 };
1074
1116
  }
1075
1117
  if (approvedPlanHash !== plan.planHash) {
1076
1118
  noteCliErrorCategory("migrate:plan_hash_changed");
1077
- console.error(`Migration plan changed; regenerate the plan and approve its current hash: kibi migrate --apply-safe --approved-plan-hash ${plan.planHash}`);
1119
+ console.error(planChangedMessage(workspaceRoot, approvedPlanHash, plan));
1078
1120
  return { exitCode: 2 };
1079
1121
  }
1080
1122
  const explicitActionIds = approveWholePlan
@@ -1125,6 +1167,8 @@ async function migratePlanCommand(options) {
1125
1167
  else {
1126
1168
  printPlanText(plan, options.backlog === true);
1127
1169
  }
1170
+ if (options.dryRun !== true)
1171
+ recordPrintedPlan(workspaceRoot, plan);
1128
1172
  return { exitCode: 0 };
1129
1173
  }
1130
1174
  /**
@@ -1174,5 +1218,7 @@ function printPlanText(plan, listBacklog) {
1174
1218
  console.log(" List each item with --backlog.");
1175
1219
  }
1176
1220
  }
1177
- console.log(`Plan status: ${plan.status} (covers both sections). Use --format json for structured actions, or --apply-safe with the approved plan hash.`);
1221
+ console.log(`Plan status: ${plan.status} (covers both sections). Use --format json for structured actions.`);
1222
+ if (automaticReady > 0)
1223
+ console.log(`Apply the ${automaticReady} ready automatic action(s) of this plan: ${applyPlanCommand(plan.planHash)}`);
1178
1224
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"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"}
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;AAajE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAEnF,OAAO,EAIL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAKrC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAGH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACzC,CAAC,CAAC;AAEH,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5C;;;;;GAKG;AAEH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,GAC1D,MAAM,CAiBR;AAED;;;;GAIG;AAEH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,CAAC,CAUb;AAQD,wBAAgB,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEjD;AAaD,wEAAwE;AAExE,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAGD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,gBAAgB,EAC7B,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,UAAU,CAWnB;AAED,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,wBAAwB,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpC,CAAC;AAEF,yEAAyE;AACzE,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgB/B;AAcD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,GAAG,IAAI,EAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,GACnD,GAAG,CAAC,MAAM,CAAC,CASb;AAED;;;;;;GAMG;AAEH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,SAAS,YAAY,EAAE,GAC7B;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAyBxD;AA8ED;;;;GAIG;AAEH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiBtC;AA8JD,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,GAAE,wBAA6B,GAClC,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA2V/B;AAED,sEAAsE;AAEtE,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAoBpC;AAED;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC/C,YAAY,CAsCd;AAED,8DAA8D;AAE9D,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,+DAA+D;IAC/D,SAAS,EAAE,SAAS,QAAQ,CAAC;QAC3B,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC,EAAE,CAAC;IACL,qEAAqE;IACrE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC,CAAC,CAAC;AAEH,8EAA8E;AAE9E,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAsB9B;AAED,+EAA+E;AAE/E,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAMD;;;;;;;;;;GAUG;AAEH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,WAAW,EAAE,mBAAmB,CAAC;CAClC,GAAG,YAAY,CAuFf"}
@@ -373,7 +373,7 @@ async function selectTestsBySelector(context, options) {
373
373
  // One line per claim a certificate test names in proves: derived (with its
374
374
  // scope), attested, or rejected with the reason.
375
375
  function claimBindingLines(result) {
376
- return result.results.flatMap((row) => (row.claimBindings ?? []).map((binding) => `${row.testId} ${binding.claim_key}${binding.requirement_id ? ` (${binding.requirement_id})` : ""}: ${binding.binding}${binding.binding === "derived" && binding.scope ? `, ${binding.scope} scope` : ""}${binding.reason ? `: ${binding.reason}` : ""}`));
376
+ return result.results.flatMap((row) => (row.claimBindings ?? []).map((binding) => `${row.testId} ${binding.claim_key}${binding.requirement_id ? ` (${binding.requirement_id})` : ""}: ${binding.binding}${binding.binding === "derived" && binding.scope ? `, ${binding.scope} scope` : ""}${binding.reason ? `: ${binding.reason}` : ""}${binding.binding === "derived" && row.scope !== undefined && row.scope !== "end_to_end" ? `; the receipt's verification_scope is ${row.scope}, and a claim is proved only once its requirement is tested end to end, so kibi proof explain keeps it unproved until an end_to_end receipt covers the scenario` : ""}`));
377
377
  }
378
378
  // implements REQ-kibi-code-proof-kinds
379
379
  // One line per certificate test whose certificate did not re-check: the test
@@ -385,8 +385,21 @@ function certificateRejectionLines(result) {
385
385
  `${row.testId} ${row.kind ?? "certificate"}: certificate rejected, ${row.certificateRejection}`,
386
386
  ]);
387
387
  }
388
+ // implements REQ-kibi-code-proof-kinds
389
+ // A test whose run passed but whose certificate or claim binding Kibi
390
+ // rejected is refused, not passed: it proves nothing about the code.
391
+ function refusedCount(result) {
392
+ return result.results.filter((row) => row.outcome === "passed" &&
393
+ (row.certificateRejection !== undefined ||
394
+ (row.claimBindings ?? []).some((binding) => binding.binding === "rejected"))).length;
395
+ }
388
396
  function summarize(result) {
389
- const parts = [`passed ${result.passed}`, `failed ${result.failed}`];
397
+ const refused = refusedCount(result);
398
+ const parts = [
399
+ `passed ${result.passed - refused}`,
400
+ ...(refused > 0 ? [`refused ${refused}`] : []),
401
+ `failed ${result.failed}`,
402
+ ];
390
403
  if (result.unchanged > 0)
391
404
  parts.push(`unchanged ${result.unchanged}`);
392
405
  return parts.join(", ");
@@ -599,7 +612,8 @@ export async function proveCommand(options, deps = {}) {
599
612
  failures.push(`the tracked workspace changed while receipts were applied; re-run kibi prove${describeWorkspaceDrift(afterIngest)}`);
600
613
  }
601
614
  }
602
- const passed = ingestResults.reduce((sum, result) => sum + result.passed, 0);
615
+ const refused = ingestResults.reduce((sum, result) => sum + refusedCount(result), 0);
616
+ const passed = ingestResults.reduce((sum, result) => sum + result.passed, 0) - refused;
603
617
  const failed = ingestResults.reduce((sum, result) => sum + result.failed, 0);
604
618
  const unchanged = ingestResults.reduce((sum, result) => sum + result.unchanged, 0);
605
619
  // implements REQ-kibi-code-proof-kinds
@@ -609,6 +623,7 @@ export async function proveCommand(options, deps = {}) {
609
623
  result.results.filter((row) => row.outcome === "passed" && row.evidenceLevel === "proved").length, 0);
610
624
  const summary = {
611
625
  passed,
626
+ ...(refused > 0 ? { refused } : {}),
612
627
  certified,
613
628
  failed,
614
629
  unchanged,
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,EAML,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,0BAA0B,EAG3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAI5E,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;CACjE;AAkBD,eAAO,MAAM,8BAA8B,QAc1C,CAAC;AA+BF;;;;;;;;;GASG;AACH,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAG7E;AA0HD,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAwSvC;AAED;;;;;;;;GAQG;AAEH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,MAAM,GAAG,IAAI,CAWf;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAOT;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAST"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,EAML,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,0BAA0B,EAG3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAI5E,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;CACjE;AAkBD,eAAO,MAAM,8BAA8B,QAc1C,CAAC;AAqCF;;;;;;;;;GASG;AACH,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAG7E;AA2HD,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CA+SvC;AAED;;;;;;;;GAQG;AAEH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,MAAM,GAAG,IAAI,CAWf;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAOT;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAST"}
@@ -66,6 +66,12 @@ const GENERATED_COORD_FIELDS = [
66
66
  "sourceEndLine",
67
67
  "sourceEndColumn",
68
68
  ];
69
+ const INACTIVE_SYMBOL_STATUSES = new Set([
70
+ "deprecated",
71
+ "removed",
72
+ "retired",
73
+ "superseded",
74
+ ]);
69
75
  const GENERATED_MANIFEST_FIELDS = new Set([
70
76
  ...GENERATED_COORD_FIELDS,
71
77
  "coordinatesGeneratedAt",
@@ -173,11 +179,12 @@ function coarseAnchorFailureReason(entry) {
173
179
  if (typeof entry.coordinateRefreshFailure === "string") {
174
180
  return entry.coordinateRefreshFailure;
175
181
  }
182
+ const missed = `no unique declaration titled '${String(entry.title ?? "")}' was found in ${String(entry.sourceFile ?? "its source file")}`;
176
183
  const reason = entry.granularity_reason;
177
184
  if (!isCoarseGranularityReason(reason)) {
178
- return `extractor produced no coordinates; add symbol_role and granularity_reason ${COARSE_GRANULARITY_REASONS_PARENTHESIZED} to enable the whole-file coarse fallback`;
185
+ return `${missed}; use the name the extractor gives the declaration`;
179
186
  }
180
- return "extractor produced no coordinates and the whole-file coarse fallback found no span for this symbol";
187
+ return `${missed} and the whole-file coarse fallback found no span for this symbol`;
181
188
  }
182
189
  // implements REQ-symbol-coordinates-derived-locally
183
190
  export async function refreshManifestCoordinates(
@@ -333,7 +340,13 @@ manifestPath, workspaceRoot, deps) {
333
340
  : typeof previous.sourceFile === "string"
334
341
  ? previous.sourceFile
335
342
  : undefined, workspaceRoot, resolved);
336
- if (eligible && !hasAllGeneratedCoordinates(current)) {
343
+ // A missing source file is no refresh candidate, but an active symbol
344
+ // that names one still gets no coordinates, so it is reported.
345
+ const unreadable = !coarseAnchor &&
346
+ !eligible &&
347
+ typeof current.coordinateRefreshFailure === "string" &&
348
+ !INACTIVE_SYMBOL_STATUSES.has(String(current.status ?? ""));
349
+ if ((eligible || unreadable) && !hasAllGeneratedCoordinates(current)) {
337
350
  failures.push({
338
351
  id: typeof current.id === "string" ? current.id : `#${i}`,
339
352
  reason: coarseAnchorFailureReason(current),
@@ -401,7 +414,7 @@ manifestPath, workspaceRoot, deps) {
401
414
  console.log(` ... and ${failures.length - maxReportedFailures} more failed symbol(s)`);
402
415
  }
403
416
  if (failures.length > 0) {
404
- console.log(" Symbols without a published coordinate entry are dropped from coverage until they succeed.");
417
+ console.log(` Symbols without a published coordinate entry are dropped from coverage until they succeed. To link a whole file instead, add symbol_role and granularity_reason ${COARSE_GRANULARITY_REASONS_PARENTHESIZED} to the symbol.`);
405
418
  }
406
419
  }
407
420
  return { artifactChanged };