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
@@ -0,0 +1,362 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import { BUILT_IN_PREDICATE_SCHEMAS } from "../../operations/modeling/predicate-catalog.js";
20
+ import {
21
+ type ArgumentRewrite,
22
+ type UndeclaredArgument,
23
+ applyArgumentRewrites,
24
+ predicateArgumentConformance,
25
+ predicateCanonicalKey,
26
+ predicateVocabularyErrors,
27
+ predicateVocabularyFromEntity,
28
+ } from "../../operations/modeling/predicate-vocabulary.js";
29
+ import type { Violation } from "../../utils/rule-registry.js";
30
+ import entitySchema from "../schemas/entity.js";
31
+ import { loadEntitiesPaged } from "./discovery-entities.js";
32
+ import type { PrologPort } from "./runtime-types.js";
33
+
34
+ const RULE = "predicate-schema-conformance";
35
+
36
+ /** Every property the public entity schema accepts. */
37
+ const AUTHORED_FIELDS: ReadonlySet<string> = new Set(
38
+ Object.keys(entitySchema.properties as Record<string, unknown>),
39
+ );
40
+ const DEFAULT_NAMESPACE = "default";
41
+
42
+ /** Fields that belong to the compiled entity, not to an authored upsert. */
43
+ const NON_AUTHORED_FIELDS = new Set([
44
+ "id",
45
+ "type",
46
+ "source",
47
+ "sourceFile",
48
+ "created_at",
49
+ "updated_at",
50
+ "links",
51
+ "relationships",
52
+ ]);
53
+
54
+ type Entity = Readonly<Record<string, unknown>>;
55
+
56
+ type SchemaRef = Readonly<{
57
+ schemaId: string;
58
+ namespace: string;
59
+ origin: "project_local" | "built_in";
60
+ argumentNames: readonly string[];
61
+ entity?: Entity;
62
+ }>;
63
+
64
+ /**
65
+ * Exact kb_upsert input that repairs one predicate fact mechanically: move it
66
+ * to the only namespace whose schema matches, and/or replace alias spellings
67
+ * with their declared constants. Present only when nothing is left for review.
68
+ */
69
+ // implements REQ-kibi-predicate-vocabulary-migration
70
+ export type PredicateFactRepair = Readonly<{
71
+ type: "fact";
72
+ id: string;
73
+ properties: Readonly<Record<string, unknown>>;
74
+ }>;
75
+
76
+ // implements REQ-kibi-predicate-vocabulary-migration
77
+ export type PredicateConformanceEvidence = Readonly<{
78
+ factId: string;
79
+ predicateName: string;
80
+ namespace: string;
81
+ arity: number;
82
+ issue: "missing_schema" | "undeclared_constant" | "alias_in_use";
83
+ schemaId: string | null;
84
+ alignment: Readonly<{
85
+ namespace: string;
86
+ schemaId: string;
87
+ origin: "project_local" | "built_in";
88
+ }> | null;
89
+ candidateNamespaces: readonly string[];
90
+ rewrites: readonly ArgumentRewrite[];
91
+ undeclared: readonly UndeclaredArgument[];
92
+ repair: PredicateFactRepair | null;
93
+ }>;
94
+
95
+ function text(value: unknown): string | undefined {
96
+ return typeof value === "string" && value.trim() !== ""
97
+ ? value.trim()
98
+ : undefined;
99
+ }
100
+
101
+ function strings(value: unknown): string[] {
102
+ return Array.isArray(value)
103
+ ? value.filter((item): item is string => typeof item === "string")
104
+ : [];
105
+ }
106
+
107
+ function sourceField(entity: Entity): { source?: string } {
108
+ const source = text(entity.source);
109
+ return source !== undefined ? { source } : {};
110
+ }
111
+
112
+ function namespaceOf(entity: Entity): string {
113
+ return text(entity.predicate_namespace) ?? DEFAULT_NAMESPACE;
114
+ }
115
+
116
+ function signature(namespace: string, name: string, arity: number): string {
117
+ return `${namespace}:${name}/${arity}`;
118
+ }
119
+
120
+ function schemaRefs(facts: readonly Entity[]): Map<string, SchemaRef[]> {
121
+ const byName = new Map<string, SchemaRef[]>();
122
+ const add = (name: string, ref: SchemaRef) => {
123
+ byName.set(name, [...(byName.get(name) ?? []), ref]);
124
+ };
125
+ for (const entity of facts) {
126
+ if (entity.fact_kind !== "predicate_schema") continue;
127
+ const name = text(entity.predicate_name);
128
+ if (name === undefined) continue;
129
+ add(name, {
130
+ schemaId: String(entity.id),
131
+ namespace: namespaceOf(entity),
132
+ origin: "project_local",
133
+ argumentNames: strings(entity.argument_names),
134
+ entity,
135
+ });
136
+ }
137
+ // Built-in catalog schemas carry no namespace: facts that use them live in
138
+ // the default namespace. A project-local schema with the same signature wins.
139
+ for (const schema of BUILT_IN_PREDICATE_SCHEMAS) {
140
+ add(schema.predicate_name, {
141
+ schemaId: schema.id,
142
+ namespace: DEFAULT_NAMESPACE,
143
+ origin: "built_in",
144
+ argumentNames: schema.argument_names,
145
+ });
146
+ }
147
+ return byName;
148
+ }
149
+
150
+ function authoredProperties(entity: Entity): Record<string, unknown> {
151
+ // Keep only fields an upsert accepts. Query rows also carry relationship
152
+ // projections (relates_to, validates, ...) as strings or lists, which must
153
+ // never be replayed as entity properties.
154
+ return Object.fromEntries(
155
+ Object.entries(entity).filter(
156
+ ([key, value]) =>
157
+ AUTHORED_FIELDS.has(key) &&
158
+ !NON_AUTHORED_FIELDS.has(key) &&
159
+ value !== null &&
160
+ value !== undefined,
161
+ ),
162
+ );
163
+ }
164
+
165
+ function repairFor(
166
+ fact: Entity,
167
+ name: string,
168
+ args: readonly string[],
169
+ targetNamespace: string | null,
170
+ rewrites: readonly ArgumentRewrite[],
171
+ ): PredicateFactRepair {
172
+ const nextArgs = applyArgumentRewrites(args, rewrites);
173
+ const properties = authoredProperties(fact);
174
+ const previousKey = predicateCanonicalKey(name, args);
175
+ const nextKey = predicateCanonicalKey(name, nextArgs);
176
+ if (targetNamespace !== null)
177
+ properties.predicate_namespace = targetNamespace;
178
+ if (rewrites.length > 0) {
179
+ properties.predicate_args = nextArgs;
180
+ properties.canonical_key = nextKey;
181
+ if (properties.title === `Predicate: ${previousKey}`) {
182
+ properties.title = `Predicate: ${nextKey}`;
183
+ }
184
+ }
185
+ return { type: "fact", id: String(fact.id), properties };
186
+ }
187
+
188
+ /**
189
+ * Predicate facts must match a schema (project-local, or the built-in catalog
190
+ * in the default namespace) with the same namespace, name, and arity, and
191
+ * must use declared constants where the schema closes an argument.
192
+ */
193
+ // implements REQ-kibi-predicate-schema-conformance
194
+ export function evaluatePredicateSchemaConformance(
195
+ facts: readonly Entity[],
196
+ ): Violation[] {
197
+ const schemasByName = schemaRefs(facts);
198
+ const violations: Violation[] = [];
199
+
200
+ for (const schema of facts) {
201
+ if (schema.fact_kind !== "predicate_schema") continue;
202
+ const errors = predicateVocabularyErrors(schema);
203
+ if (errors.length === 0) continue;
204
+ violations.push({
205
+ rule: RULE,
206
+ entityId: String(schema.id),
207
+ description: `Predicate schema ${String(schema.id)} declares an invalid argument vocabulary: ${errors.join("; ")}`,
208
+ suggestion:
209
+ "Key argument_constants and argument_aliases by argument_names, and map every alias to a declared constant.",
210
+ ...sourceField(schema),
211
+ evidence: { schemaId: String(schema.id), errors },
212
+ });
213
+ }
214
+
215
+ for (const fact of facts) {
216
+ if (fact.fact_kind !== "predicate") continue;
217
+ const name = text(fact.predicate_name);
218
+ const args = strings(fact.predicate_args);
219
+ if (name === undefined || args.length === 0) continue;
220
+ const namespace = namespaceOf(fact);
221
+ const arity = args.length;
222
+ const sameShape = (schemasByName.get(name) ?? []).filter(
223
+ (ref) => ref.argumentNames.length === arity,
224
+ );
225
+ const exact =
226
+ sameShape.find(
227
+ (ref) => ref.namespace === namespace && ref.origin === "project_local",
228
+ ) ??
229
+ sameShape.find(
230
+ (ref) => ref.namespace === namespace && ref.origin === "built_in",
231
+ );
232
+ const candidates = [
233
+ ...new Map(
234
+ sameShape
235
+ .filter((ref) => ref.namespace !== namespace)
236
+ .map((ref) => [ref.namespace, ref]),
237
+ ).values(),
238
+ ];
239
+ const alignment =
240
+ exact === undefined && candidates.length === 1
241
+ ? candidates[0]
242
+ : undefined;
243
+ const schema = exact ?? alignment;
244
+ const conformance =
245
+ schema?.entity !== undefined
246
+ ? predicateArgumentConformance(
247
+ schema.argumentNames,
248
+ args,
249
+ predicateVocabularyFromEntity(schema.entity),
250
+ )
251
+ : { rewrites: [], undeclared: [] };
252
+
253
+ if (
254
+ exact !== undefined &&
255
+ conformance.rewrites.length === 0 &&
256
+ conformance.undeclared.length === 0
257
+ ) {
258
+ continue;
259
+ }
260
+
261
+ const issue: PredicateConformanceEvidence["issue"] =
262
+ exact === undefined
263
+ ? "missing_schema"
264
+ : conformance.undeclared.length > 0
265
+ ? "undeclared_constant"
266
+ : "alias_in_use";
267
+ const mechanical =
268
+ schema !== undefined && conformance.undeclared.length === 0;
269
+ const evidence: PredicateConformanceEvidence = {
270
+ factId: String(fact.id),
271
+ predicateName: name,
272
+ namespace,
273
+ arity,
274
+ issue,
275
+ schemaId: exact?.schemaId ?? null,
276
+ alignment:
277
+ alignment !== undefined
278
+ ? {
279
+ namespace: alignment.namespace,
280
+ schemaId: alignment.schemaId,
281
+ origin: alignment.origin,
282
+ }
283
+ : null,
284
+ candidateNamespaces: candidates.map((ref) => ref.namespace).sort(),
285
+ rewrites: conformance.rewrites,
286
+ undeclared: conformance.undeclared,
287
+ repair: mechanical
288
+ ? repairFor(
289
+ fact,
290
+ name,
291
+ args,
292
+ alignment?.namespace ?? null,
293
+ conformance.rewrites,
294
+ )
295
+ : null,
296
+ };
297
+ violations.push({
298
+ rule: RULE,
299
+ entityId: String(fact.id),
300
+ description: conformanceDescription(evidence),
301
+ suggestion: conformanceSuggestion(evidence),
302
+ ...sourceField(fact),
303
+ evidence,
304
+ });
305
+ }
306
+ return violations;
307
+ }
308
+
309
+ function conformanceDescription(
310
+ evidence: PredicateConformanceEvidence,
311
+ ): string {
312
+ const where = signature(
313
+ evidence.namespace,
314
+ evidence.predicateName,
315
+ evidence.arity,
316
+ );
317
+ const parts: string[] = [];
318
+ if (evidence.issue === "missing_schema") {
319
+ parts.push(
320
+ evidence.alignment !== null
321
+ ? `Predicate fact ${evidence.factId} uses ${where}, but its schema ${evidence.alignment.schemaId} is in namespace ${evidence.alignment.namespace}`
322
+ : evidence.candidateNamespaces.length > 1
323
+ ? `Predicate fact ${evidence.factId} uses ${where}; schemas with this signature exist in several namespaces (${evidence.candidateNamespaces.join(", ")})`
324
+ : `Predicate fact ${evidence.factId} uses ${where}, which has no predicate_schema`,
325
+ );
326
+ } else {
327
+ parts.push(`Predicate fact ${evidence.factId} (${where})`);
328
+ }
329
+ for (const rewrite of evidence.rewrites) {
330
+ parts.push(
331
+ `argument ${rewrite.argumentName} uses alias ${rewrite.from} for ${rewrite.to}`,
332
+ );
333
+ }
334
+ for (const value of evidence.undeclared) {
335
+ parts.push(
336
+ `argument ${value.argumentName} value ${value.value} is not a declared constant (${value.allowed.join(", ")})`,
337
+ );
338
+ }
339
+ return parts.join("; ");
340
+ }
341
+
342
+ function conformanceSuggestion(evidence: PredicateConformanceEvidence): string {
343
+ if (evidence.repair !== null) {
344
+ return "Mechanical repair available: review and apply it with kibi migrate --apply-safe (or replay the kb_upsert in the migration action).";
345
+ }
346
+ if (evidence.undeclared.length > 0) {
347
+ return "Use a declared constant, add the value to argument_constants, or map it with argument_aliases so kibi migrate can rewrite it.";
348
+ }
349
+ if (evidence.candidateNamespaces.length > 1) {
350
+ return "Set predicate_namespace to the schema this claim belongs to.";
351
+ }
352
+ return "Declare a predicate_schema for this signature (kb_suggest_predicates helps pick an existing one) or move the claim to a schema that already exists.";
353
+ }
354
+
355
+ /** Load every fact once and evaluate predicate conformance. */
356
+ // implements REQ-kibi-predicate-schema-conformance
357
+ export async function collectPredicateSchemaConformanceViolations(
358
+ prolog: Pick<PrologPort, "query">,
359
+ ): Promise<Violation[]> {
360
+ const facts = await loadEntitiesPaged(prolog, "fact");
361
+ return evaluatePredicateSchemaConformance(facts);
362
+ }
@@ -55,28 +55,41 @@ export async function runOperationJsonQuery<T>(
55
55
  fileName: string,
56
56
  goal: string,
57
57
  errorLabel: string,
58
+ signal?: AbortSignal,
58
59
  ): Promise<T> {
59
60
  const modulePath = escapeAtom(
60
61
  resolveCoreModulePath(fileName).replaceAll("\\", "/"),
61
62
  );
62
63
  // Loading a module and invoking its predicate in one interactive goal makes
63
64
  // SWI reject `use_module/1` under the engine's guarded `once/1` wrapper, so
64
- // use two serialized requests for production and retain the combined goal
65
- // only for the repository's Bun-based one-shot tests.
65
+ // an interactive port gets two serialized requests. That split is only
66
+ // sound when both requests reach the same live session: the engine daemon
67
+ // guarantees it by recycling a lost session with every loaded module
68
+ // restored, and a started PrologProcess fails loudly once its session is
69
+ // lost. Any port whose queries run in isolated processes (an unstarted or
70
+ // one-shot PrologProcess reports `oneShotMode`) must receive the combined
71
+ // goal, or the module load and the predicate call land in different SWI
72
+ // processes and the call fails with an existence error.
66
73
  const longLivedEngine =
67
74
  typeof (prolog as { storageStatus?: unknown }).storageStatus === "function";
68
75
  const oneShotMode =
69
- prolog.oneShotMode === true ||
76
+ prolog.oneShotMode ??
70
77
  (!longLivedEngine &&
71
78
  process.env.NODE_ENV === "test" &&
72
79
  typeof (globalThis as { Bun?: unknown }).Bun !== "undefined");
73
80
  const typedStatusQuery = prolog.queryStatusJson;
74
81
  const result =
75
82
  fileName === "status.pl" && typeof typedStatusQuery === "function"
76
- ? await typedStatusQuery.call(prolog)
83
+ ? await typedStatusQuery.call(prolog, signal)
77
84
  : oneShotMode
78
- ? await prolog.query(`(use_module('${modulePath}'), ${goal})`)
79
- : await runInteractiveModuleQuery(prolog, modulePath, goal, errorLabel);
85
+ ? await prolog.query(`(use_module('${modulePath}'), ${goal})`, signal)
86
+ : await runInteractiveModuleQuery(
87
+ prolog,
88
+ modulePath,
89
+ goal,
90
+ errorLabel,
91
+ signal,
92
+ );
80
93
  if (!result.success) {
81
94
  throw new Error(
82
95
  `${errorLabel} query failed: ${result.error ?? "Unknown error"}`,
@@ -115,14 +128,15 @@ async function runInteractiveModuleQuery(
115
128
  modulePath: string,
116
129
  goal: string,
117
130
  errorLabel: string,
131
+ signal?: AbortSignal,
118
132
  ) {
119
- const loadResult = await prolog.query(`use_module('${modulePath}')`);
133
+ const loadResult = await prolog.query(`use_module('${modulePath}')`, signal);
120
134
  if (!loadResult.success) {
121
135
  throw new Error(
122
136
  `${errorLabel} module load failed: ${loadResult.error ?? "Unknown error"}`,
123
137
  );
124
138
  }
125
- return prolog.query(goal);
139
+ return prolog.query(goal, signal);
126
140
  }
127
141
 
128
142
  export function toPrologAtom(value?: string): string {
@@ -50,9 +50,29 @@ export function failedEffectStatus(
50
50
  };
51
51
  }
52
52
 
53
+ type EffectOutcome =
54
+ | { readonly kind: "completed" }
55
+ | { readonly kind: "failed"; readonly errorCode?: string }
56
+ | { readonly kind: "not_attempted" };
57
+
58
+ function effectOutcome(
59
+ status: KibiResult["status"],
60
+ options: {
61
+ readonly attempted?: boolean;
62
+ readonly error?: KibiResult["error"];
63
+ },
64
+ ): EffectOutcome {
65
+ if (status !== "error") return { kind: "completed" };
66
+ if (options.attempted === false) return { kind: "not_attempted" };
67
+ return options.error
68
+ ? { kind: "failed", errorCode: options.error.code }
69
+ : { kind: "failed" };
70
+ }
71
+
53
72
  function effectStatus(
54
73
  effect: OperationEffect,
55
74
  data: Record<string, unknown> | undefined,
75
+ outcome: EffectOutcome,
56
76
  ): KibiResult["effects"][number] {
57
77
  const failures = data?.effectFailures;
58
78
  if (Array.isArray(failures)) {
@@ -61,6 +81,25 @@ function effectStatus(
61
81
  );
62
82
  if (record(failure)) return failedEffectStatus(effect, failure);
63
83
  }
84
+ // A plan-only result declares the effects it left to a later call.
85
+ if (
86
+ Array.isArray(data?.skippedEffects) &&
87
+ data.skippedEffects.includes(effect)
88
+ ) {
89
+ return { kind: effect, status: "not_applicable" };
90
+ }
91
+ // An error envelope must never claim a declared effect completed: the
92
+ // operation either never ran or stopped before reporting its effects.
93
+ if (outcome.kind === "not_attempted") {
94
+ return { kind: effect, status: "not_applicable" };
95
+ }
96
+ if (outcome.kind === "failed") {
97
+ return {
98
+ kind: effect,
99
+ status: "failed",
100
+ ...(outcome.errorCode ? { errorCode: outcome.errorCode } : {}),
101
+ };
102
+ }
64
103
  return { kind: effect, status: "completed" };
65
104
  }
66
105
 
@@ -109,7 +148,14 @@ export function toKibiResult<T>(
109
148
  data: T,
110
149
  options: Partial<
111
150
  Pick<KibiResult<T>, "status" | "diagnostics" | "nextActions" | "error">
112
- > = {},
151
+ > & {
152
+ /**
153
+ * False when the operation was rejected before it ran (invalid input),
154
+ * so an error envelope reports its effects as not applicable rather than
155
+ * failed.
156
+ */
157
+ readonly attempted?: boolean;
158
+ } = {},
113
159
  ): KibiResult<T> {
114
160
  const row = record(data) ? data : undefined;
115
161
  const status =
@@ -117,6 +163,7 @@ export function toKibiResult<T>(
117
163
  (row?.status === "committed_with_repairs"
118
164
  ? "committed_with_repairs"
119
165
  : "success");
166
+ const outcome = effectOutcome(status, options);
120
167
  return {
121
168
  kibiProtocol: KIBI_PROTOCOL_VERSION,
122
169
  operation: spec.name as OperationName,
@@ -124,7 +171,7 @@ export function toKibiResult<T>(
124
171
  status,
125
172
  data,
126
173
  effects: [
127
- ...spec.effects.map((effect) => effectStatus(effect, row)),
174
+ ...spec.effects.map((effect) => effectStatus(effect, row, outcome)),
128
175
  ...extraFailedEffects(spec.effects, row),
129
176
  ],
130
177
  diagnostics: options.diagnostics ?? diagnostics(row?.diagnostics),
@@ -139,3 +186,68 @@ export function operationData(value: unknown): unknown {
139
186
  }
140
187
  return value;
141
188
  }
189
+
190
+ // implements REQ-kibi-telemetry-remediation-evidence
191
+ export interface NormalizedResultPayload {
192
+ /** The versioned KibiResult envelope, when the result carries one. */
193
+ readonly envelope?: Record<string, unknown>;
194
+ /** The operation payload that operation-specific telemetry fields read. */
195
+ readonly data?: Record<string, unknown>;
196
+ }
197
+
198
+ /**
199
+ * Resolve a tool result into its envelope and its operation payload.
200
+ *
201
+ * Callers hand results over in two shapes: MCP tool handlers pass the bare
202
+ * `toKibiResult` envelope, while some CLI and SDK routes wrap it as
203
+ * `{ structuredContent }`. Deriving telemetry from the wrong shape silently
204
+ * yields an absent payload, so both shapes resolve here instead of at each
205
+ * call site. An unresolvable payload stays `undefined` so callers can record
206
+ * the count as unknown rather than as zero.
207
+ */
208
+ export function normalizeResultPayload(
209
+ result: unknown,
210
+ ): NormalizedResultPayload {
211
+ if (!record(result)) return {};
212
+ const candidate = record(result.structuredContent)
213
+ ? result.structuredContent
214
+ : result;
215
+ if (candidate.kibiProtocol !== KIBI_PROTOCOL_VERSION) {
216
+ return { data: candidate };
217
+ }
218
+ return {
219
+ envelope: candidate,
220
+ ...(record(candidate.data) ? { data: candidate.data } : {}),
221
+ };
222
+ }
223
+
224
+ function readPayloadCount(raw: unknown): number | null {
225
+ if (typeof raw === "number") return Number.isFinite(raw) ? raw : null;
226
+ // Some transports serialize counts as strings; an absent or unparseable
227
+ // value stays null so it is never coerced to a plausible zero.
228
+ if (typeof raw === "string" && raw.trim() !== "") {
229
+ const parsed = Number(raw);
230
+ return Number.isFinite(parsed) ? parsed : null;
231
+ }
232
+ return null;
233
+ }
234
+
235
+ /**
236
+ * Record a count that could not be read as unknown rather than as zero.
237
+ *
238
+ * A missing payload and an empty result are different facts, and collapsing
239
+ * them hides retrieval failures behind a plausible "0 results" row. Both the
240
+ * MCP and CLI diagnostic loggers derive counts here so the two surfaces stay
241
+ * at parity.
242
+ */
243
+ export function appendPayloadCountField(
244
+ fields: Record<string, unknown>,
245
+ countKey: string,
246
+ noun: string,
247
+ payload: Record<string, unknown> | undefined,
248
+ ): void {
249
+ const count = readPayloadCount(payload?.count);
250
+ fields[countKey] = count;
251
+ fields.result_summary =
252
+ count === null ? `${noun} count unavailable` : `${count} ${noun}`;
253
+ }
@@ -1,8 +1,17 @@
1
+ import type { CapabilityRegistry } from "../../plugins/registry.js";
1
2
  import type { PrologErrorRecord } from "../../prolog/error-terms.js";
2
3
  import type { BranchAttachment } from "../../utils/branch-resolver.js";
3
4
  import type { OperationEffect } from "./types.js";
4
5
 
5
6
  export type { OperationEffect } from "./types.js";
7
+ // implements REQ-capability-plugin-activation-disclosure-v1
8
+ export type { CapabilityRegistry } from "../../plugins/registry.js";
9
+
10
+ /** Lazy or pre-materialized capability-plugin registry for an operation. */
11
+ // implements REQ-capability-plugin-activation-disclosure-v1
12
+ export type OperationPlugins =
13
+ | CapabilityRegistry
14
+ | (() => Promise<CapabilityRegistry>);
6
15
 
7
16
  export type PrologQueryResult = {
8
17
  readonly success: boolean;
@@ -115,7 +124,7 @@ export interface PrologPort {
115
124
  /** Present on the journaled engine; used to distinguish a persistent port from one-shot SWI. */
116
125
  storageStatus?(): Promise<PrologQueryResult>;
117
126
  /** Typed public freshness query; avoids exposing module loading over RPC. */
118
- queryStatusJson?(): Promise<PrologQueryResult>;
127
+ queryStatusJson?(signal?: AbortSignal): Promise<PrologQueryResult>;
119
128
  }
120
129
 
121
130
  export type FilesystemStat = {
@@ -175,6 +184,8 @@ export type RuntimeOptions = {
175
184
  readonly fs?: FilesystemPort;
176
185
  readonly git?: GitPort;
177
186
  readonly net?: NetworkPort;
187
+ /** Optional injectable capability registry (or lazy factory). */
188
+ readonly plugins?: OperationPlugins;
178
189
  };
179
190
 
180
191
  export type OperationContext = {
@@ -190,17 +201,25 @@ export type OperationContext = {
190
201
  readonly sourceFirst?: boolean;
191
202
  /** Internal apply-plan capability: source bytes were already approved/published. */
192
203
  readonly sourcePlanApplication?: boolean;
193
- /** Internal apply-plan capability: caller holds the cooperative source lock. */
204
+ /** Internal operation capability: a parent operation holds the source lock. */
194
205
  readonly sourceMutationLockHeld?: boolean;
195
206
  readonly git?: GitPort;
196
207
  readonly net?: NetworkPort;
197
208
  readonly branchAttachment?: BranchAttachment;
209
+ /** Pre-materialized or lazy capability registry supplied by the host runtime. */
210
+ readonly plugins?: OperationPlugins;
211
+ /** Lazily materialize the workspace capability registry. */
212
+ readonly ensurePlugins?: () => Promise<CapabilityRegistry>;
198
213
  };
199
-
200
214
  export interface RuntimeOperationSpec<TInput = unknown, TResult = unknown> {
201
215
  readonly name: string;
202
216
  readonly effects: readonly OperationEffect[];
203
217
  readonly requiresProlog: boolean;
218
+ /**
219
+ * When true, MCP embeds envelope `data` JSON in tool `content` for hosts that
220
+ * hide `structuredContent` (discovery/proof lookup). Default false.
221
+ */
222
+ readonly agentVisibleStructuredData?: boolean;
204
223
  execute(input: TInput, context: OperationContext): Promise<TResult>;
205
224
  }
206
225
 
@@ -29,9 +29,17 @@ export const SELECTABLE_RULE_NAMES: readonly string[] = [
29
29
  "predicate-verifiability",
30
30
  "strict-readiness",
31
31
  "semantic-completeness",
32
+ "proof-contract-symbols",
33
+ "entity-id-style",
34
+ "domain-redundancy",
35
+ "domain-implication",
36
+ "subject-key-identity",
37
+ "subject-key-shape",
38
+ "ontology-quality",
39
+ "predicate-schema-conformance",
32
40
  ];
33
41
 
34
42
  // implements REQ-006
35
43
  /** Comma-separated "Allowed:" fragment for the kb_check rules description. */
36
44
  export const SELECTABLE_RULES_ALLOWED =
37
- "must-priority-coverage, symbol-coverage, symbol-traceability, no-dangling-refs, source-relationship-parity, no-cycles, required-fields, deprecated-adr-no-successor, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness";
45
+ "must-priority-coverage, symbol-coverage, symbol-traceability, no-dangling-refs, source-relationship-parity, no-cycles, required-fields, deprecated-adr-no-successor, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, predicate-schema-conformance";