kibi-cli 2.1.0 → 2.3.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 (398) hide show
  1. package/dist/cli-operation-loader.d.ts.map +1 -1
  2. package/dist/cli-operation-loader.js +3 -0
  3. package/dist/cli-operation-metadata.d.ts +4 -0
  4. package/dist/cli-operation-metadata.d.ts.map +1 -1
  5. package/dist/cli-operation-metadata.js +5 -0
  6. package/dist/cli-protocol.d.ts.map +1 -1
  7. package/dist/cli-protocol.js +3 -2
  8. package/dist/cli-register-reporting.d.ts.map +1 -1
  9. package/dist/cli-register-reporting.js +4 -0
  10. package/dist/commands/aggregated-checks.d.ts +7 -0
  11. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  12. package/dist/commands/aggregated-checks.js +25 -1
  13. package/dist/commands/check-diff.d.ts +5 -0
  14. package/dist/commands/check-diff.d.ts.map +1 -0
  15. package/dist/commands/check-diff.js +62 -0
  16. package/dist/commands/check-generated.d.ts.map +1 -1
  17. package/dist/commands/check-generated.js +41 -18
  18. package/dist/commands/check.d.ts.map +1 -1
  19. package/dist/commands/check.js +231 -86
  20. package/dist/commands/doctor.d.ts.map +1 -1
  21. package/dist/commands/doctor.js +168 -53
  22. package/dist/commands/github-init.d.ts +1 -1
  23. package/dist/commands/github-init.d.ts.map +1 -1
  24. package/dist/commands/github-init.js +10 -3
  25. package/dist/commands/init-helpers.d.ts +17 -2
  26. package/dist/commands/init-helpers.d.ts.map +1 -1
  27. package/dist/commands/init-helpers.js +123 -23
  28. package/dist/commands/init.d.ts.map +1 -1
  29. package/dist/commands/init.js +110 -15
  30. package/dist/commands/prove.d.ts.map +1 -1
  31. package/dist/commands/prove.js +10 -18
  32. package/dist/commands/sync/cache.d.ts +20 -1
  33. package/dist/commands/sync/cache.d.ts.map +1 -1
  34. package/dist/commands/sync/cache.js +51 -2
  35. package/dist/commands/sync/discovery.d.ts.map +1 -1
  36. package/dist/commands/sync/discovery.js +1 -1
  37. package/dist/commands/sync/manifest.d.ts.map +1 -1
  38. package/dist/commands/sync/manifest.js +3 -1
  39. package/dist/commands/sync/persistence.d.ts.map +1 -1
  40. package/dist/commands/sync/persistence.js +8 -0
  41. package/dist/commands/sync.d.ts.map +1 -1
  42. package/dist/commands/sync.js +11 -3
  43. package/dist/engine.d.ts +41 -1
  44. package/dist/engine.d.ts.map +1 -1
  45. package/dist/engine.js +377 -80
  46. package/dist/extractors/manifest.d.ts.map +1 -1
  47. package/dist/extractors/manifest.js +66 -28
  48. package/dist/extractors/markdown.d.ts +2 -0
  49. package/dist/extractors/markdown.d.ts.map +1 -1
  50. package/dist/extractors/markdown.js +14 -3
  51. package/dist/extractors/relationships.d.ts.map +1 -1
  52. package/dist/extractors/relationships.js +1 -0
  53. package/dist/extractors/symbols-coordinator.d.ts +7 -0
  54. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  55. package/dist/extractors/symbols-coordinator.js +75 -39
  56. package/dist/intent-search.d.ts.map +1 -1
  57. package/dist/intent-search.js +68 -29
  58. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  59. package/dist/operations/bootstrap/generate.js +4 -3
  60. package/dist/operations/modeling/model-requirement.d.ts +1 -1
  61. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  62. package/dist/operations/modeling/model-requirement.js +176 -10
  63. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  64. package/dist/operations/modeling/predicate-applyplan.js +14 -2
  65. package/dist/operations/modeling/predicate-inference-1.js +1 -1
  66. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  67. package/dist/operations/modeling/predicate-loader.js +24 -0
  68. package/dist/operations/modeling/predicate-types.d.ts +4 -0
  69. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  70. package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
  71. package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
  72. package/dist/operations/modeling/predicate-vocabulary.js +169 -0
  73. package/dist/operations/modeling/requirement-types.d.ts +5 -0
  74. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  75. package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
  76. package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
  77. package/dist/operations/modeling/vocabulary-alignment.js +178 -0
  78. package/dist/operations/mutation/contradictions.d.ts +3 -0
  79. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  80. package/dist/operations/mutation/contradictions.js +29 -0
  81. package/dist/operations/mutation/delete.d.ts.map +1 -1
  82. package/dist/operations/mutation/delete.js +33 -1
  83. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
  84. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
  85. package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
  86. package/dist/operations/mutation/relationships.d.ts +1 -1
  87. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  88. package/dist/operations/mutation/relationships.js +1 -0
  89. package/dist/operations/mutation/saga.d.ts +5 -0
  90. package/dist/operations/mutation/saga.d.ts.map +1 -1
  91. package/dist/operations/mutation/saga.js +10 -0
  92. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  93. package/dist/operations/mutation/serialization.js +2 -0
  94. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  95. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  96. package/dist/operations/mutation/source-authoring.js +213 -52
  97. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  98. package/dist/operations/mutation/strict-fact.js +5 -0
  99. package/dist/operations/mutation/types.d.ts +17 -0
  100. package/dist/operations/mutation/types.d.ts.map +1 -1
  101. package/dist/operations/mutation/upsert.d.ts +6 -0
  102. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  103. package/dist/operations/mutation/upsert.js +77 -11
  104. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  105. package/dist/operations/mutation/validate-upsert.js +24 -1
  106. package/dist/operations/mutation/validation.d.ts.map +1 -1
  107. package/dist/operations/mutation/validation.js +16 -3
  108. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  109. package/dist/operations/planning/apply-plan.js +66 -26
  110. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  111. package/dist/operations/planning/compile-intent.js +3 -1
  112. package/dist/operations/proof/code-scope.d.ts +17 -0
  113. package/dist/operations/proof/code-scope.d.ts.map +1 -0
  114. package/dist/operations/proof/code-scope.js +60 -0
  115. package/dist/operations/proof/ingest-proof.d.ts +4 -2
  116. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  117. package/dist/operations/proof/ingest-proof.js +208 -74
  118. package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
  119. package/dist/operations/proof/migrate-legacy-receipts.js +7 -5
  120. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  121. package/dist/operations/proof/prune-receipts.js +7 -5
  122. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  123. package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
  124. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  125. package/dist/operations/semantic-advisor/analyze-prose.js +26 -4
  126. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  127. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  128. package/dist/operations/semantic-advisor/clauses.js +7 -1
  129. package/dist/performance-trace.d.ts +17 -0
  130. package/dist/performance-trace.d.ts.map +1 -0
  131. package/dist/performance-trace.js +134 -0
  132. package/dist/plugins/approved-source-analyzers.d.ts +13 -0
  133. package/dist/plugins/approved-source-analyzers.d.ts.map +1 -0
  134. package/dist/plugins/approved-source-analyzers.generated.d.ts +71 -0
  135. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -0
  136. package/dist/plugins/approved-source-analyzers.generated.js +77 -0
  137. package/dist/plugins/approved-source-analyzers.js +3 -0
  138. package/dist/plugins/compose-semantic-classifier.d.ts +6 -1
  139. package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -1
  140. package/dist/plugins/compose-semantic-classifier.js +8 -3
  141. package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
  142. package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
  143. package/dist/plugins/compose-vocabulary-alignment.js +141 -0
  144. package/dist/plugins/external-allowlist.d.ts +7 -0
  145. package/dist/plugins/external-allowlist.d.ts.map +1 -1
  146. package/dist/plugins/external-allowlist.js +13 -0
  147. package/dist/plugins/index.d.ts +2 -0
  148. package/dist/plugins/index.d.ts.map +1 -1
  149. package/dist/plugins/index.js +4 -0
  150. package/dist/plugins/maintenance-source-analysis.d.ts +14 -0
  151. package/dist/plugins/maintenance-source-analysis.d.ts.map +1 -0
  152. package/dist/plugins/maintenance-source-analysis.js +191 -0
  153. package/dist/plugins/registry.d.ts +3 -1
  154. package/dist/plugins/registry.d.ts.map +1 -1
  155. package/dist/plugins/registry.js +27 -1
  156. package/dist/plugins/source-analysis-service.d.ts +36 -1
  157. package/dist/plugins/source-analysis-service.d.ts.map +1 -1
  158. package/dist/plugins/source-analysis-service.js +184 -27
  159. package/dist/plugins/source-change-analysis.d.ts +15 -0
  160. package/dist/plugins/source-change-analysis.d.ts.map +1 -0
  161. package/dist/plugins/source-change-analysis.js +54 -0
  162. package/dist/plugins/source-classification.d.ts +41 -0
  163. package/dist/plugins/source-classification.d.ts.map +1 -0
  164. package/dist/plugins/source-classification.js +490 -0
  165. package/dist/prolog/codec.d.ts.map +1 -1
  166. package/dist/prolog/codec.js +2 -0
  167. package/dist/prolog/swipl-resolver.d.ts +88 -0
  168. package/dist/prolog/swipl-resolver.d.ts.map +1 -0
  169. package/dist/prolog/swipl-resolver.js +446 -0
  170. package/dist/prolog.d.ts +51 -1
  171. package/dist/prolog.d.ts.map +1 -1
  172. package/dist/prolog.js +145 -15
  173. package/dist/public/diagnostic-usage.d.ts.map +1 -1
  174. package/dist/public/diagnostic-usage.js +7 -25
  175. package/dist/public/impact/analyzer.d.ts.map +1 -1
  176. package/dist/public/impact/analyzer.js +56 -5
  177. package/dist/public/impact/diagnostics.d.ts.map +1 -1
  178. package/dist/public/impact/diagnostics.js +3 -1
  179. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  180. package/dist/public/impact/full-kb-quality.js +4 -12
  181. package/dist/public/impact/manifest.d.ts.map +1 -1
  182. package/dist/public/impact/manifest.js +15 -1
  183. package/dist/public/impact/source-changes.d.ts.map +1 -1
  184. package/dist/public/impact/source-changes.js +35 -27
  185. package/dist/public/impact/types.d.ts +2 -0
  186. package/dist/public/impact/types.d.ts.map +1 -1
  187. package/dist/public/operations/catalog.d.ts +80 -7
  188. package/dist/public/operations/catalog.d.ts.map +1 -1
  189. package/dist/public/operations/catalog.js +2 -0
  190. package/dist/public/operations/check-executor.d.ts.map +1 -1
  191. package/dist/public/operations/check-executor.js +10 -2
  192. package/dist/public/operations/check-helpers.d.ts +6 -0
  193. package/dist/public/operations/check-helpers.d.ts.map +1 -1
  194. package/dist/public/operations/check-helpers.js +21 -1
  195. package/dist/public/operations/contracts.d.ts.map +1 -1
  196. package/dist/public/operations/contracts.js +325 -8
  197. package/dist/public/operations/discovery-entities.d.ts +42 -2
  198. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  199. package/dist/public/operations/discovery-entities.js +195 -22
  200. package/dist/public/operations/discovery-executors.d.ts +1 -0
  201. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  202. package/dist/public/operations/discovery-executors.js +75 -46
  203. package/dist/public/operations/impact-review-preparation.d.ts +14 -0
  204. package/dist/public/operations/impact-review-preparation.d.ts.map +1 -0
  205. package/dist/public/operations/impact-review-preparation.js +379 -0
  206. package/dist/public/operations/index.d.ts +2 -0
  207. package/dist/public/operations/index.d.ts.map +1 -1
  208. package/dist/public/operations/index.js +2 -0
  209. package/dist/public/operations/migration-plan.d.ts +2 -0
  210. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  211. package/dist/public/operations/migration-plan.js +50 -0
  212. package/dist/public/operations/node-ports.d.ts.map +1 -1
  213. package/dist/public/operations/node-ports.js +1 -35
  214. package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
  215. package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
  216. package/dist/public/operations/predicate-schema-conformance.js +242 -0
  217. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  218. package/dist/public/operations/prolog-json.js +9 -3
  219. package/dist/public/operations/proof-receipt-projection.d.ts +5 -0
  220. package/dist/public/operations/proof-receipt-projection.d.ts.map +1 -0
  221. package/dist/public/operations/proof-receipt-projection.js +36 -0
  222. package/dist/public/operations/result-envelope.d.ts +34 -1
  223. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  224. package/dist/public/operations/result-envelope.js +78 -2
  225. package/dist/public/operations/runtime-types.d.ts +1 -1
  226. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  227. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  228. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  229. package/dist/public/operations/specs/check-rules.generated.js +8 -1
  230. package/dist/public/operations/specs/check.d.ts +1 -1
  231. package/dist/public/operations/specs/discovery.d.ts +7 -1
  232. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  233. package/dist/public/operations/specs/discovery.js +7 -1
  234. package/dist/public/operations/specs/impact-review-preparation.d.ts +47 -0
  235. package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -0
  236. package/dist/public/operations/specs/impact-review-preparation.js +43 -0
  237. package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
  238. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  239. package/dist/public/operations/specs/mutation-schemas.js +21 -3
  240. package/dist/public/operations/specs/reporting.d.ts +8 -0
  241. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  242. package/dist/public/operations/specs/reporting.js +46 -15
  243. package/dist/public/operations/specs/upsert.d.ts +28 -5
  244. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  245. package/dist/public/operations/specs/upsert.js +1 -1
  246. package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
  247. package/dist/public/operations/symbol-repair-plan.js +8 -3
  248. package/dist/public/operations/types.d.ts +1 -1
  249. package/dist/public/operations/types.d.ts.map +1 -1
  250. package/dist/public/schemas/entity.d.ts.map +1 -1
  251. package/dist/public/schemas/entity.js +22 -0
  252. package/dist/public/schemas/relationship.d.ts.map +1 -1
  253. package/dist/public/schemas/relationship.js +1 -0
  254. package/dist/public/skills/kibi-usage/SKILL.md +7 -3
  255. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  256. package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -0
  257. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  258. package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  259. package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
  260. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  261. package/dist/public/telemetry-acceptance.js +21 -5
  262. package/dist/relationships/shards.d.ts +6 -0
  263. package/dist/relationships/shards.d.ts.map +1 -1
  264. package/dist/relationships/shards.js +26 -19
  265. package/dist/schemas/entity.schema.json +32 -0
  266. package/dist/traceability/analysis-gate.d.ts +39 -0
  267. package/dist/traceability/analysis-gate.d.ts.map +1 -0
  268. package/dist/traceability/analysis-gate.js +51 -0
  269. package/dist/traceability/git-change-snapshot.d.ts +27 -0
  270. package/dist/traceability/git-change-snapshot.d.ts.map +1 -0
  271. package/dist/traceability/git-change-snapshot.js +411 -0
  272. package/dist/traceability/git-staged.d.ts +5 -1
  273. package/dist/traceability/git-staged.d.ts.map +1 -1
  274. package/dist/traceability/git-staged.js +16 -11
  275. package/dist/traceability/impact-evaluator.d.ts +54 -0
  276. package/dist/traceability/impact-evaluator.d.ts.map +1 -0
  277. package/dist/traceability/impact-evaluator.js +270 -0
  278. package/dist/traceability/impact-git-tree.d.ts +12 -0
  279. package/dist/traceability/impact-git-tree.d.ts.map +1 -0
  280. package/dist/traceability/impact-git-tree.js +46 -0
  281. package/dist/traceability/impact-knowledge.d.ts +16 -0
  282. package/dist/traceability/impact-knowledge.d.ts.map +1 -0
  283. package/dist/traceability/impact-knowledge.js +165 -0
  284. package/dist/traceability/impact-policy.d.ts +15 -0
  285. package/dist/traceability/impact-policy.d.ts.map +1 -0
  286. package/dist/traceability/impact-policy.js +48 -0
  287. package/dist/traceability/impact-policy.v1.schema.json +48 -0
  288. package/dist/traceability/impact-pr-diff.d.ts +5 -0
  289. package/dist/traceability/impact-pr-diff.d.ts.map +1 -0
  290. package/dist/traceability/impact-pr-diff.js +83 -0
  291. package/dist/traceability/impact-record-validation.d.ts +9 -0
  292. package/dist/traceability/impact-record-validation.d.ts.map +1 -0
  293. package/dist/traceability/impact-record-validation.js +113 -0
  294. package/dist/traceability/impact-review.d.ts +148 -0
  295. package/dist/traceability/impact-review.d.ts.map +1 -0
  296. package/dist/traceability/impact-review.js +494 -0
  297. package/dist/traceability/impact-review.schema.json +365 -0
  298. package/dist/traceability/impact-side-evidence.d.ts +13 -0
  299. package/dist/traceability/impact-side-evidence.d.ts.map +1 -0
  300. package/dist/traceability/impact-side-evidence.js +240 -0
  301. package/dist/traceability/reviewed-coordinate-refresh.d.ts +10 -0
  302. package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +1 -0
  303. package/dist/traceability/reviewed-coordinate-refresh.js +49 -0
  304. package/dist/traceability/snapshot-knowledge.d.ts +4 -0
  305. package/dist/traceability/snapshot-knowledge.d.ts.map +1 -0
  306. package/dist/traceability/snapshot-knowledge.js +98 -0
  307. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  308. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  309. package/dist/traceability/staged-entity-id-style.d.ts +12 -0
  310. package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
  311. package/dist/traceability/staged-entity-id-style.js +68 -0
  312. package/dist/traceability/staged-file-coverage.d.ts +23 -0
  313. package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
  314. package/dist/traceability/staged-impact-contract.d.ts.map +1 -1
  315. package/dist/traceability/staged-impact-contract.js +2 -16
  316. package/dist/traceability/staged-symbols-manifest.d.ts +4 -0
  317. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  318. package/dist/traceability/staged-symbols-manifest.js +17 -6
  319. package/dist/traceability/symbol-extract.d.ts +3 -5
  320. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  321. package/dist/traceability/symbol-extract.js +49 -34
  322. package/dist/traceability/temp-kb.d.ts +1 -1
  323. package/dist/traceability/temp-kb.d.ts.map +1 -1
  324. package/dist/traceability/temp-kb.js +57 -13
  325. package/dist/traceability/trusted-pr-event.d.ts +13 -0
  326. package/dist/traceability/trusted-pr-event.d.ts.map +1 -0
  327. package/dist/traceability/trusted-pr-event.js +105 -0
  328. package/dist/traceability/validate.js +1 -1
  329. package/dist/types/entities.d.ts +2 -0
  330. package/dist/types/entities.d.ts.map +1 -1
  331. package/dist/types/relationships.d.ts +1 -1
  332. package/dist/types/relationships.d.ts.map +1 -1
  333. package/dist/utils/canonical-path.d.ts +3 -0
  334. package/dist/utils/canonical-path.d.ts.map +1 -0
  335. package/dist/utils/canonical-path.js +33 -0
  336. package/dist/utils/entity-id-style.d.ts +27 -0
  337. package/dist/utils/entity-id-style.d.ts.map +1 -0
  338. package/dist/utils/entity-id-style.js +81 -0
  339. package/dist/utils/git-repository-context.d.ts +50 -0
  340. package/dist/utils/git-repository-context.d.ts.map +1 -0
  341. package/dist/utils/git-repository-context.js +259 -0
  342. package/dist/utils/rule-registry.d.ts +5 -0
  343. package/dist/utils/rule-registry.d.ts.map +1 -1
  344. package/dist/utils/rule-registry.generated.d.ts +37 -0
  345. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  346. package/dist/utils/rule-registry.generated.js +44 -0
  347. package/dist/utils/strict-modeling.d.ts +7 -0
  348. package/dist/utils/strict-modeling.d.ts.map +1 -1
  349. package/dist/utils/strict-modeling.js +11 -0
  350. package/package.json +14 -5
  351. package/schema/entities.pl +60 -1
  352. package/schema/relationships.pl +17 -4
  353. package/schema/validation.pl +118 -20
  354. package/src/public/diagnostic-usage.ts +16 -24
  355. package/src/public/impact/analyzer.ts +88 -5
  356. package/src/public/impact/diagnostics.ts +7 -5
  357. package/src/public/impact/full-kb-quality.ts +4 -16
  358. package/src/public/impact/manifest.ts +14 -1
  359. package/src/public/impact/source-changes.ts +39 -34
  360. package/src/public/impact/types.ts +5 -0
  361. package/src/public/operations/catalog.ts +2 -0
  362. package/src/public/operations/check-executor.ts +12 -1
  363. package/src/public/operations/check-helpers.ts +27 -1
  364. package/src/public/operations/contracts.ts +404 -9
  365. package/src/public/operations/discovery-entities.ts +292 -23
  366. package/src/public/operations/discovery-executors.ts +91 -55
  367. package/src/public/operations/impact-review-preparation.ts +548 -0
  368. package/src/public/operations/index.ts +2 -0
  369. package/src/public/operations/migration-plan.ts +57 -0
  370. package/src/public/operations/node-ports.ts +1 -39
  371. package/src/public/operations/predicate-schema-conformance.ts +362 -0
  372. package/src/public/operations/prolog-json.ts +9 -3
  373. package/src/public/operations/proof-receipt-projection.ts +39 -0
  374. package/src/public/operations/result-envelope.ts +114 -2
  375. package/src/public/operations/runtime-types.ts +1 -1
  376. package/src/public/operations/specs/check-rules.generated.ts +8 -1
  377. package/src/public/operations/specs/discovery.ts +8 -1
  378. package/src/public/operations/specs/impact-review-preparation.ts +46 -0
  379. package/src/public/operations/specs/mutation-schemas.ts +23 -3
  380. package/src/public/operations/specs/reporting.ts +69 -22
  381. package/src/public/operations/specs/upsert.ts +1 -1
  382. package/src/public/operations/symbol-repair-plan.ts +13 -3
  383. package/src/public/operations/types.ts +1 -0
  384. package/src/public/schemas/entity.ts +22 -0
  385. package/src/public/schemas/relationship.ts +1 -0
  386. package/src/public/skills/kibi-usage/SKILL.md +7 -3
  387. package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  388. package/src/public/skills/kibi-usage/resources/operation-access.md +1 -0
  389. package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  390. package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  391. package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
  392. package/src/public/telemetry-acceptance.ts +37 -6
  393. package/src/schemas/entity.schema.json +32 -0
  394. package/src/schemas/relationship.schema.json +1 -0
  395. package/src/traceability/impact-policy.v1.schema.json +48 -0
  396. package/src/traceability/impact-review.schema.json +365 -0
  397. package/templates/github/kibi-badge.yml +0 -4
  398. package/templates/github/kibi-report.yml +0 -4
@@ -42,8 +42,10 @@ validate_property_type(Type, Prop, Value) :-
42
42
  % check_kind(Kind, Value) succeeds if Value matches Kind
43
43
  check_kind(atom, V) :- atom(V).
44
44
  check_kind(string, V) :- string(V).
45
+ check_kind(atom_or_string, V) :- atom(V) ; string(V).
45
46
  check_kind(datetime, V) :- string(V). % accept ISO strings for now
46
47
  check_kind(list, V) :- is_list(V).
48
+ check_kind(list_or_json, V) :- is_list(V) ; string(V) ; atom(V).
47
49
  check_kind(uri, V) :- string(V).
48
50
  check_kind(integer, V) :- integer(V).
49
51
  check_kind(number, V) :- number(V).
@@ -59,11 +61,24 @@ validate_entity_shape(fact, Props) :-
59
61
  !,
60
62
  valid_optional_fact_enums(Props),
61
63
  valid_polarity_in_props(Props),
64
+ valid_claim_provenance(Props),
62
65
  ( memberchk(fact_kind=RawKind, Props) -> validate_fact_shape(RawKind, Props) ; true ).
66
+ validate_entity_shape(test, Props) :-
67
+ !,
68
+ valid_optional_test_enums(Props),
69
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)).
70
+ validate_entity_shape(req, Props) :-
71
+ !,
72
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
73
+ forall(member(Key=_, Props), \+ is_test_only_field(Key)).
63
74
  validate_entity_shape(Type, Props) :-
64
75
  Type \= fact,
65
- % Non-fact entities cannot have fact-only fields
66
- forall(member(Key=_Val, Props), \+ is_fact_only_field(Key)).
76
+ Type \= test,
77
+ Type \= req,
78
+ % Non-fact/non-test entities cannot have type-specific fields
79
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
80
+ forall(member(Key=_, Props), \+ is_test_only_field(Key)),
81
+ forall(member(Key=_, Props), Key \= logic_claims).
67
82
 
68
83
  % is_fact_only_field(+Key) - true if Key is a fact-specific field
69
84
  is_fact_only_field(fact_kind).
@@ -82,12 +97,39 @@ is_fact_only_field(closed_world).
82
97
  is_fact_only_field(valid_from).
83
98
  is_fact_only_field(valid_to).
84
99
  is_fact_only_field(canonical_key).
100
+ is_fact_only_field(claim_key).
101
+ is_fact_only_field(claim_text).
102
+ is_fact_only_field(predicate_name).
103
+ is_fact_only_field(predicate_namespace).
104
+ is_fact_only_field(predicate_arity).
105
+ is_fact_only_field(argument_names).
106
+ is_fact_only_field(argument_types).
107
+ is_fact_only_field(argument_descriptions).
108
+ is_fact_only_field(argument_constants).
109
+ is_fact_only_field(argument_aliases).
110
+ is_fact_only_field(aliases).
111
+ is_fact_only_field(examples).
112
+ is_fact_only_field(predicate_args).
113
+ is_fact_only_field(rule_ir).
114
+ is_fact_only_field(rule_hash).
115
+ is_fact_only_field(rule_schema_id).
116
+ is_fact_only_field(rule_name).
117
+ is_fact_only_field(semantic_key).
118
+ is_fact_only_field(claim_span_start).
119
+ is_fact_only_field(claim_span_end).
120
+
121
+ % is_test_only_field(+Key) - true if Key is a test-specific field
122
+ is_test_only_field(verification_scope).
123
+ is_test_only_field(verification_perspective).
124
+ is_test_only_field(proof_contract).
125
+ is_test_only_field(proof_bindings).
126
+ is_test_only_field(proof_receipts).
85
127
 
86
128
  % validate_fact_shape(+Kind, +Props)
87
129
  validate_fact_shape(subject, Props) :-
88
130
  memberchk(subject_key=_Val, Props),
89
131
  valid_optional_fact_enums(Props),
90
- valid_polarity_in_props(Props).
132
+ valid_strict_polarity_in_props(Props), !.
91
133
  validate_fact_shape(property_value, Props) :-
92
134
  memberchk(subject_key=_Subject, Props),
93
135
  memberchk(property_key=_Property, Props),
@@ -98,48 +140,104 @@ validate_fact_shape(property_value, Props) :-
98
140
  exactly_one_value_field(Props),
99
141
  value_type_matches_field(VT, Props),
100
142
  valid_optional_fact_enums(Props),
101
- valid_polarity_in_props(Props).
143
+ valid_strict_polarity_in_props(Props), !.
102
144
  validate_fact_shape(observation, Props) :-
103
- % Observation facts are allowed but don't require full strict property tuple yet
104
145
  valid_optional_fact_enums(Props),
105
- valid_polarity_in_props(Props).
146
+ valid_polarity_in_props(Props), !.
106
147
  validate_fact_shape(meta, Props) :-
107
148
  % Meta facts are allowed but don't require full strict property tuple yet
108
149
  valid_optional_fact_enums(Props),
109
- valid_polarity_in_props(Props).
150
+ valid_polarity_in_props(Props), !.
151
+ validate_fact_shape(predicate_schema, Props) :-
152
+ memberchk(predicate_name=_Name, Props),
153
+ memberchk(predicate_arity=Arity, Props),
154
+ Arity >= 1,
155
+ memberchk(argument_names=ArgumentNames, Props),
156
+ memberchk(argument_types=ArgumentTypes, Props),
157
+ same_length(ArgumentNames, ArgumentTypes),
158
+ length(ArgumentNames, Arity),
159
+ valid_optional_fact_enums(Props),
160
+ valid_polarity_in_props(Props), !.
161
+ validate_fact_shape(predicate, Props) :-
162
+ memberchk(predicate_name=_Name, Props),
163
+ memberchk(predicate_args=Args, Props),
164
+ Args \= [],
165
+ memberchk(canonical_key=_CanonicalKey, Props),
166
+ valid_optional_fact_enums(Props),
167
+ valid_predicate_polarity_in_props(Props), !.
168
+ validate_fact_shape(rule_schema, Props) :-
169
+ memberchk(rule_name=_Name, Props),
170
+ memberchk(argument_names=ArgumentNames, Props),
171
+ memberchk(argument_types=ArgumentTypes, Props),
172
+ same_length(ArgumentNames, ArgumentTypes),
173
+ valid_optional_fact_enums(Props),
174
+ valid_polarity_in_props(Props), !.
175
+ validate_fact_shape(rule, Props) :-
176
+ memberchk(rule_ir=RuleIr, Props),
177
+ nonempty_claim_value(RuleIr),
178
+ memberchk(rule_hash=_Hash, Props),
179
+ memberchk(rule_schema_id=_SchemaId, Props),
180
+ memberchk(semantic_key=_SemanticKey, Props),
181
+ valid_optional_fact_enums(Props),
182
+ valid_polarity_in_props(Props), !.
110
183
  validate_fact_shape(Kind, _Props) :-
111
184
  % Unknown fact_kind values fail validation
112
- \+ memberchk(Kind, [subject, property_value, observation, meta]),
185
+ \+ memberchk(Kind, [subject, property_value, observation, meta, predicate_schema, predicate, rule_schema, rule]),
113
186
  fail.
114
187
 
115
188
  % valid_operator(+Op)
116
- valid_operator(eq).
117
- valid_operator(neq).
118
- valid_operator(lt).
119
- valid_operator(lte).
120
- valid_operator(gt).
121
- valid_operator(gte).
189
+ valid_operator(Op) :- memberchk(Op, [eq, neq, lt, lte, gt, gte]), !.
122
190
 
123
191
  % valid_value_type(+VT)
124
- valid_value_type(string).
125
- valid_value_type(int).
126
- valid_value_type(number).
127
- valid_value_type(bool).
192
+ valid_value_type(ValueType) :- memberchk(ValueType, [string, int, number, bool]), !.
128
193
 
129
194
  % valid_polarity_in_props(+Props)
130
195
  % Validates polarity if present; succeeds if no polarity in props
131
196
  valid_polarity_in_props(Props) :-
132
197
  ( memberchk(polarity=P, Props) -> valid_polarity(P) ; true ).
133
198
 
199
+ valid_strict_polarity_in_props(Props) :-
200
+ ( memberchk(polarity=P, Props) -> valid_strict_polarity(P) ; true ).
201
+
202
+ valid_predicate_polarity_in_props(Props) :-
203
+ ( memberchk(polarity=P, Props) -> valid_predicate_polarity(P) ; true ).
204
+
205
+ % claim_key and claim_text form one auditable provenance pair.
206
+ valid_claim_provenance(Props) :-
207
+ ( memberchk(claim_key=Key, Props)
208
+ -> memberchk(claim_text=Text, Props),
209
+ nonempty_claim_value(Key),
210
+ nonempty_claim_value(Text)
211
+ ; \+ memberchk(claim_text=_, Props)
212
+ ).
213
+
214
+ nonempty_claim_value(Value) :- string(Value), Value \= "", !.
215
+ nonempty_claim_value(Value) :- atom(Value), Value \= '', !.
216
+
134
217
  % valid_optional_fact_enums(+Props)
135
218
  % Validates enum-typed fact fields whenever they are present
136
219
  valid_optional_fact_enums(Props) :-
137
220
  ( memberchk(operator=Op, Props) -> valid_operator(Op) ; true ),
138
221
  ( memberchk(value_type=VT, Props) -> valid_value_type(VT) ; true ).
139
222
 
223
+ % valid_optional_test_enums(+Props)
224
+ % Validates enum-typed test fields whenever they are present
225
+ valid_optional_test_enums(Props) :-
226
+ ( memberchk(verification_scope=Scope, Props) -> valid_verification_scope(Scope) ; true ),
227
+ ( memberchk(verification_perspective=Perspective, Props) -> valid_verification_perspective(Perspective) ; true ).
228
+
140
229
  % valid_polarity(+P)
141
- valid_polarity(require).
142
- valid_polarity(forbid).
230
+ valid_polarity(Polarity) :- memberchk(Polarity, [require, forbid, assert, deny]), !.
231
+
232
+ valid_strict_polarity(Polarity) :- memberchk(Polarity, [require, forbid]), !.
233
+
234
+ valid_predicate_polarity(Polarity) :- memberchk(Polarity, [assert, deny]), !.
235
+
236
+ % valid_verification_scope(+Scope)
237
+ valid_verification_scope(Scope) :- memberchk(Scope, [unit, integration, end_to_end]), !.
238
+
239
+ % valid_verification_perspective(+Perspective)
240
+ valid_verification_perspective(Perspective) :- memberchk(Perspective, [internal, consumer]), !.
143
241
 
144
242
  % exactly_one_value_field(+Props)
145
243
  exactly_one_value_field(Props) :-
@@ -2,6 +2,11 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { appendFileSync, mkdirSync } from "node:fs";
3
3
  import path from "node:path";
4
4
 
5
+ import {
6
+ appendPayloadCountField,
7
+ normalizeResultPayload,
8
+ } from "./operations/result-envelope.js";
9
+
5
10
  export interface DiagnosticUsageInput {
6
11
  readonly workspaceRoot: string;
7
12
  readonly tool: string;
@@ -20,16 +25,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
20
25
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
21
26
  }
22
27
 
23
- function resultRecord(result: unknown): Record<string, unknown> | undefined {
24
- if (!isRecord(result)) return undefined;
25
- if (isRecord(result.structuredContent)) return result.structuredContent;
26
- // CLI JSON operations return the same versioned KibiResult envelope as MCP
27
- // structuredContent. Unwrap its data before deriving operation-specific
28
- // telemetry fields (coverage/proof fields in particular).
29
- if (result.kibiProtocol === 1 && isRecord(result.data)) return result.data;
30
- return result;
31
- }
32
-
33
28
  function stringArray(value: unknown): string[] {
34
29
  return Array.isArray(value)
35
30
  ? value.filter((item): item is string => typeof item === "string")
@@ -188,11 +183,7 @@ export function deriveDiagnosticUsageFields(
188
183
  }
189
184
  }
190
185
 
191
- const structured = resultRecord(result);
192
- const envelope =
193
- isRecord(structured) && structured.kibiProtocol === 1
194
- ? structured
195
- : undefined;
186
+ const { envelope, data: structured } = normalizeResultPayload(result);
196
187
  if (envelope) {
197
188
  fields.protocol_version = envelope.kibiProtocol;
198
189
  fields.result_version =
@@ -214,18 +205,19 @@ export function deriveDiagnosticUsageFields(
214
205
  fields.unsafe_original_retry = telemetry?.unsafe_original_retry === true;
215
206
  }
216
207
  if (tool === "kb_query" || tool === "kb_search") {
217
- const resultCount = Number(structured?.count ?? 0);
218
- fields.result_count = resultCount;
219
- fields.zero_results = resultCount === 0;
220
- fields.result_summary =
221
- resultCount === 0 ? "0 results" : `${resultCount} results`;
208
+ appendPayloadCountField(fields, "result_count", "results", structured);
209
+ if (typeof fields.result_count === "number") {
210
+ fields.zero_results = fields.result_count === 0;
211
+ }
222
212
  }
223
213
  if (tool === "kb_check") {
224
- const count = Number(structured?.count ?? 0);
225
- fields.violation_count = count;
214
+ appendPayloadCountField(
215
+ fields,
216
+ "violation_count",
217
+ "violations",
218
+ structured,
219
+ );
226
220
  fields.requested_rules = Array.isArray(args.rules) ? args.rules : [];
227
- fields.result_summary =
228
- count === 0 ? "0 violations" : `${count} violations`;
229
221
  }
230
222
  if (tool === "kb_coverage" && structured) {
231
223
  appendCoverageFields(fields, args, structured);
@@ -1,4 +1,14 @@
1
1
  import * as path from "node:path";
2
+ import {
3
+ createMaintenanceSourceAnalysisService,
4
+ readSnapshotSourceConfig,
5
+ } from "../../plugins/maintenance-source-analysis.js";
6
+ import {
7
+ analyzeSourceChanges,
8
+ assertSourceAnalysisGate,
9
+ } from "../../plugins/source-change-analysis.js";
10
+ import { captureStagedSnapshot } from "../../traceability/git-change-snapshot.js";
11
+ import { readSnapshotKnowledge } from "../../traceability/snapshot-knowledge.js";
2
12
  import type { ExtractedSymbol } from "../../traceability/symbol-extract.js";
3
13
  import { extractSymbolsFromStagedFileAsync } from "../../traceability/symbol-extract.js";
4
14
  import {
@@ -9,6 +19,7 @@ import {
9
19
  createImpactManifestLookup,
10
20
  readImpactManifestResults,
11
21
  } from "./manifest.js";
22
+ import { normalizeSourceFile } from "./source-changes.js";
12
23
  import { collectSourceChanges, uniqueSorted } from "./source-changes.js";
13
24
  import {
14
25
  buildNextActions,
@@ -25,16 +36,73 @@ export async function analyzeChangedFileImpact(
25
36
  options: ChangedFileImpactOptions,
26
37
  ): Promise<ChangedFileImpactResult> {
27
38
  const workspaceRoot = path.resolve(options.workspaceRoot);
28
- const sourceChanges = collectSourceChanges({ ...options, workspaceRoot });
29
- const sourceFiles = uniqueSorted(sourceChanges.map((change) => change.file));
30
- const manifestResults = readImpactManifestResults(workspaceRoot);
39
+ const snapshot = options.staged
40
+ ? captureStagedSnapshot(workspaceRoot)
41
+ : undefined;
42
+ const filter = new Set(
43
+ (options.sourceFiles ?? []).map((file) =>
44
+ normalizeSourceFile(workspaceRoot, file),
45
+ ),
46
+ );
47
+ const snapshotAnalysisInventory = snapshot
48
+ ? snapshot.inventory.filter(
49
+ (file) => filter.size === 0 || filter.has(file.path),
50
+ )
51
+ : undefined;
52
+ const snapshotSourceInventory = snapshot
53
+ ? snapshot.inventory.filter(
54
+ (file) =>
55
+ file.analysisDepth !== "metadata" &&
56
+ !file.skipReason &&
57
+ file.content !== undefined &&
58
+ (filter.size === 0 || filter.has(file.path)),
59
+ )
60
+ : undefined;
61
+ const sourceChanges = snapshot
62
+ ? (snapshotSourceInventory ?? []).map((file) => ({
63
+ file: file.path,
64
+ status: file.status,
65
+ hunkRanges: file.hunkRanges,
66
+ content: file.content ?? "",
67
+ }))
68
+ : collectSourceChanges({ ...options, workspaceRoot });
69
+ const service = createMaintenanceSourceAnalysisService(
70
+ workspaceRoot,
71
+ snapshot ? readSnapshotSourceConfig(snapshot) : undefined,
72
+ );
73
+ const analyses = snapshot
74
+ ? await analyzeSourceChanges(snapshotAnalysisInventory ?? [], service)
75
+ : undefined;
76
+ if (analyses)
77
+ assertSourceAnalysisGate(snapshotAnalysisInventory ?? [], analyses);
78
+ const sourceFiles = uniqueSorted(
79
+ snapshot
80
+ ? snapshot.inventory
81
+ .filter(
82
+ (file) =>
83
+ file.analysisDepth !== "metadata" &&
84
+ (filter.size === 0 || filter.has(file.path)),
85
+ )
86
+ .map((file) => file.path)
87
+ : sourceChanges.map((change) => change.file),
88
+ );
89
+ const manifestResults = snapshot
90
+ ? readSnapshotKnowledge(
91
+ snapshot.readGit,
92
+ snapshot.headTree,
93
+ snapshot.readBlobs,
94
+ ).filter((result) => result.entity.type === "symbol")
95
+ : readImpactManifestResults(workspaceRoot);
31
96
  const manifestLookup = createImpactManifestLookup(manifestResults);
32
97
  const symbolsByFile = new Map<string, ExtractedSymbol[]>();
33
98
  const sourceContentByFile = new Map<string, string>();
99
+ const sourceSymbolsByFile = new Map<string, ExtractedSymbol[]>();
34
100
 
35
101
  for (const change of sourceChanges) {
36
102
  sourceContentByFile.set(change.file, change.content);
37
- // Maintenance path: builtin-only (do not pass registry / workspaceRoot).
103
+ const analysis =
104
+ analyses?.get(change.file)?.after ??
105
+ (await service.analyzeTextV2(change.file, change.content));
38
106
  const extracted = await extractSymbolsFromStagedFileAsync(
39
107
  {
40
108
  path: change.file,
@@ -43,8 +111,21 @@ export async function analyzeChangedFileImpact(
43
111
  content: change.content,
44
112
  },
45
113
  manifestLookup,
46
- {},
114
+ { analyzeText: async () => analysis },
115
+ );
116
+ const allSymbols = await extractSymbolsFromStagedFileAsync(
117
+ {
118
+ path: change.file,
119
+ status: change.status,
120
+ content: change.content,
121
+ hunkRanges: [
122
+ { start: 1, end: Math.max(1, change.content.split("\n").length) },
123
+ ],
124
+ },
125
+ manifestLookup,
126
+ { analyzeText: async () => analysis },
47
127
  );
128
+ sourceSymbolsByFile.set(change.file, allSymbols);
48
129
  symbolsByFile.set(
49
130
  change.file,
50
131
  extracted.filter((symbol) => symbol.hunkRanges.length > 0),
@@ -65,6 +146,7 @@ export async function analyzeChangedFileImpact(
65
146
  manifestResults: activeManifestResults,
66
147
  symbolsByFile,
67
148
  sourceContentByFile,
149
+ sourceSymbolsByFile,
68
150
  workspaceRoot,
69
151
  }),
70
152
  ...createSymbolQualityDiagnostics({
@@ -79,6 +161,7 @@ export async function analyzeChangedFileImpact(
79
161
  ? impactDiagnostics.slice(0, maxDiagnostics)
80
162
  : impactDiagnostics;
81
163
 
164
+ snapshot?.assertUnchanged();
82
165
  return {
83
166
  impactDiagnostics: cappedDiagnostics,
84
167
  sourceFiles,
@@ -74,11 +74,13 @@ function getGranularSymbolsForSourceFile(
74
74
  readonly candidateSymbols: readonly ExtractedSymbol[];
75
75
  readonly sourceSymbols: readonly ExtractedSymbol[];
76
76
  } {
77
- const sourceSymbols = readSourceSymbols(
78
- sourceFile,
79
- options.sourceContentByFile,
80
- options.workspaceRoot ?? process.cwd(),
81
- );
77
+ const sourceSymbols = options.sourceSymbolsByFile
78
+ ? (options.sourceSymbolsByFile.get(sourceFile) ?? [])
79
+ : readSourceSymbols(
80
+ sourceFile,
81
+ options.sourceContentByFile,
82
+ options.workspaceRoot ?? process.cwd(),
83
+ );
82
84
  const changedSymbols = options.symbolsByFile.get(sourceFile);
83
85
 
84
86
  return {
@@ -568,22 +568,10 @@ export async function loadKbExtractionResults(
568
568
  prolog.queryEntities.bind(prolog),
569
569
  );
570
570
  } else {
571
- const entityResult = await prolog.query(
572
- "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)",
573
- );
574
- if (entityResult.success) {
575
- entities = entityResult.bindings.Results
576
- ? parseListOfLists(entityResult.bindings.Results).map(
577
- parseEntityFromList,
578
- )
579
- : [];
580
- } else if (isOutputCapacityError(entityResult.error)) {
581
- entities = await loadBoundedEntityProjection(prolog);
582
- } else {
583
- throw new Error(
584
- `Full KB entity projection query failed: ${entityResult.error ?? "Unknown error"}`,
585
- );
586
- }
571
+ // Never probe with an unbounded all-entities findall: receipt histories
572
+ // make that answer grow without limit, and an overflow terminates the
573
+ // interactive Prolog process that serves every later query.
574
+ entities = await loadBoundedEntityProjection(prolog);
587
575
  }
588
576
  const relationships = new Map<string, ExtractionResult["relationships"]>();
589
577
 
@@ -2,6 +2,7 @@ import { existsSync } from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { extractFromManifest } from "../../extractors/manifest.js";
4
4
  import type { ExtractionResult } from "../../extractors/markdown.js";
5
+ import { createManifestLookupSentinelKey } from "../../traceability/symbol-extract.js";
5
6
  import type { ManifestLookup } from "../../traceability/symbol-extract.js";
6
7
  import { CANONICAL_ENTITY_PATHS } from "../../utils/kb-paths.js";
7
8
  import { isTraceabilityRelationshipType } from "../symbol-granularity.js";
@@ -42,10 +43,22 @@ export function createImpactManifestLookup(
42
43
  manifestResults: readonly ExtractionResult[],
43
44
  ): ManifestLookup {
44
45
  const manifestLookup: ManifestLookup = new Map();
46
+ manifestLookup.set(createManifestLookupSentinelKey(".kb/symbols.yaml"), {
47
+ id: "__captured_manifest__",
48
+ relationships: [],
49
+ });
50
+ const ambiguous = new Set<string>();
45
51
 
46
52
  for (const result of manifestResults) {
47
53
  const sourceFile = result.sourceFile ?? result.entity.source;
48
- manifestLookup.set(`${sourceFile}:${result.entity.title}`, {
54
+ const key = `${sourceFile}:${result.entity.title}`;
55
+ if (ambiguous.has(key)) continue;
56
+ if (manifestLookup.has(key)) {
57
+ manifestLookup.delete(key);
58
+ ambiguous.add(key);
59
+ continue;
60
+ }
61
+ manifestLookup.set(key, {
49
62
  id: result.entity.id,
50
63
  relationships: toTraceabilityRelationships(result.relationships),
51
64
  });
@@ -1,6 +1,7 @@
1
- import { execSync } from "node:child_process";
2
- import { existsSync, readFileSync } from "node:fs";
1
+ import { execFileSync, execSync } from "node:child_process";
2
+ import { existsSync, lstatSync, readFileSync, realpathSync } from "node:fs";
3
3
  import * as path from "node:path";
4
+ import { isQualifiedSourcePath } from "../../plugins/source-classification.js";
4
5
  import type { HunkRange } from "../../traceability/git-staged.js";
5
6
  import {
6
7
  getStagedFiles,
@@ -9,19 +10,8 @@ import {
9
10
  import { hasMeaningfulSourceDiff } from "./diff-meaning.js";
10
11
  import type { ChangedFileImpactOptions, SourceChange } from "./types.js";
11
12
 
12
- const SOURCE_EXTENSIONS = new Set([
13
- ".ts",
14
- ".tsx",
15
- ".js",
16
- ".jsx",
17
- ".mts",
18
- ".cts",
19
- ".mjs",
20
- ".cjs",
21
- ]);
22
-
23
13
  function isSupportedSourcePath(filePath: string): boolean {
24
- return SOURCE_EXTENSIONS.has(path.extname(filePath));
14
+ return isQualifiedSourcePath(filePath);
25
15
  }
26
16
 
27
17
  export function normalizeSourceFile(
@@ -38,12 +28,12 @@ export function uniqueSorted(values: Iterable<string>): string[] {
38
28
  return [...new Set(values)].sort();
39
29
  }
40
30
 
41
- function escapeGitPath(filePath: string): string {
42
- return filePath.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
43
- }
44
-
45
- function runGit(workspaceRoot: string, command: string): string {
46
- return execSync(command, { cwd: workspaceRoot, encoding: "utf8" });
31
+ function runGit(workspaceRoot: string, args: readonly string[]): string {
32
+ return execFileSync("git", [...args], {
33
+ cwd: workspaceRoot,
34
+ encoding: "utf8",
35
+ env: { ...process.env, GIT_LITERAL_PATHSPECS: "1" },
36
+ });
47
37
  }
48
38
 
49
39
  function readWorkingTreeSource(
@@ -51,8 +41,24 @@ function readWorkingTreeSource(
51
41
  sourceFile: string,
52
42
  ): string | null {
53
43
  const absolutePath = path.resolve(workspaceRoot, sourceFile);
54
- if (!existsSync(absolutePath)) return null;
55
- return readFileSync(absolutePath, "utf8");
44
+ const relative = path.relative(workspaceRoot, absolutePath);
45
+ if (!relative || relative.startsWith("..") || path.isAbsolute(relative))
46
+ throw new Error("Source path must remain inside the workspace");
47
+ if (!existsSync(absolutePath) || !lstatSync(absolutePath).isFile())
48
+ return null;
49
+ const actualRelative = path.relative(
50
+ realpathSync(workspaceRoot),
51
+ realpathSync(absolutePath),
52
+ );
53
+ if (actualRelative.startsWith("..") || path.isAbsolute(actualRelative))
54
+ throw new Error("Source path escapes the workspace");
55
+ const bytes = readFileSync(absolutePath);
56
+ if (bytes.includes(0)) return null;
57
+ try {
58
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
59
+ } catch {
60
+ return null;
61
+ }
56
62
  }
57
63
 
58
64
  function fullFileHunk(content: string): HunkRange[] {
@@ -62,9 +68,9 @@ function fullFileHunk(content: string): HunkRange[] {
62
68
  function getWorkingTreeDiffSourceFiles(workspaceRoot: string): string[] {
63
69
  try {
64
70
  return uniqueSorted(
65
- runGit(workspaceRoot, "git diff --name-only --diff-filter=ACMR")
66
- .split(/\r?\n/)
67
- .map((filePath) => normalizeSourceFile(workspaceRoot, filePath.trim()))
71
+ runGit(workspaceRoot, ["diff", "--name-only", "-z", "--diff-filter=ACMR"])
72
+ .split("\0")
73
+ .map((filePath) => normalizeSourceFile(workspaceRoot, filePath))
68
74
  .filter((filePath) => filePath.length > 0)
69
75
  .filter(isSupportedSourcePath),
70
76
  );
@@ -78,10 +84,7 @@ function getWorkingTreeHunks(
78
84
  sourceFile: string,
79
85
  ): HunkRange[] {
80
86
  try {
81
- const diffText = runGit(
82
- workspaceRoot,
83
- `git diff -U0 -- "${escapeGitPath(sourceFile)}"`,
84
- );
87
+ const diffText = runGit(workspaceRoot, ["diff", "-U0", "--", sourceFile]);
85
88
  return parseHunksFromDiff(diffText);
86
89
  } catch {
87
90
  return [];
@@ -104,6 +107,7 @@ function getStagedSourceChanges(
104
107
  .flatMap((file): SourceChange[] => {
105
108
  if (file.content === undefined || file.hunkRanges.length === 0) return [];
106
109
  if (
110
+ !/\.(pyi?|go|rs)$/.test(file.path) &&
107
111
  file.diffText !== undefined &&
108
112
  !hasMeaningfulSourceDiff(file.diffText)
109
113
  ) {
@@ -132,11 +136,12 @@ function getWorkingTreeSourceChanges(
132
136
  return sourceFiles.flatMap((sourceFile): SourceChange[] => {
133
137
  const content = readWorkingTreeSource(workspaceRoot, sourceFile);
134
138
  if (content === null) return [];
135
- const diffText = runGit(
136
- workspaceRoot,
137
- `git diff -U0 -- "${escapeGitPath(sourceFile)}"`,
138
- );
139
- if (!hasMeaningfulSourceDiff(diffText)) return [];
139
+ const diffText = runGit(workspaceRoot, ["diff", "-U0", "--", sourceFile]);
140
+ if (
141
+ !/\.(pyi?|go|rs)$/.test(sourceFile) &&
142
+ !hasMeaningfulSourceDiff(diffText)
143
+ )
144
+ return [];
140
145
  const hunkRanges = getWorkingTreeHunks(workspaceRoot, sourceFile);
141
146
  if (hunkRanges.length === 0) return [];
142
147
  return [{ file: sourceFile, status: "M", hunkRanges, content }];
@@ -39,6 +39,11 @@ export type SymbolGranularityDiagnosticsOptions = {
39
39
  readonly activeEntityIds?: ReadonlySet<string>;
40
40
  readonly symbolsByFile: SymbolsByFile;
41
41
  readonly sourceContentByFile?: ReadonlyMap<string, string>;
42
+ /** Complete snapshot analysis; when supplied, filesystem fallback is forbidden. */
43
+ readonly sourceSymbolsByFile?: ReadonlyMap<
44
+ string,
45
+ readonly ExtractedSymbol[]
46
+ >;
42
47
  readonly workspaceRoot?: string;
43
48
  };
44
49
 
@@ -6,6 +6,7 @@ import {
6
6
  import { planBootstrapSpec } from "./specs/bootstrap.js";
7
7
  import { checkSpec } from "./specs/check.js";
8
8
  import { querySpec, searchSpec, statusSpec } from "./specs/discovery.js";
9
+ import { prepareImpactReviewSpec } from "./specs/impact-review-preparation.js";
9
10
  import {
10
11
  modelRequirementSpec,
11
12
  suggestPredicatesSpec,
@@ -49,6 +50,7 @@ export const OPERATION_CATALOG = [
49
50
  upsertSpec,
50
51
  deleteSpec,
51
52
  checkSpec,
53
+ prepareImpactReviewSpec,
52
54
  sparqlRemoteSpec,
53
55
  compileIntentSpec,
54
56
  applyPlanSpec,