kibi-cli 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/dist/cli-operation-loader.d.ts.map +1 -1
  2. package/dist/cli-operation-loader.js +3 -0
  3. package/dist/cli-operation-metadata.d.ts +4 -0
  4. package/dist/cli-operation-metadata.d.ts.map +1 -1
  5. package/dist/cli-operation-metadata.js +5 -0
  6. package/dist/cli-protocol.d.ts.map +1 -1
  7. package/dist/cli-protocol.js +3 -2
  8. package/dist/cli-register-reporting.d.ts.map +1 -1
  9. package/dist/cli-register-reporting.js +4 -0
  10. package/dist/commands/aggregated-checks.d.ts +7 -0
  11. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  12. package/dist/commands/aggregated-checks.js +25 -1
  13. package/dist/commands/check-diff.d.ts +5 -0
  14. package/dist/commands/check-diff.d.ts.map +1 -0
  15. package/dist/commands/check-diff.js +62 -0
  16. package/dist/commands/check-generated.d.ts.map +1 -1
  17. package/dist/commands/check-generated.js +41 -18
  18. package/dist/commands/check.d.ts.map +1 -1
  19. package/dist/commands/check.js +231 -86
  20. package/dist/commands/doctor.d.ts.map +1 -1
  21. package/dist/commands/doctor.js +168 -53
  22. package/dist/commands/github-init.d.ts +1 -1
  23. package/dist/commands/github-init.d.ts.map +1 -1
  24. package/dist/commands/github-init.js +10 -3
  25. package/dist/commands/init-helpers.d.ts +17 -2
  26. package/dist/commands/init-helpers.d.ts.map +1 -1
  27. package/dist/commands/init-helpers.js +123 -23
  28. package/dist/commands/init.d.ts.map +1 -1
  29. package/dist/commands/init.js +110 -15
  30. package/dist/commands/prove.d.ts.map +1 -1
  31. package/dist/commands/prove.js +10 -18
  32. package/dist/commands/sync/cache.d.ts +20 -1
  33. package/dist/commands/sync/cache.d.ts.map +1 -1
  34. package/dist/commands/sync/cache.js +51 -2
  35. package/dist/commands/sync/discovery.d.ts.map +1 -1
  36. package/dist/commands/sync/discovery.js +1 -1
  37. package/dist/commands/sync/manifest.d.ts.map +1 -1
  38. package/dist/commands/sync/manifest.js +3 -1
  39. package/dist/commands/sync/persistence.d.ts.map +1 -1
  40. package/dist/commands/sync/persistence.js +8 -0
  41. package/dist/commands/sync.d.ts.map +1 -1
  42. package/dist/commands/sync.js +11 -3
  43. package/dist/engine.d.ts +41 -1
  44. package/dist/engine.d.ts.map +1 -1
  45. package/dist/engine.js +377 -80
  46. package/dist/extractors/manifest.d.ts.map +1 -1
  47. package/dist/extractors/manifest.js +66 -28
  48. package/dist/extractors/markdown.d.ts +2 -0
  49. package/dist/extractors/markdown.d.ts.map +1 -1
  50. package/dist/extractors/markdown.js +14 -3
  51. package/dist/extractors/relationships.d.ts.map +1 -1
  52. package/dist/extractors/relationships.js +1 -0
  53. package/dist/extractors/symbols-coordinator.d.ts +7 -0
  54. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  55. package/dist/extractors/symbols-coordinator.js +75 -39
  56. package/dist/intent-search.d.ts.map +1 -1
  57. package/dist/intent-search.js +68 -29
  58. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  59. package/dist/operations/bootstrap/generate.js +4 -3
  60. package/dist/operations/modeling/model-requirement.d.ts +1 -1
  61. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  62. package/dist/operations/modeling/model-requirement.js +176 -10
  63. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  64. package/dist/operations/modeling/predicate-applyplan.js +14 -2
  65. package/dist/operations/modeling/predicate-inference-1.js +1 -1
  66. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  67. package/dist/operations/modeling/predicate-loader.js +24 -0
  68. package/dist/operations/modeling/predicate-types.d.ts +4 -0
  69. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  70. package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
  71. package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
  72. package/dist/operations/modeling/predicate-vocabulary.js +169 -0
  73. package/dist/operations/modeling/requirement-types.d.ts +5 -0
  74. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  75. package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
  76. package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
  77. package/dist/operations/modeling/vocabulary-alignment.js +178 -0
  78. package/dist/operations/mutation/contradictions.d.ts +3 -0
  79. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  80. package/dist/operations/mutation/contradictions.js +29 -0
  81. package/dist/operations/mutation/delete.d.ts.map +1 -1
  82. package/dist/operations/mutation/delete.js +33 -1
  83. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
  84. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
  85. package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
  86. package/dist/operations/mutation/relationships.d.ts +1 -1
  87. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  88. package/dist/operations/mutation/relationships.js +1 -0
  89. package/dist/operations/mutation/saga.d.ts +5 -0
  90. package/dist/operations/mutation/saga.d.ts.map +1 -1
  91. package/dist/operations/mutation/saga.js +10 -0
  92. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  93. package/dist/operations/mutation/serialization.js +2 -0
  94. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  95. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  96. package/dist/operations/mutation/source-authoring.js +213 -52
  97. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  98. package/dist/operations/mutation/strict-fact.js +5 -0
  99. package/dist/operations/mutation/types.d.ts +17 -0
  100. package/dist/operations/mutation/types.d.ts.map +1 -1
  101. package/dist/operations/mutation/upsert.d.ts +6 -0
  102. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  103. package/dist/operations/mutation/upsert.js +77 -11
  104. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  105. package/dist/operations/mutation/validate-upsert.js +24 -1
  106. package/dist/operations/mutation/validation.d.ts.map +1 -1
  107. package/dist/operations/mutation/validation.js +16 -3
  108. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  109. package/dist/operations/planning/apply-plan.js +66 -26
  110. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  111. package/dist/operations/planning/compile-intent.js +3 -1
  112. package/dist/operations/proof/code-scope.d.ts +17 -0
  113. package/dist/operations/proof/code-scope.d.ts.map +1 -0
  114. package/dist/operations/proof/code-scope.js +60 -0
  115. package/dist/operations/proof/ingest-proof.d.ts +4 -2
  116. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  117. package/dist/operations/proof/ingest-proof.js +208 -74
  118. package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
  119. package/dist/operations/proof/migrate-legacy-receipts.js +7 -5
  120. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  121. package/dist/operations/proof/prune-receipts.js +7 -5
  122. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  123. package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
  124. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  125. package/dist/operations/semantic-advisor/analyze-prose.js +26 -4
  126. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  127. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  128. package/dist/operations/semantic-advisor/clauses.js +7 -1
  129. package/dist/performance-trace.d.ts +17 -0
  130. package/dist/performance-trace.d.ts.map +1 -0
  131. package/dist/performance-trace.js +134 -0
  132. package/dist/plugins/approved-source-analyzers.d.ts +13 -0
  133. package/dist/plugins/approved-source-analyzers.d.ts.map +1 -0
  134. package/dist/plugins/approved-source-analyzers.generated.d.ts +71 -0
  135. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -0
  136. package/dist/plugins/approved-source-analyzers.generated.js +77 -0
  137. package/dist/plugins/approved-source-analyzers.js +3 -0
  138. package/dist/plugins/compose-semantic-classifier.d.ts +6 -1
  139. package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -1
  140. package/dist/plugins/compose-semantic-classifier.js +8 -3
  141. package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
  142. package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
  143. package/dist/plugins/compose-vocabulary-alignment.js +141 -0
  144. package/dist/plugins/external-allowlist.d.ts +7 -0
  145. package/dist/plugins/external-allowlist.d.ts.map +1 -1
  146. package/dist/plugins/external-allowlist.js +13 -0
  147. package/dist/plugins/index.d.ts +2 -0
  148. package/dist/plugins/index.d.ts.map +1 -1
  149. package/dist/plugins/index.js +4 -0
  150. package/dist/plugins/maintenance-source-analysis.d.ts +14 -0
  151. package/dist/plugins/maintenance-source-analysis.d.ts.map +1 -0
  152. package/dist/plugins/maintenance-source-analysis.js +191 -0
  153. package/dist/plugins/registry.d.ts +3 -1
  154. package/dist/plugins/registry.d.ts.map +1 -1
  155. package/dist/plugins/registry.js +27 -1
  156. package/dist/plugins/source-analysis-service.d.ts +36 -1
  157. package/dist/plugins/source-analysis-service.d.ts.map +1 -1
  158. package/dist/plugins/source-analysis-service.js +184 -27
  159. package/dist/plugins/source-change-analysis.d.ts +15 -0
  160. package/dist/plugins/source-change-analysis.d.ts.map +1 -0
  161. package/dist/plugins/source-change-analysis.js +54 -0
  162. package/dist/plugins/source-classification.d.ts +41 -0
  163. package/dist/plugins/source-classification.d.ts.map +1 -0
  164. package/dist/plugins/source-classification.js +490 -0
  165. package/dist/prolog/codec.d.ts.map +1 -1
  166. package/dist/prolog/codec.js +2 -0
  167. package/dist/prolog/swipl-resolver.d.ts +88 -0
  168. package/dist/prolog/swipl-resolver.d.ts.map +1 -0
  169. package/dist/prolog/swipl-resolver.js +446 -0
  170. package/dist/prolog.d.ts +51 -1
  171. package/dist/prolog.d.ts.map +1 -1
  172. package/dist/prolog.js +145 -15
  173. package/dist/public/diagnostic-usage.d.ts.map +1 -1
  174. package/dist/public/diagnostic-usage.js +7 -25
  175. package/dist/public/impact/analyzer.d.ts.map +1 -1
  176. package/dist/public/impact/analyzer.js +56 -5
  177. package/dist/public/impact/diagnostics.d.ts.map +1 -1
  178. package/dist/public/impact/diagnostics.js +3 -1
  179. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  180. package/dist/public/impact/full-kb-quality.js +4 -12
  181. package/dist/public/impact/manifest.d.ts.map +1 -1
  182. package/dist/public/impact/manifest.js +15 -1
  183. package/dist/public/impact/source-changes.d.ts.map +1 -1
  184. package/dist/public/impact/source-changes.js +35 -27
  185. package/dist/public/impact/types.d.ts +2 -0
  186. package/dist/public/impact/types.d.ts.map +1 -1
  187. package/dist/public/operations/catalog.d.ts +80 -7
  188. package/dist/public/operations/catalog.d.ts.map +1 -1
  189. package/dist/public/operations/catalog.js +2 -0
  190. package/dist/public/operations/check-executor.d.ts.map +1 -1
  191. package/dist/public/operations/check-executor.js +10 -2
  192. package/dist/public/operations/check-helpers.d.ts +6 -0
  193. package/dist/public/operations/check-helpers.d.ts.map +1 -1
  194. package/dist/public/operations/check-helpers.js +21 -1
  195. package/dist/public/operations/contracts.d.ts.map +1 -1
  196. package/dist/public/operations/contracts.js +325 -8
  197. package/dist/public/operations/discovery-entities.d.ts +42 -2
  198. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  199. package/dist/public/operations/discovery-entities.js +195 -22
  200. package/dist/public/operations/discovery-executors.d.ts +1 -0
  201. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  202. package/dist/public/operations/discovery-executors.js +75 -46
  203. package/dist/public/operations/impact-review-preparation.d.ts +14 -0
  204. package/dist/public/operations/impact-review-preparation.d.ts.map +1 -0
  205. package/dist/public/operations/impact-review-preparation.js +379 -0
  206. package/dist/public/operations/index.d.ts +2 -0
  207. package/dist/public/operations/index.d.ts.map +1 -1
  208. package/dist/public/operations/index.js +2 -0
  209. package/dist/public/operations/migration-plan.d.ts +2 -0
  210. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  211. package/dist/public/operations/migration-plan.js +50 -0
  212. package/dist/public/operations/node-ports.d.ts.map +1 -1
  213. package/dist/public/operations/node-ports.js +1 -35
  214. package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
  215. package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
  216. package/dist/public/operations/predicate-schema-conformance.js +242 -0
  217. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  218. package/dist/public/operations/prolog-json.js +9 -3
  219. package/dist/public/operations/proof-receipt-projection.d.ts +5 -0
  220. package/dist/public/operations/proof-receipt-projection.d.ts.map +1 -0
  221. package/dist/public/operations/proof-receipt-projection.js +36 -0
  222. package/dist/public/operations/result-envelope.d.ts +34 -1
  223. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  224. package/dist/public/operations/result-envelope.js +78 -2
  225. package/dist/public/operations/runtime-types.d.ts +1 -1
  226. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  227. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  228. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  229. package/dist/public/operations/specs/check-rules.generated.js +8 -1
  230. package/dist/public/operations/specs/check.d.ts +1 -1
  231. package/dist/public/operations/specs/discovery.d.ts +7 -1
  232. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  233. package/dist/public/operations/specs/discovery.js +7 -1
  234. package/dist/public/operations/specs/impact-review-preparation.d.ts +47 -0
  235. package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -0
  236. package/dist/public/operations/specs/impact-review-preparation.js +43 -0
  237. package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
  238. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  239. package/dist/public/operations/specs/mutation-schemas.js +21 -3
  240. package/dist/public/operations/specs/reporting.d.ts +8 -0
  241. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  242. package/dist/public/operations/specs/reporting.js +46 -15
  243. package/dist/public/operations/specs/upsert.d.ts +28 -5
  244. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  245. package/dist/public/operations/specs/upsert.js +1 -1
  246. package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
  247. package/dist/public/operations/symbol-repair-plan.js +8 -3
  248. package/dist/public/operations/types.d.ts +1 -1
  249. package/dist/public/operations/types.d.ts.map +1 -1
  250. package/dist/public/schemas/entity.d.ts.map +1 -1
  251. package/dist/public/schemas/entity.js +22 -0
  252. package/dist/public/schemas/relationship.d.ts.map +1 -1
  253. package/dist/public/schemas/relationship.js +1 -0
  254. package/dist/public/skills/kibi-usage/SKILL.md +7 -3
  255. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  256. package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -0
  257. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  258. package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  259. package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
  260. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  261. package/dist/public/telemetry-acceptance.js +21 -5
  262. package/dist/relationships/shards.d.ts +6 -0
  263. package/dist/relationships/shards.d.ts.map +1 -1
  264. package/dist/relationships/shards.js +26 -19
  265. package/dist/schemas/entity.schema.json +32 -0
  266. package/dist/traceability/analysis-gate.d.ts +39 -0
  267. package/dist/traceability/analysis-gate.d.ts.map +1 -0
  268. package/dist/traceability/analysis-gate.js +51 -0
  269. package/dist/traceability/git-change-snapshot.d.ts +27 -0
  270. package/dist/traceability/git-change-snapshot.d.ts.map +1 -0
  271. package/dist/traceability/git-change-snapshot.js +411 -0
  272. package/dist/traceability/git-staged.d.ts +5 -1
  273. package/dist/traceability/git-staged.d.ts.map +1 -1
  274. package/dist/traceability/git-staged.js +16 -11
  275. package/dist/traceability/impact-evaluator.d.ts +54 -0
  276. package/dist/traceability/impact-evaluator.d.ts.map +1 -0
  277. package/dist/traceability/impact-evaluator.js +270 -0
  278. package/dist/traceability/impact-git-tree.d.ts +12 -0
  279. package/dist/traceability/impact-git-tree.d.ts.map +1 -0
  280. package/dist/traceability/impact-git-tree.js +46 -0
  281. package/dist/traceability/impact-knowledge.d.ts +16 -0
  282. package/dist/traceability/impact-knowledge.d.ts.map +1 -0
  283. package/dist/traceability/impact-knowledge.js +165 -0
  284. package/dist/traceability/impact-policy.d.ts +15 -0
  285. package/dist/traceability/impact-policy.d.ts.map +1 -0
  286. package/dist/traceability/impact-policy.js +48 -0
  287. package/dist/traceability/impact-policy.v1.schema.json +48 -0
  288. package/dist/traceability/impact-pr-diff.d.ts +5 -0
  289. package/dist/traceability/impact-pr-diff.d.ts.map +1 -0
  290. package/dist/traceability/impact-pr-diff.js +83 -0
  291. package/dist/traceability/impact-record-validation.d.ts +9 -0
  292. package/dist/traceability/impact-record-validation.d.ts.map +1 -0
  293. package/dist/traceability/impact-record-validation.js +113 -0
  294. package/dist/traceability/impact-review.d.ts +148 -0
  295. package/dist/traceability/impact-review.d.ts.map +1 -0
  296. package/dist/traceability/impact-review.js +494 -0
  297. package/dist/traceability/impact-review.schema.json +365 -0
  298. package/dist/traceability/impact-side-evidence.d.ts +13 -0
  299. package/dist/traceability/impact-side-evidence.d.ts.map +1 -0
  300. package/dist/traceability/impact-side-evidence.js +240 -0
  301. package/dist/traceability/reviewed-coordinate-refresh.d.ts +10 -0
  302. package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +1 -0
  303. package/dist/traceability/reviewed-coordinate-refresh.js +49 -0
  304. package/dist/traceability/snapshot-knowledge.d.ts +4 -0
  305. package/dist/traceability/snapshot-knowledge.d.ts.map +1 -0
  306. package/dist/traceability/snapshot-knowledge.js +98 -0
  307. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  308. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  309. package/dist/traceability/staged-entity-id-style.d.ts +12 -0
  310. package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
  311. package/dist/traceability/staged-entity-id-style.js +68 -0
  312. package/dist/traceability/staged-file-coverage.d.ts +23 -0
  313. package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
  314. package/dist/traceability/staged-impact-contract.d.ts.map +1 -1
  315. package/dist/traceability/staged-impact-contract.js +2 -16
  316. package/dist/traceability/staged-symbols-manifest.d.ts +4 -0
  317. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  318. package/dist/traceability/staged-symbols-manifest.js +17 -6
  319. package/dist/traceability/symbol-extract.d.ts +3 -5
  320. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  321. package/dist/traceability/symbol-extract.js +49 -34
  322. package/dist/traceability/temp-kb.d.ts +1 -1
  323. package/dist/traceability/temp-kb.d.ts.map +1 -1
  324. package/dist/traceability/temp-kb.js +57 -13
  325. package/dist/traceability/trusted-pr-event.d.ts +13 -0
  326. package/dist/traceability/trusted-pr-event.d.ts.map +1 -0
  327. package/dist/traceability/trusted-pr-event.js +105 -0
  328. package/dist/traceability/validate.js +1 -1
  329. package/dist/types/entities.d.ts +2 -0
  330. package/dist/types/entities.d.ts.map +1 -1
  331. package/dist/types/relationships.d.ts +1 -1
  332. package/dist/types/relationships.d.ts.map +1 -1
  333. package/dist/utils/canonical-path.d.ts +3 -0
  334. package/dist/utils/canonical-path.d.ts.map +1 -0
  335. package/dist/utils/canonical-path.js +33 -0
  336. package/dist/utils/entity-id-style.d.ts +27 -0
  337. package/dist/utils/entity-id-style.d.ts.map +1 -0
  338. package/dist/utils/entity-id-style.js +81 -0
  339. package/dist/utils/git-repository-context.d.ts +50 -0
  340. package/dist/utils/git-repository-context.d.ts.map +1 -0
  341. package/dist/utils/git-repository-context.js +259 -0
  342. package/dist/utils/rule-registry.d.ts +5 -0
  343. package/dist/utils/rule-registry.d.ts.map +1 -1
  344. package/dist/utils/rule-registry.generated.d.ts +37 -0
  345. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  346. package/dist/utils/rule-registry.generated.js +44 -0
  347. package/dist/utils/strict-modeling.d.ts +7 -0
  348. package/dist/utils/strict-modeling.d.ts.map +1 -1
  349. package/dist/utils/strict-modeling.js +11 -0
  350. package/package.json +14 -5
  351. package/schema/entities.pl +60 -1
  352. package/schema/relationships.pl +17 -4
  353. package/schema/validation.pl +118 -20
  354. package/src/public/diagnostic-usage.ts +16 -24
  355. package/src/public/impact/analyzer.ts +88 -5
  356. package/src/public/impact/diagnostics.ts +7 -5
  357. package/src/public/impact/full-kb-quality.ts +4 -16
  358. package/src/public/impact/manifest.ts +14 -1
  359. package/src/public/impact/source-changes.ts +39 -34
  360. package/src/public/impact/types.ts +5 -0
  361. package/src/public/operations/catalog.ts +2 -0
  362. package/src/public/operations/check-executor.ts +12 -1
  363. package/src/public/operations/check-helpers.ts +27 -1
  364. package/src/public/operations/contracts.ts +404 -9
  365. package/src/public/operations/discovery-entities.ts +292 -23
  366. package/src/public/operations/discovery-executors.ts +91 -55
  367. package/src/public/operations/impact-review-preparation.ts +548 -0
  368. package/src/public/operations/index.ts +2 -0
  369. package/src/public/operations/migration-plan.ts +57 -0
  370. package/src/public/operations/node-ports.ts +1 -39
  371. package/src/public/operations/predicate-schema-conformance.ts +362 -0
  372. package/src/public/operations/prolog-json.ts +9 -3
  373. package/src/public/operations/proof-receipt-projection.ts +39 -0
  374. package/src/public/operations/result-envelope.ts +114 -2
  375. package/src/public/operations/runtime-types.ts +1 -1
  376. package/src/public/operations/specs/check-rules.generated.ts +8 -1
  377. package/src/public/operations/specs/discovery.ts +8 -1
  378. package/src/public/operations/specs/impact-review-preparation.ts +46 -0
  379. package/src/public/operations/specs/mutation-schemas.ts +23 -3
  380. package/src/public/operations/specs/reporting.ts +69 -22
  381. package/src/public/operations/specs/upsert.ts +1 -1
  382. package/src/public/operations/symbol-repair-plan.ts +13 -3
  383. package/src/public/operations/types.ts +1 -0
  384. package/src/public/schemas/entity.ts +22 -0
  385. package/src/public/schemas/relationship.ts +1 -0
  386. package/src/public/skills/kibi-usage/SKILL.md +7 -3
  387. package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  388. package/src/public/skills/kibi-usage/resources/operation-access.md +1 -0
  389. package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  390. package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  391. package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
  392. package/src/public/telemetry-acceptance.ts +37 -6
  393. package/src/schemas/entity.schema.json +32 -0
  394. package/src/schemas/relationship.schema.json +1 -0
  395. package/src/traceability/impact-policy.v1.schema.json +48 -0
  396. package/src/traceability/impact-review.schema.json +365 -0
  397. package/templates/github/kibi-badge.yml +0 -4
  398. package/templates/github/kibi-report.yml +0 -4
@@ -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()));
@@ -125,34 +199,98 @@ export function paginateResults<T>(
125
199
  // implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
126
200
  export const SEARCH_CANDIDATE_PAGE_SIZE = 500;
127
201
 
202
+ function isPrologOutputOverflow(error: unknown): boolean {
203
+ return error instanceof Error && error.message.includes("ENOBUFS");
204
+ }
205
+
128
206
  // implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
129
207
  export async function loadSearchCandidates(
130
- prolog: Pick<PrologPort, "searchEntities">,
208
+ prolog: Pick<PrologPort, "searchEntities"> &
209
+ Partial<Pick<PrologPort, "query">>,
131
210
  input: {
132
211
  readonly query: string;
133
212
  readonly type?: string;
134
213
  readonly maxCandidates?: number;
135
214
  },
136
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
+ },
137
267
  ): Promise<Record<string, unknown>[]> {
138
268
  const maxCandidates = input.maxCandidates ?? Number.POSITIVE_INFINITY;
139
269
  const candidates: Record<string, unknown>[] = [];
140
270
  let offset = 0;
141
271
  let total = Number.POSITIVE_INFINITY;
272
+ let pageSize = SEARCH_CANDIDATE_PAGE_SIZE;
142
273
  while (offset < total && candidates.length < maxCandidates) {
143
- // Call through the port property, never via a detached local: EngineClient
144
- // searchEntities depends on `this` (this.command), and the PrologPort
145
- // contract does not promise a pre-bound method.
146
- const page = await prolog.searchEntities?.(
147
- {
274
+ let page: PrologSearchQueryResult;
275
+ try {
276
+ page = await readPage({
148
277
  query: input.query,
149
278
  ...(input.type !== undefined ? { type: input.type } : {}),
150
- limit: SEARCH_CANDIDATE_PAGE_SIZE,
279
+ limit: pageSize,
151
280
  offset,
152
- },
153
- signal,
154
- );
155
- if (!page || page.entities.length === 0) break;
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;
156
294
  candidates.push(...page.entities);
157
295
  total = page.count;
158
296
  offset += page.entities.length;
@@ -162,6 +300,137 @@ export async function loadSearchCandidates(
162
300
  : candidates;
163
301
  }
164
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
+
165
434
  // implements REQ-002
166
435
  export function dedupeEntities(
167
436
  entities: readonly Record<string, unknown>[],
@@ -1,3 +1,4 @@
1
+ import { compilerFingerprintReason } from "../../commands/sync/cache.js";
1
2
  import { EngineClient } from "../../engine.js";
2
3
  import {
3
4
  type IntentSearchAnalysis,
@@ -21,6 +22,8 @@ import {
21
22
  loadEntities,
22
23
  loadSearchCandidates,
23
24
  paginateResults,
25
+ queryEntitiesViaQuery,
26
+ reloadFullEntities,
24
27
  validateEntityType,
25
28
  } from "./discovery-entities.js";
26
29
  import {
@@ -60,6 +63,7 @@ export type SearchInput = {
60
63
  readonly semanticFacets?: IntentSearchFacets;
61
64
  readonly sourceLocations?: readonly SourceLocation[];
62
65
  readonly minScore?: number;
66
+ readonly fields?: "summary" | "full";
63
67
  };
64
68
 
65
69
  export type SearchPayload = {
@@ -140,51 +144,29 @@ export async function executeQuery(
140
144
  // implements REQ-kibi-operation-interface-parity
141
145
  const { type, id, tags, sourceFile, limit = 100, offset = 0 } = input;
142
146
  try {
147
+ validateEntityType(type);
143
148
  const prolog = requireProlog(context);
144
149
  const signal = context.signal;
145
- const indexedPage = prolog.queryEntities
146
- ? await prolog.queryEntities(
147
- {
148
- ...(type !== undefined ? { type } : {}),
149
- ...(id !== undefined ? { id } : {}),
150
- ...(tags !== undefined ? { tags } : {}),
151
- ...(sourceFile !== undefined ? { sourceFile } : {}),
152
- limit,
153
- offset,
154
- },
155
- signal,
156
- )
157
- : null;
158
- if (indexedPage !== null) {
159
- const paginated = indexedPage.entities;
160
- const text =
161
- indexedPage.count === 0
162
- ? `No entities found${type ? ` of type '${type}'` : ""}.`
163
- : `Found ${indexedPage.count} entities${type ? ` of type '${type}'` : ""}. Showing ${paginated.length} (offset ${offset}, limit ${limit}): ${paginated
164
- .map((entity) => {
165
- const entityId = String(entity.id ?? "").replace(
166
- /^file:\/\/.*\//,
167
- "",
168
- );
169
- return `${entityId} (${String(entity.title ?? "")}, status=${String(entity.status ?? "")})`;
170
- })
171
- .join(", ")}`;
172
- return {
173
- content: [{ type: "text", text }],
174
- structuredContent: { entities: paginated, count: indexedPage.count },
175
- };
176
- }
177
- const entities = await loadEntities(requireProlog(context), {
150
+ const pageInput = {
178
151
  ...(type !== undefined ? { type } : {}),
179
152
  ...(id !== undefined ? { id } : {}),
180
153
  ...(tags !== undefined ? { tags } : {}),
181
154
  ...(sourceFile !== undefined ? { sourceFile } : {}),
182
- });
183
- const paginated = paginateResults(entities, limit, offset);
155
+ limit,
156
+ offset,
157
+ };
158
+ // Both paths return one bounded page plus the total count. Ports without
159
+ // the engine method page kb_query_entities through `query` instead of
160
+ // materializing every matching entity (receipt histories make an
161
+ // all-tests answer exceed the bounded engine output).
162
+ const indexedPage = prolog.queryEntities
163
+ ? await prolog.queryEntities(pageInput, signal)
164
+ : await queryEntitiesViaQuery(prolog, pageInput, signal);
165
+ const paginated = indexedPage.entities;
184
166
  const text =
185
- entities.length === 0
167
+ indexedPage.count === 0
186
168
  ? `No entities found${type ? ` of type '${type}'` : ""}.`
187
- : `Found ${entities.length} entities${type ? ` of type '${type}'` : ""}. Showing ${paginated.length} (offset ${offset}, limit ${limit}): ${paginated
169
+ : `Found ${indexedPage.count} entities${type ? ` of type '${type}'` : ""}. Showing ${paginated.length} (offset ${offset}, limit ${limit}): ${paginated
188
170
  .map((entity) => {
189
171
  const entityId = String(entity.id ?? "").replace(
190
172
  /^file:\/\/.*\//,
@@ -195,7 +177,7 @@ export async function executeQuery(
195
177
  .join(", ")}`;
196
178
  return {
197
179
  content: [{ type: "text", text }],
198
- structuredContent: { entities: paginated, count: entities.length },
180
+ structuredContent: { entities: paginated, count: indexedPage.count },
199
181
  };
200
182
  } catch (error) {
201
183
  const message = error instanceof Error ? error.message : String(error);
@@ -203,6 +185,55 @@ export async function executeQuery(
203
185
  }
204
186
  }
205
187
 
188
+ /**
189
+ * Identifying metadata a caller needs to decide which hits to open.
190
+ *
191
+ * Search is a discovery step, so returning complete entity bodies for every
192
+ * hit spends a large share of an agent's context before it has chosen
193
+ * anything. Full bodies stay available through `fields: "full"` or a follow-up
194
+ * kb_query for the exact ids.
195
+ */
196
+ const SUMMARY_ENTITY_FIELDS = [
197
+ "id",
198
+ "type",
199
+ "title",
200
+ "status",
201
+ "priority",
202
+ "tags",
203
+ "source",
204
+ "sourceFile",
205
+ "updated_at",
206
+ ] as const;
207
+
208
+ function summarizeMatch<TMatch extends { readonly entity: unknown }>(
209
+ match: TMatch,
210
+ ): TMatch {
211
+ const entity = match.entity;
212
+ if (entity === null || typeof entity !== "object" || Array.isArray(entity)) {
213
+ return match;
214
+ }
215
+ const row = entity as Record<string, unknown>;
216
+ const summary: Record<string, unknown> = {};
217
+ for (const field of SUMMARY_ENTITY_FIELDS) {
218
+ if (row[field] !== undefined) summary[field] = row[field];
219
+ }
220
+ return { ...match, entity: summary };
221
+ }
222
+
223
+ // Candidates are projected rows, so `fields: "full"` reloads the final page's
224
+ // complete entities by id (one bounded query each).
225
+ async function projectMatches<
226
+ TMatch extends { readonly entity: Record<string, unknown> },
227
+ >(
228
+ prolog: Pick<PrologPort, "query">,
229
+ matches: readonly TMatch[],
230
+ fields: SearchInput["fields"],
231
+ ): Promise<readonly TMatch[]> {
232
+ return fields === "full"
233
+ ? reloadFullEntities(prolog, matches)
234
+ : matches.map(summarizeMatch);
235
+ }
236
+
206
237
  export async function executeSearch(
207
238
  input: SearchInput,
208
239
  context: OperationContext,
@@ -217,6 +248,7 @@ export async function executeSearch(
217
248
  semanticFacets,
218
249
  sourceLocations,
219
250
  minScore,
251
+ fields = "summary",
220
252
  } = input;
221
253
  const trimmedQuery = query.trim();
222
254
  if (!trimmedQuery) {
@@ -258,27 +290,23 @@ export async function executeSearch(
258
290
  return {
259
291
  content: [{ type: "text", text }],
260
292
  structuredContent: {
261
- results: paginated,
293
+ results: await projectMatches(prolog, paginated, fields),
262
294
  count: intentResult.matches.length,
263
295
  queryAnalysis: intentResult.analysis,
264
296
  },
265
297
  };
266
298
  }
267
- const indexedCandidates = prolog.searchEntities
268
- ? await loadSearchCandidates(
269
- prolog,
270
- {
271
- query: trimmedQuery,
272
- ...(type !== undefined ? { type } : {}),
273
- },
274
- context.signal,
275
- )
276
- : null;
277
- const entities = indexedCandidates
278
- ? [...indexedCandidates]
279
- : await loadEntities(prolog, {
280
- ...(type !== undefined ? { type } : {}),
281
- });
299
+ // Candidates are projected rows (no receipt histories or other large
300
+ // structured properties); ports without the engine method run the same
301
+ // bounded Prolog search through `query`.
302
+ const entities = await loadSearchCandidates(
303
+ prolog,
304
+ {
305
+ query: trimmedQuery,
306
+ ...(type !== undefined ? { type } : {}),
307
+ },
308
+ context.signal,
309
+ );
282
310
  const matches = await rankEntities(
283
311
  entities,
284
312
  trimmedQuery,
@@ -296,7 +324,10 @@ export async function executeSearch(
296
324
  .join(", ")}`;
297
325
  return {
298
326
  content: [{ type: "text", text }],
299
- structuredContent: { results: paginated, count: matches.length },
327
+ structuredContent: {
328
+ results: await projectMatches(prolog, paginated, fields),
329
+ count: matches.length,
330
+ },
300
331
  };
301
332
  } catch (error) {
302
333
  const message = error instanceof Error ? error.message : String(error);
@@ -400,6 +431,7 @@ export async function executeStatus(
400
431
  const existingReasons = payload.staleReasons ?? [];
401
432
  const storeReason = branchStoreReason(store);
402
433
  const lockReason = storeLockJournalReason(store.path);
434
+ const compilerReason = compilerFingerprintReason(store.path);
403
435
  const engineReason = engineStatus
404
436
  ? {
405
437
  code: engineStatus.errorCode ?? "engine_status_unavailable",
@@ -418,12 +450,16 @@ export async function executeStatus(
418
450
  ...existingReasons,
419
451
  ...(storeReason ? [storeReason] : []),
420
452
  ...(lockReason ? [lockReason] : []),
453
+ ...(compilerReason ? [compilerReason] : []),
421
454
  ...(engineReason ? [engineReason] : []),
422
455
  ].sort((left, right) =>
423
456
  String(left.path ?? "").localeCompare(String(right.path ?? "")),
424
457
  );
425
458
  const enrichedPayload: StatusPayload = {
426
459
  ...payload,
460
+ // Source hashes can all match while the compilation itself is lossy, so
461
+ // a compiler contract change alone makes the store stale.
462
+ ...(compilerReason ? { syncState: "stale", dirty: true } : {}),
427
463
  branchAttachment: attachment,
428
464
  branchStore: store,
429
465
  ...(engineStatus ? { engineStatus } : {}),