kibi-cli 2.0.0 → 2.2.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 (377) hide show
  1. package/dist/cli-protocol.d.ts.map +1 -1
  2. package/dist/cli-protocol.js +3 -2
  3. package/dist/cli-register-proof.d.ts.map +1 -1
  4. package/dist/cli-register-proof.js +25 -1
  5. package/dist/cli-register-reporting.d.ts.map +1 -1
  6. package/dist/cli-register-reporting.js +6 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +2 -0
  9. package/dist/commands/aggregated-checks.d.ts +7 -0
  10. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  11. package/dist/commands/aggregated-checks.js +25 -1
  12. package/dist/commands/check-generated.d.ts +7 -0
  13. package/dist/commands/check-generated.d.ts.map +1 -0
  14. package/dist/commands/check-generated.js +192 -0
  15. package/dist/commands/check.d.ts.map +1 -1
  16. package/dist/commands/check.js +24 -15
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +227 -25
  19. package/dist/commands/engine.d.ts.map +1 -1
  20. package/dist/commands/engine.js +3 -1
  21. package/dist/commands/github-init.d.ts +1 -1
  22. package/dist/commands/github-init.d.ts.map +1 -1
  23. package/dist/commands/github-init.js +1 -1
  24. package/dist/commands/init-helpers.d.ts +17 -2
  25. package/dist/commands/init-helpers.d.ts.map +1 -1
  26. package/dist/commands/init-helpers.js +136 -30
  27. package/dist/commands/init.d.ts.map +1 -1
  28. package/dist/commands/init.js +110 -15
  29. package/dist/commands/proof-explain.d.ts +10 -0
  30. package/dist/commands/proof-explain.d.ts.map +1 -0
  31. package/dist/commands/proof-explain.js +45 -0
  32. package/dist/commands/proof-impact.d.ts +7 -0
  33. package/dist/commands/proof-impact.d.ts.map +1 -0
  34. package/dist/commands/proof-impact.js +39 -0
  35. package/dist/commands/proof-migrate-legacy.js +1 -1
  36. package/dist/commands/proof-prune.js +1 -1
  37. package/dist/commands/prove.d.ts.map +1 -1
  38. package/dist/commands/prove.js +14 -22
  39. package/dist/commands/report.d.ts.map +1 -1
  40. package/dist/commands/report.js +17 -2
  41. package/dist/commands/sync/cache.d.ts +20 -1
  42. package/dist/commands/sync/cache.d.ts.map +1 -1
  43. package/dist/commands/sync/cache.js +51 -2
  44. package/dist/commands/sync/discovery.d.ts.map +1 -1
  45. package/dist/commands/sync/discovery.js +1 -1
  46. package/dist/commands/sync/manifest.d.ts +1 -0
  47. package/dist/commands/sync/manifest.d.ts.map +1 -1
  48. package/dist/commands/sync/manifest.js +18 -16
  49. package/dist/commands/sync/persistence.d.ts.map +1 -1
  50. package/dist/commands/sync/persistence.js +14 -0
  51. package/dist/commands/sync.d.ts.map +1 -1
  52. package/dist/commands/sync.js +11 -3
  53. package/dist/engine.d.ts +29 -1
  54. package/dist/engine.d.ts.map +1 -1
  55. package/dist/engine.js +259 -89
  56. package/dist/env/bootstrap.d.ts +84 -0
  57. package/dist/env/bootstrap.d.ts.map +1 -0
  58. package/dist/env/bootstrap.js +310 -0
  59. package/dist/extractors/manifest.d.ts.map +1 -1
  60. package/dist/extractors/manifest.js +67 -29
  61. package/dist/extractors/markdown.d.ts +4 -0
  62. package/dist/extractors/markdown.d.ts.map +1 -1
  63. package/dist/extractors/markdown.js +33 -3
  64. package/dist/extractors/relationships.d.ts.map +1 -1
  65. package/dist/extractors/relationships.js +1 -0
  66. package/dist/extractors/symbols-coordinator.d.ts +8 -0
  67. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  68. package/dist/extractors/symbols-coordinator.js +40 -0
  69. package/dist/extractors/symbols-ts.d.ts +8 -19
  70. package/dist/extractors/symbols-ts.d.ts.map +1 -1
  71. package/dist/extractors/symbols-ts.js +33 -503
  72. package/dist/intent-search.d.ts.map +1 -1
  73. package/dist/intent-search.js +68 -30
  74. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  75. package/dist/operations/bootstrap/generate.js +4 -3
  76. package/dist/operations/modeling/model-requirement.d.ts +1 -1
  77. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  78. package/dist/operations/modeling/model-requirement.js +179 -9
  79. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  80. package/dist/operations/modeling/predicate-applyplan.js +14 -2
  81. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  82. package/dist/operations/modeling/predicate-loader.js +24 -0
  83. package/dist/operations/modeling/predicate-types.d.ts +4 -0
  84. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  85. package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
  86. package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
  87. package/dist/operations/modeling/predicate-vocabulary.js +169 -0
  88. package/dist/operations/modeling/requirement-types.d.ts +5 -0
  89. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  90. package/dist/operations/modeling/suggest-predicates.d.ts +1 -1
  91. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  92. package/dist/operations/modeling/suggest-predicates.js +30 -3
  93. package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
  94. package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
  95. package/dist/operations/modeling/vocabulary-alignment.js +178 -0
  96. package/dist/operations/mutation/contradictions.d.ts +3 -0
  97. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  98. package/dist/operations/mutation/contradictions.js +29 -0
  99. package/dist/operations/mutation/delete.d.ts.map +1 -1
  100. package/dist/operations/mutation/delete.js +33 -1
  101. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
  102. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
  103. package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
  104. package/dist/operations/mutation/relationships.d.ts +1 -1
  105. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  106. package/dist/operations/mutation/relationships.js +1 -0
  107. package/dist/operations/mutation/saga.d.ts +5 -0
  108. package/dist/operations/mutation/saga.d.ts.map +1 -1
  109. package/dist/operations/mutation/saga.js +10 -0
  110. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  111. package/dist/operations/mutation/serialization.js +2 -0
  112. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  113. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  114. package/dist/operations/mutation/source-authoring.js +65 -26
  115. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  116. package/dist/operations/mutation/strict-fact.js +5 -0
  117. package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
  118. package/dist/operations/mutation/symbol-granularity.js +9 -87
  119. package/dist/operations/mutation/types.d.ts +17 -0
  120. package/dist/operations/mutation/types.d.ts.map +1 -1
  121. package/dist/operations/mutation/upsert.d.ts +6 -0
  122. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  123. package/dist/operations/mutation/upsert.js +72 -4
  124. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  125. package/dist/operations/mutation/validate-upsert.js +24 -1
  126. package/dist/operations/mutation/validation.d.ts.map +1 -1
  127. package/dist/operations/mutation/validation.js +16 -3
  128. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  129. package/dist/operations/planning/apply-plan.js +61 -17
  130. package/dist/operations/planning/compile-intent.d.ts +49 -0
  131. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  132. package/dist/operations/planning/compile-intent.js +66 -4
  133. package/dist/operations/proof/baseline-diff.d.ts +41 -0
  134. package/dist/operations/proof/baseline-diff.d.ts.map +1 -0
  135. package/dist/operations/proof/baseline-diff.js +153 -0
  136. package/dist/operations/proof/code-scope.d.ts +17 -0
  137. package/dist/operations/proof/code-scope.d.ts.map +1 -0
  138. package/dist/operations/proof/code-scope.js +60 -0
  139. package/dist/operations/proof/explain.d.ts +75 -0
  140. package/dist/operations/proof/explain.d.ts.map +1 -0
  141. package/dist/operations/proof/explain.js +294 -0
  142. package/dist/operations/proof/impact.d.ts +45 -0
  143. package/dist/operations/proof/impact.d.ts.map +1 -0
  144. package/dist/operations/proof/impact.js +118 -0
  145. package/dist/operations/proof/ingest-proof.d.ts +4 -2
  146. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  147. package/dist/operations/proof/ingest-proof.js +251 -77
  148. package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
  149. package/dist/operations/proof/migrate-legacy-receipts.js +28 -22
  150. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  151. package/dist/operations/proof/prune-receipts.js +8 -6
  152. package/dist/operations/proof/receipt-document.js +2 -2
  153. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  154. package/dist/operations/semantic-advisor/analysis-receipt.js +3 -9
  155. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  156. package/dist/operations/semantic-advisor/analyze-prose.js +18 -67
  157. package/dist/operations/semantic-advisor/plugin-orchestration.d.ts +63 -0
  158. package/dist/operations/semantic-advisor/plugin-orchestration.d.ts.map +1 -0
  159. package/dist/operations/semantic-advisor/plugin-orchestration.js +489 -0
  160. package/dist/operations/semantic-advisor/predicate-rules-core.d.ts +15 -2
  161. package/dist/operations/semantic-advisor/predicate-rules-core.d.ts.map +1 -1
  162. package/dist/operations/semantic-advisor/predicate-rules-core.js +7 -140
  163. package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts +11 -12
  164. package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts.map +1 -1
  165. package/dist/operations/semantic-advisor/predicate-rules-launcher.js +6 -94
  166. package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts +16 -0
  167. package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts.map +1 -1
  168. package/dist/operations/semantic-advisor/predicate-rules-policy.js +7 -150
  169. package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts +9 -0
  170. package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts.map +1 -1
  171. package/dist/operations/semantic-advisor/predicate-rules-product-tail.js +7 -102
  172. package/dist/operations/semantic-advisor/predicate-rules-product.d.ts +13 -0
  173. package/dist/operations/semantic-advisor/predicate-rules-product.d.ts.map +1 -1
  174. package/dist/operations/semantic-advisor/predicate-rules-product.js +7 -133
  175. package/dist/operations/semantic-advisor/types.d.ts +1 -0
  176. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  177. package/dist/plugins/compose-ontology-packs.d.ts +51 -0
  178. package/dist/plugins/compose-ontology-packs.d.ts.map +1 -0
  179. package/dist/plugins/compose-ontology-packs.js +257 -0
  180. package/dist/plugins/compose-semantic-classifier.d.ts +47 -0
  181. package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -0
  182. package/dist/plugins/compose-semantic-classifier.js +216 -0
  183. package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
  184. package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
  185. package/dist/plugins/compose-vocabulary-alignment.js +141 -0
  186. package/dist/plugins/external-allowlist.d.ts +17 -0
  187. package/dist/plugins/external-allowlist.d.ts.map +1 -0
  188. package/dist/plugins/external-allowlist.js +29 -0
  189. package/dist/plugins/index.d.ts +11 -0
  190. package/dist/plugins/index.d.ts.map +1 -0
  191. package/dist/plugins/index.js +37 -0
  192. package/dist/plugins/load-plugin.d.ts +19 -0
  193. package/dist/plugins/load-plugin.d.ts.map +1 -0
  194. package/dist/plugins/load-plugin.js +59 -0
  195. package/dist/plugins/project-config.d.ts +28 -0
  196. package/dist/plugins/project-config.d.ts.map +1 -0
  197. package/dist/plugins/project-config.js +90 -0
  198. package/dist/plugins/registry.d.ts +94 -0
  199. package/dist/plugins/registry.d.ts.map +1 -0
  200. package/dist/plugins/registry.js +359 -0
  201. package/dist/plugins/resolve-package.d.ts +47 -0
  202. package/dist/plugins/resolve-package.d.ts.map +1 -0
  203. package/dist/plugins/resolve-package.js +262 -0
  204. package/dist/plugins/source-analysis-service.d.ts +44 -0
  205. package/dist/plugins/source-analysis-service.d.ts.map +1 -0
  206. package/dist/plugins/source-analysis-service.js +232 -0
  207. package/dist/prolog/codec.d.ts.map +1 -1
  208. package/dist/prolog/codec.js +2 -0
  209. package/dist/prolog/janitor.d.ts.map +1 -1
  210. package/dist/prolog/janitor.js +1 -1
  211. package/dist/prolog/store-lock.d.ts +1 -1
  212. package/dist/prolog/store-lock.d.ts.map +1 -1
  213. package/dist/prolog.d.ts +36 -0
  214. package/dist/prolog.d.ts.map +1 -1
  215. package/dist/prolog.js +78 -9
  216. package/dist/proof/inspect.js +1 -1
  217. package/dist/proof/producers/playwright-case-id.js +2 -2
  218. package/dist/proof/producers/playwright-reporter.js +4 -4
  219. package/dist/public/diagnostic-usage.d.ts.map +1 -1
  220. package/dist/public/diagnostic-usage.js +7 -25
  221. package/dist/public/extractors/symbols-coordinator.d.ts +1 -1
  222. package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
  223. package/dist/public/extractors/symbols-coordinator.js +1 -1
  224. package/dist/public/impact/analyzer.d.ts +1 -1
  225. package/dist/public/impact/analyzer.d.ts.map +1 -1
  226. package/dist/public/impact/analyzer.js +6 -4
  227. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  228. package/dist/public/impact/full-kb-quality.js +4 -12
  229. package/dist/public/operations/catalog.d.ts +39 -7
  230. package/dist/public/operations/catalog.d.ts.map +1 -1
  231. package/dist/public/operations/check-executor.d.ts.map +1 -1
  232. package/dist/public/operations/check-executor.js +11 -3
  233. package/dist/public/operations/check-helpers.d.ts +7 -1
  234. package/dist/public/operations/check-helpers.d.ts.map +1 -1
  235. package/dist/public/operations/check-helpers.js +22 -2
  236. package/dist/public/operations/contracts.d.ts.map +1 -1
  237. package/dist/public/operations/contracts.js +51 -12
  238. package/dist/public/operations/discovery-entities.d.ts +53 -1
  239. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  240. package/dist/public/operations/discovery-entities.js +219 -12
  241. package/dist/public/operations/discovery-executors.d.ts +1 -0
  242. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  243. package/dist/public/operations/discovery-executors.js +93 -59
  244. package/dist/public/operations/migration-plan.d.ts +2 -0
  245. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  246. package/dist/public/operations/migration-plan.js +50 -0
  247. package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
  248. package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
  249. package/dist/public/operations/predicate-schema-conformance.js +242 -0
  250. package/dist/public/operations/prolog-json.d.ts +1 -1
  251. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  252. package/dist/public/operations/prolog-json.js +16 -10
  253. package/dist/public/operations/result-envelope.d.ts +34 -1
  254. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  255. package/dist/public/operations/result-envelope.js +78 -2
  256. package/dist/public/operations/runtime-types.d.ts +17 -2
  257. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  258. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  259. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  260. package/dist/public/operations/specs/check-rules.generated.js +9 -1
  261. package/dist/public/operations/specs/check.d.ts +1 -1
  262. package/dist/public/operations/specs/discovery.d.ts +10 -1
  263. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  264. package/dist/public/operations/specs/discovery.js +10 -1
  265. package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
  266. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  267. package/dist/public/operations/specs/mutation-schemas.js +21 -3
  268. package/dist/public/operations/specs/proof.js +1 -1
  269. package/dist/public/operations/specs/reporting.d.ts +9 -0
  270. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  271. package/dist/public/operations/specs/reporting.js +48 -17
  272. package/dist/public/operations/specs/semantic.d.ts +1 -1
  273. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  274. package/dist/public/operations/specs/semantic.js +54 -4
  275. package/dist/public/operations/specs/upsert.d.ts +28 -5
  276. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  277. package/dist/public/operations/specs/upsert.js +1 -1
  278. package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
  279. package/dist/public/operations/symbol-repair-plan.js +11 -4
  280. package/dist/public/operations/types.d.ts +5 -0
  281. package/dist/public/operations/types.d.ts.map +1 -1
  282. package/dist/public/proof-protocol.js +4 -4
  283. package/dist/public/schemas/entity.d.ts.map +1 -1
  284. package/dist/public/schemas/entity.js +22 -0
  285. package/dist/public/schemas/relationship.d.ts.map +1 -1
  286. package/dist/public/schemas/relationship.js +1 -0
  287. package/dist/public/skills/kibi-usage/SKILL.md +10 -3
  288. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  289. package/dist/public/skills/kibi-usage/resources/proof.md +45 -0
  290. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  291. package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  292. package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
  293. package/dist/public/symbol-granularity.d.ts +1 -1
  294. package/dist/public/symbol-granularity.d.ts.map +1 -1
  295. package/dist/public/symbol-granularity.generated.d.ts.map +1 -1
  296. package/dist/public/symbol-granularity.generated.js +38 -5
  297. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  298. package/dist/public/telemetry-acceptance.js +21 -5
  299. package/dist/relationships/shards.d.ts +6 -0
  300. package/dist/relationships/shards.d.ts.map +1 -1
  301. package/dist/relationships/shards.js +26 -19
  302. package/dist/report/html-report.css +1239 -281
  303. package/dist/runtime/cli-runtime.d.ts.map +1 -1
  304. package/dist/runtime/cli-runtime.js +18 -0
  305. package/dist/schemas/entity.schema.json +32 -0
  306. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  307. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  308. package/dist/traceability/staged-entity-id-style.d.ts +12 -0
  309. package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
  310. package/dist/traceability/staged-entity-id-style.js +68 -0
  311. package/dist/traceability/symbol-extract.d.ts +24 -7
  312. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  313. package/dist/traceability/symbol-extract.js +64 -208
  314. package/dist/traceability/temp-kb.d.ts.map +1 -1
  315. package/dist/traceability/temp-kb.js +8 -0
  316. package/dist/traceability/validate.js +1 -1
  317. package/dist/types/entities.d.ts +2 -0
  318. package/dist/types/entities.d.ts.map +1 -1
  319. package/dist/types/relationships.d.ts +1 -1
  320. package/dist/types/relationships.d.ts.map +1 -1
  321. package/dist/utils/entity-id-style.d.ts +27 -0
  322. package/dist/utils/entity-id-style.d.ts.map +1 -0
  323. package/dist/utils/entity-id-style.js +81 -0
  324. package/dist/utils/git-repository-context.d.ts +50 -0
  325. package/dist/utils/git-repository-context.d.ts.map +1 -0
  326. package/dist/utils/git-repository-context.js +259 -0
  327. package/dist/utils/rule-registry.d.ts +5 -0
  328. package/dist/utils/rule-registry.d.ts.map +1 -1
  329. package/dist/utils/rule-registry.generated.d.ts +42 -0
  330. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  331. package/dist/utils/rule-registry.generated.js +50 -0
  332. package/dist/utils/strict-modeling.d.ts +7 -0
  333. package/dist/utils/strict-modeling.d.ts.map +1 -1
  334. package/dist/utils/strict-modeling.js +11 -0
  335. package/package.json +14 -11
  336. package/schema/entities.pl +60 -1
  337. package/schema/relationships.pl +17 -4
  338. package/schema/validation.pl +118 -20
  339. package/src/public/diagnostic-usage.ts +16 -24
  340. package/src/public/extractors/symbols-coordinator.ts +1 -0
  341. package/src/public/impact/analyzer.ts +15 -12
  342. package/src/public/impact/full-kb-quality.ts +4 -16
  343. package/src/public/operations/check-executor.ts +13 -2
  344. package/src/public/operations/check-helpers.ts +29 -3
  345. package/src/public/operations/contracts.ts +59 -12
  346. package/src/public/operations/discovery-entities.ts +327 -12
  347. package/src/public/operations/discovery-executors.ts +110 -61
  348. package/src/public/operations/migration-plan.ts +57 -0
  349. package/src/public/operations/predicate-schema-conformance.ts +362 -0
  350. package/src/public/operations/prolog-json.ts +22 -8
  351. package/src/public/operations/result-envelope.ts +114 -2
  352. package/src/public/operations/runtime-types.ts +22 -3
  353. package/src/public/operations/specs/check-rules.generated.ts +9 -1
  354. package/src/public/operations/specs/discovery.ts +11 -1
  355. package/src/public/operations/specs/mutation-schemas.ts +23 -3
  356. package/src/public/operations/specs/proof.ts +1 -1
  357. package/src/public/operations/specs/reporting.ts +71 -24
  358. package/src/public/operations/specs/semantic.ts +79 -17
  359. package/src/public/operations/specs/upsert.ts +1 -1
  360. package/src/public/operations/symbol-repair-plan.ts +16 -7
  361. package/src/public/operations/types.ts +5 -0
  362. package/src/public/proof-fingerprint.ts +1 -1
  363. package/src/public/proof-protocol-types.d.ts +1 -1
  364. package/src/public/proof-protocol.ts +4 -4
  365. package/src/public/schemas/entity.ts +22 -0
  366. package/src/public/schemas/relationship.ts +1 -0
  367. package/src/public/skills/kibi-usage/SKILL.md +10 -3
  368. package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  369. package/src/public/skills/kibi-usage/resources/proof.md +45 -0
  370. package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  371. package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  372. package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
  373. package/src/public/symbol-granularity.generated.ts +45 -12
  374. package/src/public/symbol-granularity.ts +3 -3
  375. package/src/public/telemetry-acceptance.ts +37 -6
  376. package/src/schemas/entity.schema.json +32 -0
  377. package/src/schemas/relationship.schema.json +1 -0
@@ -1,3 +1,4 @@
1
+ import { execSync } from "node:child_process";
1
2
  import { readFileSync } from "node:fs";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import path from "node:path";
@@ -20,6 +21,8 @@ import path from "node:path";
20
21
  */
21
22
  import { getKbPlPathOverride } from "../../env.js";
22
23
  import { resolveKbPlPath } from "../../prolog.js";
24
+ import { getStagedFiles } from "../../traceability/git-staged.js";
25
+ import { createStagedEntityIdStyleDiagnostics } from "../../traceability/staged-entity-id-style.js";
23
26
  import { analyzePrologQueryPlanSafety } from "../../utils/prolog-query-plan-safety.js";
24
27
  import {
25
28
  RULE_NAMES,
@@ -63,7 +66,7 @@ export function partitionCheckFindings(findings: readonly Violation[]): {
63
66
  const definition = getRuleDefinition(finding.rule);
64
67
  qualityDiagnostics.push({
65
68
  id: `rule.${finding.rule}`,
66
- severity: "warning",
69
+ severity: definition?.diagnosticSeverity ?? "warning",
67
70
  blocking: false,
68
71
  category: definition?.category ?? "integrity",
69
72
  ...(finding.entityId !== undefined ? { entityId: finding.entityId } : {}),
@@ -144,10 +147,10 @@ export function hasImpactOptions(args: CheckInput): boolean {
144
147
  }
145
148
 
146
149
  // implements REQ-mcp-tool-check
147
- export function analyzeKbCheckImpact(
150
+ export async function analyzeKbCheckImpact(
148
151
  workspaceRoot: string,
149
152
  args: CheckInput,
150
- ): ChangedFileImpactResult | undefined {
153
+ ): Promise<ChangedFileImpactResult | undefined> {
151
154
  if (!hasImpactOptions(args)) {
152
155
  return undefined;
153
156
  }
@@ -169,6 +172,29 @@ export function analyzeKbCheckImpact(
169
172
  });
170
173
  }
171
174
 
175
+ /**
176
+ * Advisory naming-style review for entity Markdown staged as new. Runs only
177
+ * for `staged: true`, the creation boundary where a purely numeric ID can
178
+ * still be renamed cheaply; committed legacy entities are never evaluated.
179
+ */
180
+ // implements REQ-kibi-entity-id-style
181
+ export function stagedEntityIdStyleDiagnostics(
182
+ workspaceRoot: string,
183
+ args: Pick<CheckInput, "staged">,
184
+ ): readonly QualityDiagnostic[] {
185
+ if (args.staged !== true) return [];
186
+ try {
187
+ return createStagedEntityIdStyleDiagnostics(
188
+ getStagedFiles((command, options) =>
189
+ execSync(command, { ...options, cwd: workspaceRoot }),
190
+ ),
191
+ );
192
+ } catch {
193
+ // Outside a Git work tree there is no staged creation boundary.
194
+ return [];
195
+ }
196
+ }
197
+
172
198
  // implements REQ-mcp-tool-check
173
199
  export function qualityDiagnosticsFromImpact(
174
200
  impactResult: ChangedFileImpactResult | undefined,
@@ -33,6 +33,25 @@ function objectData(
33
33
  };
34
34
  }
35
35
 
36
+ /**
37
+ * kibi.job.v1 receipt returned by async-mode operations (kb_check with
38
+ * `async: true`) instead of the synchronous payload. Agents poll
39
+ * kb_job_status with the jobId. Declared as a union member of the operation
40
+ * data contract so hosts validating tool output against the declared schema
41
+ * accept the receipt without weakening the synchronous payload contract.
42
+ */
43
+ const jobReceiptData: OperationJsonSchema = objectData(
44
+ {
45
+ kibiProtocol: { const: 1 },
46
+ jobVersion: { const: "kibi.job.v1" },
47
+ jobId: { type: "string" },
48
+ tool: { type: "string" },
49
+ status: { type: "string" },
50
+ pollWith: { const: "kb_job_status" },
51
+ },
52
+ ["kibiProtocol", "jobVersion", "jobId", "tool", "status", "pollWith"],
53
+ );
54
+
36
55
  const stringValue: OperationJsonSchema = { type: "string" };
37
56
  const integerValue: OperationJsonSchema = { type: "integer" };
38
57
  const numberValue: OperationJsonSchema = { type: "number" };
@@ -135,6 +154,7 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
135
154
  kb_semantic_advisor: objectData({
136
155
  receipt: recordValue,
137
156
  warnings: stringArray,
157
+ capabilityPlugins: recordValue,
138
158
  }),
139
159
  kb_model_requirement: objectData({
140
160
  statement: stringValue,
@@ -152,6 +172,24 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
152
172
  warnings: recordArray,
153
173
  migrationWarning: { type: ["string", "null"] },
154
174
  logic: recordValue,
175
+ vocabularyAlignment: objectData(
176
+ {
177
+ subject: recordValue,
178
+ redundancyCandidates: recordArray,
179
+ reviewPlan: recordArray,
180
+ stamps: recordArray,
181
+ fallbackUsed: booleanValue,
182
+ diagnostics: recordArray,
183
+ },
184
+ [
185
+ "subject",
186
+ "redundancyCandidates",
187
+ "reviewPlan",
188
+ "stamps",
189
+ "fallbackUsed",
190
+ "diagnostics",
191
+ ],
192
+ ),
155
193
  }),
156
194
  kb_suggest_predicates: objectData({
157
195
  text: stringValue,
@@ -236,22 +274,30 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
236
274
  sourceWrites: recordArray,
237
275
  deletionPlan: recordValue,
238
276
  supersessionPlan: recordValue,
277
+ skippedEffects: stringArray,
239
278
  status: stringValue,
240
279
  effectFailures: recordArray,
241
280
  nextActions: recordArray,
242
281
  }),
243
- kb_check: objectData({
244
- violations: valueArray,
245
- count: integerValue,
246
- diagnostics: recordArray,
247
- qualityDiagnostics: recordArray,
248
- impactDiagnostics: recordArray,
249
- sourceFiles: stringArray,
250
- extractedSymbols: recordArray,
251
- linkedEntities: recordArray,
252
- nextActions: valueArray,
253
- migrationPlan: recordValue,
254
- }),
282
+ kb_check: {
283
+ description:
284
+ "Synchronous check payload, or a kibi.job.v1 receipt when async:true detached the check into a background job (poll kb_job_status with the jobId).",
285
+ anyOf: [
286
+ objectData({
287
+ violations: valueArray,
288
+ count: integerValue,
289
+ diagnostics: recordArray,
290
+ qualityDiagnostics: recordArray,
291
+ impactDiagnostics: recordArray,
292
+ sourceFiles: stringArray,
293
+ extractedSymbols: recordArray,
294
+ linkedEntities: recordArray,
295
+ nextActions: valueArray,
296
+ migrationPlan: recordValue,
297
+ }),
298
+ jobReceiptData,
299
+ ],
300
+ },
255
301
  kb_compile_intent: objectData({
256
302
  version: stringValue,
257
303
  planHash: stringValue,
@@ -265,6 +311,7 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
265
311
  steps: valueArray,
266
312
  sourceWrites: recordArray,
267
313
  diagnostics: stringArray,
314
+ capabilityPlugins: recordValue,
268
315
  }),
269
316
  kb_apply_plan: objectData({
270
317
  version: stringValue,
@@ -1,10 +1,18 @@
1
1
  import {
2
2
  escapeAtomContent,
3
+ normalizeEntityId,
4
+ parseAtomList,
3
5
  parseEntityFromBinding,
4
6
  parseEntityFromList,
5
7
  parseListOfLists,
6
8
  } from "../../prolog/codec.js";
7
- import type { PrologPort } from "./runtime-types.js";
9
+ import type {
10
+ PrologEntityQueryInput,
11
+ PrologEntityQueryResult,
12
+ PrologPort,
13
+ PrologSearchQueryInput,
14
+ PrologSearchQueryResult,
15
+ } from "./runtime-types.js";
8
16
 
9
17
  export type EntityQueryInput = {
10
18
  readonly type?: string;
@@ -14,6 +22,11 @@ export type EntityQueryInput = {
14
22
  /** Page size for index-backed queries; bounds each query's output. */
15
23
  readonly limit?: number;
16
24
  readonly offset?: number;
25
+ /**
26
+ * Proof selection only needs the contract. Omit receipt histories so a
27
+ * campaign does not page every full test entity.
28
+ */
29
+ readonly projection?: "proof_contract";
17
30
  };
18
31
 
19
32
  export const VALID_ENTITY_TYPES = [
@@ -36,9 +49,22 @@ export function validateEntityType(type?: string): void {
36
49
  }
37
50
  }
38
51
 
52
+ /**
53
+ * Proof campaign selection must not materialize every contracted test in a
54
+ * single Prolog result. The specialized projection excludes receipt histories
55
+ * and returns one bounded page at a time.
56
+ */
57
+ export const PROOF_CONTRACT_PAGE_SIZE = 100;
58
+
39
59
  // implements REQ-002, REQ-013
40
60
  export function buildEntityGoal(input: EntityQueryInput): string {
41
61
  const { type, id, tags, sourceFile } = input;
62
+ if (type === "test" && input.projection === "proof_contract") {
63
+ const idTerm = id ? `some('${escapeAtomContent(id)}')` : "none";
64
+ const limit = input.limit ?? PROOF_CONTRACT_PAGE_SIZE;
65
+ const offset = input.offset ?? 0;
66
+ return `kb_query_proof_contracts(${idTerm},${limit},${offset},Results)`;
67
+ }
42
68
  if (sourceFile) {
43
69
  const safeSource = escapeAtomContent(sourceFile);
44
70
  if (type) {
@@ -75,24 +101,72 @@ export function buildEntityGoal(input: EntityQueryInput): string {
75
101
  return "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)";
76
102
  }
77
103
 
104
+ /**
105
+ * Full test entities carry their receipt histories, which only grow. Callers
106
+ * that must see every full entity of a type page through the indexed query so
107
+ * no single Prolog answer can approach the bounded output capacity.
108
+ */
109
+ const FULL_ENTITY_PAGE_SIZE = 25;
110
+
111
+ // implements REQ-002, REQ-013
112
+ export async function loadEntitiesPaged(
113
+ prolog: Pick<PrologPort, "query">,
114
+ type: (typeof VALID_ENTITY_TYPES)[number],
115
+ pageSize: number = FULL_ENTITY_PAGE_SIZE,
116
+ ): Promise<Record<string, unknown>[]> {
117
+ if (!Number.isInteger(pageSize) || pageSize <= 0) {
118
+ throw new Error("loadEntitiesPaged pageSize must be a positive integer");
119
+ }
120
+ const entities: Record<string, unknown>[] = [];
121
+ for (let offset = 0; ; offset += pageSize) {
122
+ const page = await loadEntities(prolog, { type, limit: pageSize, offset });
123
+ entities.push(...page);
124
+ if (page.length < pageSize) break;
125
+ }
126
+ return dedupeEntities(entities);
127
+ }
128
+
78
129
  // implements REQ-002, REQ-013
79
130
  export async function loadEntities(
80
131
  prolog: Pick<PrologPort, "query">,
81
132
  input: EntityQueryInput,
82
133
  ): Promise<Record<string, unknown>[]> {
83
134
  validateEntityType(input.type);
84
- const queryResult = await prolog.query(buildEntityGoal(input));
85
- if (!queryResult.success) {
86
- throw new Error(queryResult.error || "Query failed with unknown error");
87
- }
135
+ const readPage = async (
136
+ pageInput: EntityQueryInput,
137
+ ): Promise<Record<string, unknown>[]> => {
138
+ const queryResult = await prolog.query(buildEntityGoal(pageInput));
139
+ if (!queryResult.success) {
140
+ throw new Error(queryResult.error || "Query failed with unknown error");
141
+ }
142
+ const resultsBinding = queryResult.bindings.Results;
143
+ const resultBinding = queryResult.bindings.Result;
144
+ if (resultsBinding) {
145
+ return parseListOfLists(resultsBinding).map(parseEntityFromList);
146
+ }
147
+ return resultBinding ? [parseEntityFromBinding(resultBinding)] : [];
148
+ };
88
149
 
89
- let entities: Record<string, unknown>[] = [];
90
- const resultsBinding = queryResult.bindings.Results;
91
- const resultBinding = queryResult.bindings.Result;
92
- if (resultsBinding) {
93
- entities = parseListOfLists(resultsBinding).map(parseEntityFromList);
94
- } else if (resultBinding) {
95
- entities = [parseEntityFromBinding(resultBinding)];
150
+ let entities: Record<string, unknown>[];
151
+ if (
152
+ input.type === "test" &&
153
+ input.projection === "proof_contract" &&
154
+ input.id === undefined &&
155
+ input.limit === undefined &&
156
+ input.offset === undefined
157
+ ) {
158
+ entities = [];
159
+ for (let offset = 0; ; offset += PROOF_CONTRACT_PAGE_SIZE) {
160
+ const page = await readPage({
161
+ ...input,
162
+ limit: PROOF_CONTRACT_PAGE_SIZE,
163
+ offset,
164
+ });
165
+ entities.push(...page);
166
+ if (page.length < PROOF_CONTRACT_PAGE_SIZE) break;
167
+ }
168
+ } else {
169
+ entities = await readPage(input);
96
170
  }
97
171
  if (input.tags && input.tags.length > 0) {
98
172
  const requested = new Set(input.tags.map((tag) => tag.trim()));
@@ -116,6 +190,247 @@ export function paginateResults<T>(
116
190
  return results.slice(offset, offset + limit);
117
191
  }
118
192
 
193
+ /**
194
+ * Page size for index-backed search candidate fetches. Each page is one
195
+ * Prolog query, so a fixed page size substantially bounds each response and
196
+ * fixes the observed large-KB output overflow; it is a practical bound, not
197
+ * a byte-size guarantee for arbitrarily large individual entity payloads.
198
+ */
199
+ // implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
200
+ export const SEARCH_CANDIDATE_PAGE_SIZE = 500;
201
+
202
+ function isPrologOutputOverflow(error: unknown): boolean {
203
+ return error instanceof Error && error.message.includes("ENOBUFS");
204
+ }
205
+
206
+ // implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
207
+ export async function loadSearchCandidates(
208
+ prolog: Pick<PrologPort, "searchEntities"> &
209
+ Partial<Pick<PrologPort, "query">>,
210
+ input: {
211
+ readonly query: string;
212
+ readonly type?: string;
213
+ readonly maxCandidates?: number;
214
+ },
215
+ signal?: AbortSignal,
216
+ ): Promise<Record<string, unknown>[]> {
217
+ // Call through the port property, never via a detached local: EngineClient
218
+ // searchEntities depends on `this` (this.command), and the PrologPort
219
+ // contract does not promise a pre-bound method. Ports without the indexed
220
+ // engine method run the same bounded Prolog search through `query`.
221
+ const readPage = (
222
+ page: PrologSearchQueryInput,
223
+ ): Promise<PrologSearchQueryResult> => {
224
+ if (prolog.searchEntities) return prolog.searchEntities(page, signal);
225
+ const query = prolog.query;
226
+ if (query === undefined) return Promise.resolve({ entities: [], count: 0 });
227
+ return searchEntitiesViaQuery(
228
+ { query: (goal, querySignal) => query.call(prolog, goal, querySignal) },
229
+ page,
230
+ signal,
231
+ );
232
+ };
233
+ return readCandidatePages(readPage, input);
234
+ }
235
+
236
+ /**
237
+ * Projected candidate rows for every entity (optionally of one type), in id
238
+ * order, bounded by `maxCandidates`. For semantic discovery that has no
239
+ * lexical token to pre-filter candidates.
240
+ */
241
+ // implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
242
+ export async function listSearchCandidates(
243
+ prolog: Pick<PrologPort, "query">,
244
+ input: { readonly type?: string; readonly maxCandidates: number },
245
+ signal?: AbortSignal,
246
+ ): Promise<Record<string, unknown>[]> {
247
+ const type = input.type ? `'${escapeAtomContent(input.type)}'` : "none";
248
+ return readCandidatePages(
249
+ (page) =>
250
+ readRowsAndCount(
251
+ prolog,
252
+ `kb_list_search_candidates(${type}, ${page.limit}, ${page.offset}, Rows, Count)`,
253
+ "Search candidate listing failed",
254
+ signal,
255
+ ),
256
+ { query: "", maxCandidates: input.maxCandidates },
257
+ );
258
+ }
259
+
260
+ async function readCandidatePages(
261
+ readPage: (page: PrologSearchQueryInput) => Promise<PrologSearchQueryResult>,
262
+ input: {
263
+ readonly query: string;
264
+ readonly type?: string;
265
+ readonly maxCandidates?: number;
266
+ },
267
+ ): Promise<Record<string, unknown>[]> {
268
+ const maxCandidates = input.maxCandidates ?? Number.POSITIVE_INFINITY;
269
+ const candidates: Record<string, unknown>[] = [];
270
+ let offset = 0;
271
+ let total = Number.POSITIVE_INFINITY;
272
+ let pageSize = SEARCH_CANDIDATE_PAGE_SIZE;
273
+ while (offset < total && candidates.length < maxCandidates) {
274
+ let page: PrologSearchQueryResult;
275
+ try {
276
+ page = await readPage({
277
+ query: input.query,
278
+ ...(input.type !== undefined ? { type: input.type } : {}),
279
+ limit: pageSize,
280
+ offset,
281
+ });
282
+ } catch (error) {
283
+ // A page of unusually large rows can still exceed the bounded Prolog
284
+ // output. Halve the page and retry the same offset; the smaller size is
285
+ // kept for the rest of the scan. Only a single row that overflows on its
286
+ // own is a real failure.
287
+ if (pageSize > 1 && isPrologOutputOverflow(error)) {
288
+ pageSize = Math.max(1, Math.floor(pageSize / 2));
289
+ continue;
290
+ }
291
+ throw error;
292
+ }
293
+ if (page.entities.length === 0) break;
294
+ candidates.push(...page.entities);
295
+ total = page.count;
296
+ offset += page.entities.length;
297
+ }
298
+ return Number.isFinite(maxCandidates)
299
+ ? candidates.slice(0, maxCandidates)
300
+ : candidates;
301
+ }
302
+
303
+ function searchEntitiesViaQuery(
304
+ prolog: Pick<PrologPort, "query">,
305
+ input: PrologSearchQueryInput,
306
+ signal?: AbortSignal,
307
+ ): Promise<PrologSearchQueryResult> {
308
+ const type = input.type ? `'${escapeAtomContent(input.type)}'` : "none";
309
+ return readRowsAndCount(
310
+ prolog,
311
+ `kb_search_entities(${type}, '${escapeAtomContent(input.query)}', ${input.limit}, ${input.offset}, Rows, Count)`,
312
+ "Indexed search candidate query failed",
313
+ signal,
314
+ );
315
+ }
316
+
317
+ async function readRowsAndCount(
318
+ prolog: Pick<PrologPort, "query">,
319
+ goal: string,
320
+ errorLabel: string,
321
+ signal?: AbortSignal,
322
+ ): Promise<PrologEntityQueryResult> {
323
+ const result = await prolog.query(goal, signal);
324
+ if (!result.success) {
325
+ // Same message as the engine client's indexed methods, so both surfaces
326
+ // report a failure identically.
327
+ throw new Error(result.error ?? errorLabel);
328
+ }
329
+ const entities = result.bindings.Rows
330
+ ? parseListOfLists(result.bindings.Rows).map(parseEntityFromList)
331
+ : [];
332
+ const count = Number.parseInt(result.bindings.Count ?? "0", 10);
333
+ return { entities, count: Number.isFinite(count) ? count : entities.length };
334
+ }
335
+
336
+ /**
337
+ * Rows per `kb_query_entities` request. Full entities carry receipt
338
+ * histories, so a caller-sized page (up to 100k rows) is split into bounded
339
+ * requests and concatenated; the reported count is the total match count.
340
+ */
341
+ export const ENTITY_QUERY_CHUNK_SIZE = 25;
342
+
343
+ // implements REQ-kibi-operation-interface-parity
344
+ export async function queryEntityChunks(
345
+ readChunk: (
346
+ input: PrologEntityQueryInput,
347
+ ) => Promise<PrologEntityQueryResult>,
348
+ input: PrologEntityQueryInput,
349
+ ): Promise<PrologEntityQueryResult> {
350
+ const entities: Record<string, unknown>[] = [];
351
+ let count = 0;
352
+ let first = true;
353
+ while (first || entities.length < input.limit) {
354
+ const chunkLimit = Math.min(
355
+ ENTITY_QUERY_CHUNK_SIZE,
356
+ input.limit - entities.length,
357
+ );
358
+ const chunk = await readChunk({
359
+ ...input,
360
+ limit: chunkLimit,
361
+ offset: input.offset + entities.length,
362
+ });
363
+ if (first) count = chunk.count;
364
+ first = false;
365
+ entities.push(...chunk.entities);
366
+ if (chunk.entities.length < chunkLimit || chunkLimit === 0) break;
367
+ }
368
+ return { entities, count };
369
+ }
370
+
371
+ /** Bounded `kb_query_entities` paging for ports without the engine method. */
372
+ // implements REQ-kibi-operation-interface-parity
373
+ export function queryEntitiesViaQuery(
374
+ prolog: Pick<PrologPort, "query">,
375
+ input: PrologEntityQueryInput,
376
+ signal?: AbortSignal,
377
+ ): Promise<PrologEntityQueryResult> {
378
+ const atom = (value: string | undefined) =>
379
+ value === undefined ? "none" : `'${escapeAtomContent(value)}'`;
380
+ const tags = `[${(input.tags ?? []).map((tag) => `'${escapeAtomContent(tag)}'`).join(",")}]`;
381
+ return queryEntityChunks(
382
+ (chunk) =>
383
+ readRowsAndCount(
384
+ prolog,
385
+ `kb_query_entities(${atom(chunk.type)}, ${atom(chunk.id)}, ${tags}, ${atom(chunk.sourceFile)}, ${chunk.limit}, ${chunk.offset}, Rows, Count)`,
386
+ "Indexed entity query failed",
387
+ signal,
388
+ ),
389
+ input,
390
+ );
391
+ }
392
+
393
+ /** Every entity id, without materializing entity properties. */
394
+ // implements REQ-002
395
+ export async function loadEntityIds(
396
+ prolog: Pick<PrologPort, "query">,
397
+ ): Promise<string[]> {
398
+ const result = await prolog.query("kb_entity_ids(Ids)");
399
+ if (!result.success) {
400
+ throw new Error(
401
+ `Entity id enumeration failed: ${result.error ?? "Unknown error"}`,
402
+ );
403
+ }
404
+ return parseAtomList(result.bindings.Ids ?? "[]").map(normalizeEntityId);
405
+ }
406
+
407
+ /**
408
+ * Replace projected search candidates with complete entities, one bounded
409
+ * query per entity. Used only for the final result page when a caller asks
410
+ * for full entity bodies.
411
+ */
412
+ // implements REQ-mcp-search-discovery
413
+ export async function reloadFullEntities<
414
+ TMatch extends { readonly entity: Record<string, unknown> },
415
+ >(
416
+ prolog: Pick<PrologPort, "query">,
417
+ matches: readonly TMatch[],
418
+ ): Promise<TMatch[]> {
419
+ const reloaded: TMatch[] = [];
420
+ for (const match of matches) {
421
+ const id = String(match.entity.id ?? "");
422
+ const type = match.entity.type;
423
+ const [full] = id
424
+ ? await loadEntities(prolog, {
425
+ id,
426
+ ...(typeof type === "string" ? { type } : {}),
427
+ })
428
+ : [];
429
+ reloaded.push(full ? { ...match, entity: full } : match);
430
+ }
431
+ return reloaded;
432
+ }
433
+
119
434
  // implements REQ-002
120
435
  export function dedupeEntities(
121
436
  entities: readonly Record<string, unknown>[],