kibi-cli 2.4.0 → 2.5.1

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 (354) hide show
  1. package/dist/cli-json-command.d.ts +6 -0
  2. package/dist/cli-json-command.d.ts.map +1 -1
  3. package/dist/cli-json-command.js +37 -9
  4. package/dist/cli-operation-loader.d.ts.map +1 -1
  5. package/dist/cli-operation-loader.js +7 -0
  6. package/dist/cli-operation-metadata.d.ts +12 -4
  7. package/dist/cli-operation-metadata.d.ts.map +1 -1
  8. package/dist/cli-operation-metadata.js +14 -4
  9. package/dist/cli-protocol.d.ts +14 -0
  10. package/dist/cli-protocol.d.ts.map +1 -1
  11. package/dist/cli-protocol.js +31 -2
  12. package/dist/cli-register-proof.d.ts.map +1 -1
  13. package/dist/cli-register-proof.js +13 -0
  14. package/dist/commands/check.d.ts.map +1 -1
  15. package/dist/commands/check.js +11 -2
  16. package/dist/commands/discovery-shared.d.ts.map +1 -1
  17. package/dist/commands/discovery-shared.js +8 -2
  18. package/dist/commands/engine.d.ts.map +1 -1
  19. package/dist/commands/engine.js +4 -2
  20. package/dist/commands/gc.d.ts.map +1 -1
  21. package/dist/commands/gc.js +7 -0
  22. package/dist/commands/init-helpers.d.ts.map +1 -1
  23. package/dist/commands/init-helpers.js +38 -12
  24. package/dist/commands/init.d.ts.map +1 -1
  25. package/dist/commands/init.js +10 -15
  26. package/dist/commands/migrate.d.ts.map +1 -1
  27. package/dist/commands/migrate.js +281 -14
  28. package/dist/commands/proof-compact.d.ts +9 -0
  29. package/dist/commands/proof-compact.d.ts.map +1 -0
  30. package/dist/commands/proof-compact.js +58 -0
  31. package/dist/commands/prove.d.ts +38 -0
  32. package/dist/commands/prove.d.ts.map +1 -1
  33. package/dist/commands/prove.js +222 -47
  34. package/dist/commands/sync/persistence.d.ts.map +1 -1
  35. package/dist/commands/sync/persistence.js +61 -16
  36. package/dist/commands/sync.d.ts +8 -0
  37. package/dist/commands/sync.d.ts.map +1 -1
  38. package/dist/commands/sync.js +42 -16
  39. package/dist/diagnostics.js +1 -1
  40. package/dist/engine-limits.d.ts +74 -0
  41. package/dist/engine-limits.d.ts.map +1 -0
  42. package/dist/engine-limits.js +201 -0
  43. package/dist/engine.d.ts +10 -0
  44. package/dist/engine.d.ts.map +1 -1
  45. package/dist/engine.js +57 -9
  46. package/dist/extractors/manifest.d.ts +8 -0
  47. package/dist/extractors/manifest.d.ts.map +1 -1
  48. package/dist/extractors/manifest.js +34 -5
  49. package/dist/extractors/markdown.d.ts +8 -0
  50. package/dist/extractors/markdown.d.ts.map +1 -1
  51. package/dist/extractors/markdown.js +57 -0
  52. package/dist/extractors/relationships.d.ts.map +1 -1
  53. package/dist/extractors/relationships.js +2 -0
  54. package/dist/intent-search.d.ts +4 -1
  55. package/dist/intent-search.d.ts.map +1 -1
  56. package/dist/intent-search.js +186 -33
  57. package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
  58. package/dist/operations/bootstrap/candidate-helpers.js +8 -1
  59. package/dist/operations/bootstrap/candidates.d.ts.map +1 -1
  60. package/dist/operations/bootstrap/candidates.js +54 -38
  61. package/dist/operations/bootstrap/generate.d.ts +2 -0
  62. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  63. package/dist/operations/bootstrap/generate.js +87 -33
  64. package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -1
  65. package/dist/operations/bootstrap/intent-claims.js +12 -4
  66. package/dist/operations/bootstrap/markdown-candidates.d.ts +2 -0
  67. package/dist/operations/bootstrap/markdown-candidates.d.ts.map +1 -1
  68. package/dist/operations/bootstrap/markdown-candidates.js +32 -10
  69. package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
  70. package/dist/operations/bootstrap/presentation.js +6 -2
  71. package/dist/operations/bootstrap/requirement-claims.d.ts +1 -0
  72. package/dist/operations/bootstrap/requirement-claims.d.ts.map +1 -1
  73. package/dist/operations/bootstrap/requirement-claims.js +13 -1
  74. package/dist/operations/bootstrap/validation.d.ts +4 -0
  75. package/dist/operations/bootstrap/validation.d.ts.map +1 -0
  76. package/dist/operations/bootstrap/validation.js +20 -0
  77. package/dist/operations/migration/inventory-rederive.d.ts +81 -0
  78. package/dist/operations/migration/inventory-rederive.d.ts.map +1 -0
  79. package/dist/operations/migration/inventory-rederive.js +484 -0
  80. package/dist/operations/migration/kb-sources.d.ts +53 -0
  81. package/dist/operations/migration/kb-sources.d.ts.map +1 -0
  82. package/dist/operations/migration/kb-sources.js +233 -0
  83. package/dist/operations/migration/origin-backfill.d.ts +39 -0
  84. package/dist/operations/migration/origin-backfill.d.ts.map +1 -0
  85. package/dist/operations/migration/origin-backfill.js +164 -0
  86. package/dist/operations/migration/polarity-values.d.ts +10 -0
  87. package/dist/operations/migration/polarity-values.d.ts.map +1 -0
  88. package/dist/operations/migration/polarity-values.js +60 -0
  89. package/dist/operations/migration/schema6.d.ts +59 -0
  90. package/dist/operations/migration/schema6.d.ts.map +1 -0
  91. package/dist/operations/migration/schema6.js +379 -0
  92. package/dist/operations/migration/source-paths.d.ts +131 -0
  93. package/dist/operations/migration/source-paths.d.ts.map +1 -0
  94. package/dist/operations/migration/source-paths.js +308 -0
  95. package/dist/operations/migration/superseded-closure.d.ts +54 -0
  96. package/dist/operations/migration/superseded-closure.d.ts.map +1 -0
  97. package/dist/operations/migration/superseded-closure.js +187 -0
  98. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
  99. package/dist/operations/modeling/logic-modeling.js +3 -5
  100. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  101. package/dist/operations/modeling/model-requirement.js +225 -67
  102. package/dist/operations/mutation/contradictions.d.ts +16 -0
  103. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  104. package/dist/operations/mutation/contradictions.js +32 -0
  105. package/dist/operations/mutation/delete.d.ts.map +1 -1
  106. package/dist/operations/mutation/delete.js +15 -7
  107. package/dist/operations/mutation/origin.d.ts +21 -0
  108. package/dist/operations/mutation/origin.d.ts.map +1 -0
  109. package/dist/operations/mutation/origin.js +78 -0
  110. package/dist/operations/mutation/plan-apply-journal.d.ts +182 -0
  111. package/dist/operations/mutation/plan-apply-journal.d.ts.map +1 -0
  112. package/dist/operations/mutation/plan-apply-journal.js +613 -0
  113. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +3 -1
  114. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -1
  115. package/dist/operations/mutation/predicate-vocabulary-guard.js +13 -2
  116. package/dist/operations/mutation/relationships.d.ts +5 -5
  117. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  118. package/dist/operations/mutation/relationships.js +31 -11
  119. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  120. package/dist/operations/mutation/serialization.js +3 -1
  121. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  122. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  123. package/dist/operations/mutation/source-authoring.js +7 -1
  124. package/dist/operations/mutation/types.d.ts +14 -0
  125. package/dist/operations/mutation/types.d.ts.map +1 -1
  126. package/dist/operations/mutation/upsert.d.ts +30 -3
  127. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  128. package/dist/operations/mutation/upsert.js +105 -35
  129. package/dist/operations/mutation/validate-upsert.d.ts +6 -0
  130. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  131. package/dist/operations/mutation/validate-upsert.js +34 -30
  132. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  133. package/dist/operations/planning/apply-plan.js +753 -145
  134. package/dist/operations/planning/compile-intent.d.ts +34 -1
  135. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  136. package/dist/operations/planning/compile-intent.js +314 -98
  137. package/dist/operations/proof/code-scope.d.ts +28 -0
  138. package/dist/operations/proof/code-scope.d.ts.map +1 -1
  139. package/dist/operations/proof/code-scope.js +72 -0
  140. package/dist/operations/proof/compact-receipts.d.ts +49 -0
  141. package/dist/operations/proof/compact-receipts.d.ts.map +1 -0
  142. package/dist/operations/proof/compact-receipts.js +160 -0
  143. package/dist/operations/proof/ingest-proof.d.ts +2 -0
  144. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  145. package/dist/operations/proof/ingest-proof.js +44 -23
  146. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  147. package/dist/operations/proof/prune-receipts.js +5 -9
  148. package/dist/operations/proof/receipt-compaction.d.ts +48 -0
  149. package/dist/operations/proof/receipt-compaction.d.ts.map +1 -0
  150. package/dist/operations/proof/receipt-compaction.js +121 -0
  151. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  152. package/dist/operations/semantic-advisor/analysis-receipt.js +12 -1
  153. package/dist/operations/semantic-advisor/analyze-prose.d.ts +2 -1
  154. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  155. package/dist/operations/semantic-advisor/analyze-prose.js +51 -5
  156. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  157. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  158. package/dist/operations/semantic-advisor/clauses.js +11 -1
  159. package/dist/operations/semantic-advisor/conditional-rules.d.ts +33 -0
  160. package/dist/operations/semantic-advisor/conditional-rules.d.ts.map +1 -0
  161. package/dist/operations/semantic-advisor/conditional-rules.js +262 -0
  162. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +3 -1
  163. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
  164. package/dist/operations/semantic-advisor/ingestion-boundary.js +14 -6
  165. package/dist/operations/semantic-advisor/plugin-orchestration.js +1 -1
  166. package/dist/prolog/codec.d.ts.map +1 -1
  167. package/dist/prolog/codec.js +2 -1
  168. package/dist/prolog.d.ts +9 -0
  169. package/dist/prolog.d.ts.map +1 -1
  170. package/dist/prolog.js +56 -10
  171. package/dist/proof/command-test-report.d.ts +74 -0
  172. package/dist/proof/command-test-report.d.ts.map +1 -0
  173. package/dist/proof/command-test-report.js +206 -0
  174. package/dist/public/branch-resolver.d.ts +1 -0
  175. package/dist/public/branch-resolver.d.ts.map +1 -1
  176. package/dist/public/branch-resolver.js +1 -0
  177. package/dist/public/entity-origin.d.ts +69 -0
  178. package/dist/public/entity-origin.d.ts.map +1 -0
  179. package/dist/public/entity-origin.js +142 -0
  180. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  181. package/dist/public/impact/full-kb-quality.js +1 -0
  182. package/dist/public/impact/requirement-quality.js +1 -1
  183. package/dist/public/operations/catalog.d.ts +130 -19
  184. package/dist/public/operations/catalog.d.ts.map +1 -1
  185. package/dist/public/operations/catalog.js +3 -0
  186. package/dist/public/operations/check-executor.d.ts.map +1 -1
  187. package/dist/public/operations/check-executor.js +8 -0
  188. package/dist/public/operations/contracts.d.ts +0 -5
  189. package/dist/public/operations/contracts.d.ts.map +1 -1
  190. package/dist/public/operations/contracts.js +63 -14
  191. package/dist/public/operations/discovery-entities.d.ts +15 -0
  192. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  193. package/dist/public/operations/discovery-entities.js +59 -0
  194. package/dist/public/operations/discovery-executors.d.ts +6 -1
  195. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  196. package/dist/public/operations/discovery-executors.js +65 -6
  197. package/dist/public/operations/index.d.ts +1 -0
  198. package/dist/public/operations/index.d.ts.map +1 -1
  199. package/dist/public/operations/index.js +1 -0
  200. package/dist/public/operations/migration-plan.d.ts +5 -0
  201. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  202. package/dist/public/operations/migration-plan.js +26 -1
  203. package/dist/public/operations/node-ports.d.ts.map +1 -1
  204. package/dist/public/operations/node-ports.js +24 -3
  205. package/dist/public/operations/origin-review.d.ts +51 -0
  206. package/dist/public/operations/origin-review.d.ts.map +1 -0
  207. package/dist/public/operations/origin-review.js +307 -0
  208. package/dist/public/operations/predicate-schema-conformance.js +1 -1
  209. package/dist/public/operations/repair-plan.d.ts.map +1 -1
  210. package/dist/public/operations/repair-plan.js +4 -0
  211. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  212. package/dist/public/operations/result-envelope.js +17 -5
  213. package/dist/public/operations/runtime-types.d.ts +9 -0
  214. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  215. package/dist/public/operations/schema6-check-actions.d.ts +127 -0
  216. package/dist/public/operations/schema6-check-actions.d.ts.map +1 -0
  217. package/dist/public/operations/schema6-check-actions.js +575 -0
  218. package/dist/public/operations/source-path-dangling.d.ts +17 -0
  219. package/dist/public/operations/source-path-dangling.d.ts.map +1 -0
  220. package/dist/public/operations/source-path-dangling.js +66 -0
  221. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  222. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  223. package/dist/public/operations/specs/check-rules.generated.js +15 -1
  224. package/dist/public/operations/specs/check.d.ts +2 -2
  225. package/dist/public/operations/specs/check.js +1 -1
  226. package/dist/public/operations/specs/composite.d.ts +351 -0
  227. package/dist/public/operations/specs/composite.d.ts.map +1 -0
  228. package/dist/public/operations/specs/composite.js +96 -0
  229. package/dist/public/operations/specs/discovery.d.ts +8 -3
  230. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  231. package/dist/public/operations/specs/discovery.js +8 -3
  232. package/dist/public/operations/specs/modeling.d.ts +2 -2
  233. package/dist/public/operations/specs/modeling.js +2 -2
  234. package/dist/public/operations/specs/mutation-schemas.d.ts +73 -8
  235. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  236. package/dist/public/operations/specs/mutation-schemas.js +43 -7
  237. package/dist/public/operations/specs/mutation.d.ts +1 -1
  238. package/dist/public/operations/specs/mutation.js +1 -1
  239. package/dist/public/operations/specs/planning.d.ts +2 -2
  240. package/dist/public/operations/specs/planning.js +4 -4
  241. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  242. package/dist/public/operations/specs/reporting.js +13 -26
  243. package/dist/public/operations/specs/upsert.d.ts +79 -9
  244. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  245. package/dist/public/operations/specs/upsert.js +6 -1
  246. package/dist/public/operations/types.d.ts +1 -1
  247. package/dist/public/operations/types.d.ts.map +1 -1
  248. package/dist/public/proof-receipt.d.ts +1 -0
  249. package/dist/public/proof-receipt.d.ts.map +1 -1
  250. package/dist/public/schemas/entity.d.ts.map +1 -1
  251. package/dist/public/schemas/entity.js +52 -0
  252. package/dist/public/schemas/relationship.d.ts.map +1 -1
  253. package/dist/public/schemas/relationship.js +2 -0
  254. package/dist/public/skills/kibi-bootstrap/SKILL.md +35 -67
  255. package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  256. package/dist/public/skills/kibi-usage/SKILL.md +68 -18
  257. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  258. package/dist/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
  259. package/dist/public/skills/kibi-usage/resources/logic-ir.md +2 -2
  260. package/dist/public/skills/kibi-usage/resources/operation-access.md +25 -1
  261. package/dist/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
  262. package/dist/public/skills/kibi-usage/resources/workflows.md +42 -25
  263. package/dist/public/telemetry-acceptance.d.ts +58 -2
  264. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  265. package/dist/public/telemetry-acceptance.js +136 -10
  266. package/dist/public/telemetry-remediation.d.ts.map +1 -1
  267. package/dist/public/telemetry-remediation.js +26 -10
  268. package/dist/relationships/shards.d.ts +13 -0
  269. package/dist/relationships/shards.d.ts.map +1 -1
  270. package/dist/relationships/shards.js +54 -28
  271. package/dist/runtime/cli-runtime.d.ts.map +1 -1
  272. package/dist/runtime/cli-runtime.js +44 -3
  273. package/dist/runtime/detached-snapshot.d.ts +38 -0
  274. package/dist/runtime/detached-snapshot.d.ts.map +1 -0
  275. package/dist/runtime/detached-snapshot.js +92 -0
  276. package/dist/schemas/entity.schema.json +122 -0
  277. package/dist/search-answer.d.ts +157 -0
  278. package/dist/search-answer.d.ts.map +1 -0
  279. package/dist/search-answer.js +846 -0
  280. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  281. package/dist/traceability/impact-knowledge.js +7 -0
  282. package/dist/traceability/symbol-extract.js +3 -3
  283. package/dist/traceability/temp-kb.d.ts.map +1 -1
  284. package/dist/traceability/temp-kb.js +12 -0
  285. package/dist/types/entities.d.ts +13 -0
  286. package/dist/types/entities.d.ts.map +1 -1
  287. package/dist/types/relationships.d.ts +1 -1
  288. package/dist/types/relationships.d.ts.map +1 -1
  289. package/dist/utils/branch-resolver.d.ts +37 -1
  290. package/dist/utils/branch-resolver.d.ts.map +1 -1
  291. package/dist/utils/branch-resolver.js +130 -3
  292. package/dist/utils/repo-relative-path.d.ts +18 -0
  293. package/dist/utils/repo-relative-path.d.ts.map +1 -0
  294. package/dist/utils/repo-relative-path.js +58 -0
  295. package/dist/utils/rule-registry.generated.d.ts +75 -3
  296. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  297. package/dist/utils/rule-registry.generated.js +89 -3
  298. package/dist/utils/schema-version.d.ts +1 -1
  299. package/dist/utils/schema-version.d.ts.map +1 -1
  300. package/dist/utils/schema-version.js +4 -3
  301. package/dist/utils/strict-modeling.d.ts +1 -1
  302. package/dist/utils/strict-modeling.d.ts.map +1 -1
  303. package/dist/utils/strict-modeling.js +23 -3
  304. package/package.json +3 -3
  305. package/schema/entities.pl +22 -0
  306. package/schema/relationships.pl +14 -0
  307. package/schema/validation.pl +45 -1
  308. package/src/public/branch-resolver.ts +1 -0
  309. package/src/public/entity-origin.ts +175 -0
  310. package/src/public/impact/full-kb-quality.ts +1 -0
  311. package/src/public/impact/requirement-quality.ts +1 -1
  312. package/src/public/operations/catalog.ts +3 -0
  313. package/src/public/operations/check-executor.ts +15 -0
  314. package/src/public/operations/contracts.ts +75 -15
  315. package/src/public/operations/discovery-entities.ts +74 -0
  316. package/src/public/operations/discovery-executors.ts +88 -10
  317. package/src/public/operations/index.ts +1 -0
  318. package/src/public/operations/migration-plan.ts +30 -1
  319. package/src/public/operations/node-ports.ts +24 -3
  320. package/src/public/operations/origin-review.ts +375 -0
  321. package/src/public/operations/predicate-schema-conformance.ts +1 -1
  322. package/src/public/operations/repair-plan.ts +4 -0
  323. package/src/public/operations/result-envelope.ts +18 -6
  324. package/src/public/operations/runtime-types.ts +9 -0
  325. package/src/public/operations/schema6-check-actions.ts +699 -0
  326. package/src/public/operations/source-path-dangling.ts +81 -0
  327. package/src/public/operations/specs/check-rules.generated.ts +15 -1
  328. package/src/public/operations/specs/check.ts +1 -1
  329. package/src/public/operations/specs/composite.ts +141 -0
  330. package/src/public/operations/specs/discovery.ts +9 -3
  331. package/src/public/operations/specs/modeling.ts +2 -2
  332. package/src/public/operations/specs/mutation-schemas.ts +49 -7
  333. package/src/public/operations/specs/mutation.ts +1 -1
  334. package/src/public/operations/specs/planning.ts +4 -4
  335. package/src/public/operations/specs/reporting.ts +13 -38
  336. package/src/public/operations/specs/upsert.ts +7 -1
  337. package/src/public/operations/types.ts +2 -0
  338. package/src/public/proof-receipt.ts +1 -0
  339. package/src/public/schemas/entity.ts +57 -0
  340. package/src/public/schemas/relationship.ts +2 -0
  341. package/src/public/skills/kibi-bootstrap/SKILL.md +35 -67
  342. package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  343. package/src/public/skills/kibi-usage/SKILL.md +68 -18
  344. package/src/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  345. package/src/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
  346. package/src/public/skills/kibi-usage/resources/logic-ir.md +2 -2
  347. package/src/public/skills/kibi-usage/resources/operation-access.md +25 -1
  348. package/src/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
  349. package/src/public/skills/kibi-usage/resources/workflows.md +42 -25
  350. package/src/public/telemetry-acceptance-types.d.ts +4 -1
  351. package/src/public/telemetry-acceptance.ts +204 -10
  352. package/src/public/telemetry-remediation.ts +39 -10
  353. package/src/schemas/entity.schema.json +122 -0
  354. package/src/schemas/relationship.schema.json +2 -0
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
2
2
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { executeIngestProof } from "../operations/proof/ingest-proof.js";
5
+ import { PROOF_TEST_REPORT_ENV, PROOF_TEST_REPORT_VERSION, attributeCommandRun, proofTestReportPath, } from "../proof/command-test-report.js";
5
6
  import { PROOF_RUNS_DIR, loadProofIntegrations, resolveIntegration, } from "../proof/integrations.js";
6
7
  import { convertJUnitXml } from "../proof/producers/junit-adapter.js";
7
8
  import { convertTap } from "../proof/producers/tap-adapter.js";
@@ -273,6 +274,7 @@ export async function proveCommand(options, deps = {}) {
273
274
  const runsDir = path.join(context.workspaceRoot, PROOF_RUNS_DIR);
274
275
  await mkdir(runsDir, { recursive: true });
275
276
  const ingestResults = [];
277
+ const runAttribution = new Map();
276
278
  const failures = [];
277
279
  for (const [integrationId, tests] of groups) {
278
280
  const integration = resolveIntegration(integrations.integrations, integrationId);
@@ -285,7 +287,17 @@ export async function proveCommand(options, deps = {}) {
285
287
  path.join(PROOF_RUNS_DIR, `${integrationId}.json`));
286
288
  await mkdir(path.dirname(artifactPath), { recursive: true });
287
289
  await rm(artifactPath, { force: true });
288
- const env = commandEnvironment(integration, commandArgv, snapshot, context.workspaceRoot, tests.map((test) => String(test.id)), artifactPath);
290
+ const selectedTestIds = tests.map((test) => String(test.id));
291
+ // Command integrations may attribute their run per test; any report
292
+ // left by an earlier run must never be read as this run's evidence.
293
+ const testReportPath = integration.producer === "command"
294
+ ? proofTestReportPath(artifactPath)
295
+ : undefined;
296
+ if (testReportPath !== undefined)
297
+ await rm(testReportPath, { force: true });
298
+ const env = commandEnvironment(integration, commandArgv, snapshot, context.workspaceRoot, selectedTestIds, artifactPath);
299
+ if (testReportPath !== undefined)
300
+ env[PROOF_TEST_REPORT_ENV] = testReportPath;
289
301
  const startedAt = new Date().toISOString();
290
302
  let exitCode;
291
303
  try {
@@ -296,41 +308,78 @@ export async function proveCommand(options, deps = {}) {
296
308
  continue;
297
309
  }
298
310
  const finishedAt = new Date().toISOString();
299
- let artifact;
311
+ let evaluated;
300
312
  try {
301
- artifact = await buildArtifact({
302
- integration,
303
- commandArgv,
304
- exitCode,
305
- startedAt,
306
- finishedAt,
307
- artifactPath,
308
- snapshot,
309
- tests,
310
- });
313
+ evaluated =
314
+ testReportPath === undefined
315
+ ? {
316
+ artifacts: [
317
+ {
318
+ artifact: await buildArtifact({
319
+ integration,
320
+ commandArgv,
321
+ exitCode,
322
+ startedAt,
323
+ finishedAt,
324
+ artifactPath,
325
+ snapshot,
326
+ tests,
327
+ }),
328
+ testIds: selectedTestIds,
329
+ },
330
+ ],
331
+ }
332
+ : buildCommandRunArtifacts({
333
+ integration,
334
+ commandArgv,
335
+ exitCode,
336
+ startedAt,
337
+ finishedAt,
338
+ snapshot,
339
+ tests,
340
+ attribution: await readCommandAttribution(testReportPath, selectedTestIds, exitCode),
341
+ });
311
342
  }
312
343
  catch (error) {
313
344
  failures.push(`integration '${integrationId}': ${error instanceof Error ? error.message : String(error)}`);
314
345
  continue;
315
346
  }
316
- const artifactErrors = proofRunArtifactErrors(artifact);
347
+ const artifactErrors = [
348
+ ...(evaluated.wholeRun === undefined ? [] : [evaluated.wholeRun]),
349
+ ...evaluated.artifacts.map((entry) => entry.artifact),
350
+ ].flatMap((artifact) => proofRunArtifactErrors(artifact));
317
351
  if (artifactErrors.length > 0) {
318
352
  failures.push(`integration '${integrationId}' produced an invalid kibi.proof-run.v1 artifact: ${artifactErrors.join("; ")}`);
319
353
  continue;
320
354
  }
321
355
  await mkdir(path.dirname(artifactPath), { recursive: true });
322
- await writeFile(artifactPath, `${JSON.stringify(artifact, null, 2)}\n`, "utf8");
356
+ await writeFile(artifactPath, `${JSON.stringify(evaluated.wholeRun ?? evaluated.artifacts[0]?.artifact, null, 2)}\n`, "utf8");
357
+ if (evaluated.wholeRun !== undefined) {
358
+ for (const entry of evaluated.artifacts) {
359
+ await writeFile(partitionArtifactPath(artifactPath, entry.artifact.run.outcome), `${JSON.stringify(entry.artifact, null, 2)}\n`, "utf8");
360
+ }
361
+ }
323
362
  const afterRun = await readWorkspaceSnapshot(context);
324
363
  if (!afterRun.available || afterRun.snapshot.hash !== snapshot) {
325
364
  failures.push(`integration '${integrationId}' changed the tracked workspace during proof execution; proof is bound to snapshot ${snapshot}${describeWorkspaceDrift(afterRun)}`);
326
365
  continue;
327
366
  }
328
- const ingested = await ingestProof({
329
- snapshot,
330
- artifact: artifact,
331
- testIds: tests.map((test) => String(test.id)),
332
- }, context);
333
- ingestResults.push(ingested.structuredContent);
367
+ // One ingest per partition: each test is evaluated only against the
368
+ // slice of the run its own steps produced.
369
+ const partitionResults = [];
370
+ for (const entry of evaluated.artifacts) {
371
+ const ingested = await ingestProof({
372
+ snapshot,
373
+ artifact: entry.artifact,
374
+ testIds: entry.testIds,
375
+ }, context);
376
+ partitionResults.push(ingested.structuredContent);
377
+ }
378
+ const merged = mergeIngestResults(partitionResults);
379
+ if (merged !== undefined) {
380
+ ingestResults.push(merged);
381
+ runAttribution.set(merged, evaluated);
382
+ }
334
383
  const afterIngest = await readWorkspaceSnapshot(context);
335
384
  if (!afterIngest.available || afterIngest.snapshot.hash !== snapshot) {
336
385
  failures.push(`the tracked workspace changed while receipts were applied; re-run kibi prove${describeWorkspaceDrift(afterIngest)}`);
@@ -343,11 +392,25 @@ export async function proveCommand(options, deps = {}) {
343
392
  proved: passed,
344
393
  failed,
345
394
  unchanged,
346
- runs: ingestResults.map((result) => ({
347
- integration: result.integration,
348
- summary: summarize(result),
349
- results: result.results,
350
- })),
395
+ runs: ingestResults.map((result) => {
396
+ const attribution = runAttribution.get(result)?.attribution;
397
+ return {
398
+ integration: result.integration,
399
+ summary: summarize(result),
400
+ ...(attribution === undefined
401
+ ? {}
402
+ : {
403
+ attribution: attribution.attribution,
404
+ ...(attribution.attribution === "aggregate"
405
+ ? { attributionReason: attribution.reason }
406
+ : {}),
407
+ ...(attribution.failedSteps.length > 0
408
+ ? { failedSteps: attribution.failedSteps }
409
+ : {}),
410
+ }),
411
+ results: result.results,
412
+ };
413
+ }),
351
414
  ...(failures.length > 0 ? { failures } : {}),
352
415
  };
353
416
  process.stdout.write(`${JSON.stringify(summary)}\n`);
@@ -361,6 +424,138 @@ export async function proveCommand(options, deps = {}) {
361
424
  : { status: "error", error: 1 });
362
425
  }
363
426
  }
427
+ /** Read a command integration's optional per-test report and attribute it. */
428
+ // implements REQ-kibi-fresh-verification-receipts-v2
429
+ export async function readCommandAttribution(reportPath, selectedTestIds, exitCode) {
430
+ let raw;
431
+ try {
432
+ raw = await readFile(reportPath, "utf8");
433
+ }
434
+ catch {
435
+ return attributeCommandRun({
436
+ selectedTestIds,
437
+ exitCode,
438
+ report: undefined,
439
+ });
440
+ }
441
+ let report;
442
+ try {
443
+ report = JSON.parse(raw);
444
+ }
445
+ catch (error) {
446
+ return {
447
+ attribution: "aggregate",
448
+ reason: `the ${PROOF_TEST_REPORT_VERSION} is not valid JSON (${error instanceof Error ? error.message : String(error)}), so the run is evaluated as one unit`,
449
+ failedSteps: [],
450
+ };
451
+ }
452
+ return attributeCommandRun({ selectedTestIds, exitCode, report });
453
+ }
454
+ /** Where a partition's evaluated artifact is kept next to the run artifact. */
455
+ // implements REQ-kibi-fresh-verification-receipts-v2
456
+ export function partitionArtifactPath(artifactPath, outcome) {
457
+ const stem = artifactPath.endsWith(".json")
458
+ ? artifactPath.slice(0, -".json".length)
459
+ : artifactPath;
460
+ return `${stem}.${outcome}.json`;
461
+ }
462
+ function describeFailedStep(step) {
463
+ return `${step.testId} step ${step.stepIndex} ${step.outcome}${step.exitCode === null ? "" : ` (exit ${step.exitCode})`}: ${step.command.join(" ")}`;
464
+ }
465
+ /**
466
+ * Build the kibi.proof-run.v1 evidence of a `command` integration run.
467
+ *
468
+ * Without per-test attribution the run is one unit, exactly as before: a
469
+ * failing process fails every selected test. With a valid
470
+ * kibi.proof-test-report.v1 the run is split into one artifact per test
471
+ * outcome: tests whose own steps all passed are evaluated against a passing
472
+ * slice (exit code 0, the aggregate result of their own steps), and each
473
+ * failing outcome gets a failing slice that names the steps that failed. The
474
+ * whole-process artifact is kept alongside for audit.
475
+ */
476
+ // implements REQ-kibi-fresh-verification-receipts-v2
477
+ export function buildCommandRunArtifacts(input) {
478
+ const { integration, exitCode, tests, attribution } = input;
479
+ const base = (run, proofResults, diagnostics) => ({
480
+ version: PROOF_RUN_VERSION,
481
+ producer: {
482
+ name: "kibi-command-producer",
483
+ ...(integration.producer_version !== undefined
484
+ ? { version: integration.producer_version }
485
+ : {}),
486
+ },
487
+ integration: integration.id,
488
+ command_argv: [...input.commandArgv],
489
+ code_snapshot: input.snapshot,
490
+ environment: {
491
+ os: process.platform,
492
+ arch: process.arch,
493
+ runtime: { name: "node", version: process.version },
494
+ },
495
+ run,
496
+ proof_results: proofResults,
497
+ ...(diagnostics.length > 0 ? { diagnostics: [...diagnostics] } : {}),
498
+ });
499
+ const timing = { started_at: input.startedAt, finished_at: input.finishedAt };
500
+ const allTestIds = tests.map((test) => String(test.id));
501
+ const wholeResults = dedupeObligations(tests);
502
+ const failedLines = attribution.failedSteps.map(describeFailedStep);
503
+ if (attribution.attribution === "aggregate") {
504
+ const passedRun = exitCode === 0;
505
+ const artifact = base({
506
+ outcome: passedRun ? "passed" : "failed",
507
+ exit_code: exitCode,
508
+ ...timing,
509
+ }, passedRun ? wholeResults : markAggregateFailure(wholeResults), passedRun ? [] : [attribution.reason, ...failedLines]);
510
+ return {
511
+ artifacts: [{ artifact, testIds: allTestIds }],
512
+ attribution,
513
+ };
514
+ }
515
+ const byId = new Map(tests.map((test) => [String(test.id), test]));
516
+ const artifacts = attribution.partitions.map((partition) => {
517
+ const partitionTests = partition.testIds.map((testId) => byId.get(testId));
518
+ const results = dedupeObligations(partitionTests).map((result) => ({
519
+ ...result,
520
+ outcome: partition.outcome,
521
+ }));
522
+ const artifact = base({
523
+ outcome: partition.outcome,
524
+ exit_code: partition.exitCode,
525
+ ...timing,
526
+ ...(partition.outcome === "passed"
527
+ ? {}
528
+ : { failure_phase: "execution" }),
529
+ }, results, [
530
+ `per-test attribution: ${partition.testIds.length} of ${allTestIds.length} selected test(s) whose own steps ${partition.outcome === "passed" ? "all passed" : `ended ${partition.outcome}`}; the integration process exited ${exitCode}`,
531
+ ...partition.failedSteps.map(describeFailedStep),
532
+ ]);
533
+ return { artifact, testIds: partition.testIds };
534
+ });
535
+ const wholeRun = base({
536
+ outcome: exitCode === 0 ? "passed" : "failed",
537
+ exit_code: exitCode,
538
+ ...timing,
539
+ }, exitCode === 0 ? wholeResults : markAggregateFailure(wholeResults), [
540
+ `evaluated per test: ${attribution.partitions.map((partition) => `${partition.testIds.length} ${partition.outcome}`).join(", ")}`,
541
+ ...failedLines,
542
+ ]);
543
+ return { artifacts, wholeRun, attribution };
544
+ }
545
+ function mergeIngestResults(results) {
546
+ const [first] = results;
547
+ if (first === undefined)
548
+ return undefined;
549
+ if (results.length === 1)
550
+ return first;
551
+ return {
552
+ ...first,
553
+ passed: results.reduce((sum, result) => sum + result.passed, 0),
554
+ failed: results.reduce((sum, result) => sum + result.failed, 0),
555
+ unchanged: results.reduce((sum, result) => sum + result.unchanged, 0),
556
+ results: results.flatMap((result) => result.results),
557
+ };
558
+ }
364
559
  async function buildArtifact(input) {
365
560
  const { integration, commandArgv, exitCode, startedAt, finishedAt, artifactPath, snapshot, tests, } = input;
366
561
  const run = (outcome) => ({
@@ -369,28 +564,8 @@ async function buildArtifact(input) {
369
564
  started_at: startedAt,
370
565
  finished_at: finishedAt,
371
566
  });
372
- if (integration.producer === "command") {
373
- const results = dedupeObligations(tests);
374
- return {
375
- version: PROOF_RUN_VERSION,
376
- producer: {
377
- name: "kibi-command-producer",
378
- ...(integration.producer_version !== undefined
379
- ? { version: integration.producer_version }
380
- : {}),
381
- },
382
- integration: integration.id,
383
- command_argv: [...commandArgv],
384
- code_snapshot: snapshot,
385
- environment: {
386
- os: process.platform,
387
- arch: process.arch,
388
- runtime: { name: "node", version: process.version },
389
- },
390
- run: run(exitCode === 0 ? "passed" : "failed"),
391
- proof_results: exitCode === 0 ? results : markAggregateFailure(results),
392
- };
393
- }
567
+ // `command` integrations never reach this function: proveCommand builds
568
+ // their artifacts with buildCommandRunArtifacts (per-test attribution).
394
569
  if (integration.producer === "junit" || integration.producer === "tap") {
395
570
  const nativePath = integration.artifact;
396
571
  if (!nativePath)
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0HrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AA8CD,iFAAiF;AACjF,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,CAkCjB;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,8EAA8E;AAC9E,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,SAAS,qBAAqB,EAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAyPvD;AA4BD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAER;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,EAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAmO7D"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA2HrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAuFD,iFAAiF;AACjF,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,8EAA8E;AAC9E,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,SAAS,qBAAqB,EAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA8QvD;AA4BD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAER;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,EAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAmO7D"}
@@ -60,6 +60,7 @@ const STRING_ARRAY_FIELDS = new Set([
60
60
  "argument_names",
61
61
  "argument_types",
62
62
  "argument_descriptions",
63
+ "key_arguments",
63
64
  "aliases",
64
65
  "examples",
65
66
  "predicate_args",
@@ -149,29 +150,54 @@ function parsePrologList(value) {
149
150
  }
150
151
  return values;
151
152
  }
152
- async function entityIdsForSource(prolog, sourceFile) {
153
- const candidates = new Set([
154
- sourceFile,
155
- path.relative(process.cwd(), sourceFile),
156
- path.basename(sourceFile),
157
- ]);
153
+ function sourceLookupCandidates(sourceFile) {
154
+ return [
155
+ ...new Set([
156
+ sourceFile,
157
+ path.relative(process.cwd(), sourceFile),
158
+ path.basename(sourceFile),
159
+ ]),
160
+ ];
161
+ }
162
+ async function entityIdsForCandidate(prolog, candidate, ids) {
163
+ const result = await prolog.query(`kb_entities_by_source(${toPrologString(candidate)}, Ids)`);
164
+ if (result.success) {
165
+ for (const id of parsePrologList(result.bindings?.Ids))
166
+ ids.add(id);
167
+ }
168
+ }
169
+ /**
170
+ * Source lookups per round trip. One engine round trip per candidate made a
171
+ * cold sync of ~1,600 sources spend minutes in socket and poll latency; the
172
+ * lookups are pure reads, so a bounded batch returns the same id union.
173
+ */
174
+ const SOURCE_LOOKUP_BATCH_SIZE = 200;
175
+ // implements REQ-core-journaled-engine-persistence
176
+ async function entityIdsForSources(prolog, sourceFiles) {
177
+ const candidates = [
178
+ ...new Set(sourceFiles.flatMap((file) => sourceLookupCandidates(file))),
179
+ ];
158
180
  const ids = new Set();
159
- for (const candidate of candidates) {
160
- const result = await prolog.query(`kb_entities_by_source(${toPrologString(candidate)}, Ids)`);
161
- if (result.success) {
162
- for (const id of parsePrologList(result.bindings?.Ids))
181
+ for (let offset = 0; offset < candidates.length; offset += SOURCE_LOOKUP_BATCH_SIZE) {
182
+ const chunk = candidates.slice(offset, offset + SOURCE_LOOKUP_BATCH_SIZE);
183
+ const sources = chunk.map((candidate) => toPrologString(candidate));
184
+ const batched = await prolog.query(`findall(Id, (member(Source, [${sources.join(",")}]), kb_entities_by_source(Source, SourceIds), member(Id, SourceIds)), Ids)`);
185
+ if (batched.success) {
186
+ for (const id of parsePrologList(batched.bindings?.Ids))
163
187
  ids.add(id);
188
+ continue;
189
+ }
190
+ // A failed batch must not hide the ids a single lookup would still find:
191
+ // retry this chunk one candidate at a time, as before batching.
192
+ for (const candidate of chunk) {
193
+ await entityIdsForCandidate(prolog, candidate, ids);
164
194
  }
165
195
  }
166
- return [...ids];
196
+ return ids;
167
197
  }
168
198
  /** Remove entities owned by changed/deleted source files before re-upserting. */
169
199
  export async function retractEntitiesForSources(prolog, sourceFiles) {
170
- const ids = new Set();
171
- for (const sourceFile of sourceFiles) {
172
- for (const id of await entityIdsForSource(prolog, sourceFile))
173
- ids.add(id);
174
- }
200
+ const ids = await entityIdsForSources(prolog, sourceFiles);
175
201
  if (ids.size === 0)
176
202
  return 0;
177
203
  const goals = [...ids].map((id) => `kb_retract_entity(${toPrologAtom(id)})`);
@@ -351,9 +377,28 @@ prolog, results, entityIds, options = {}) {
351
377
  if (entity.type === "req" && entity.proof_exempt !== undefined) {
352
378
  props.push(`proof_exempt=${entity.proof_exempt}`);
353
379
  }
380
+ if (entity.type === "scenario" && entity.expects !== undefined) {
381
+ props.push(`expects=${toPrologAtom(entity.expects)}`);
382
+ }
354
383
  if (entity.type === "req" && entity.proof_exempt_reason !== undefined) {
355
384
  props.push(`proof_exempt_reason=${toPrologString(entity.proof_exempt_reason)}`);
356
385
  }
386
+ for (const field of [
387
+ "approved_by",
388
+ "approval_ref",
389
+ "rationale",
390
+ ]) {
391
+ const value = entity.type === "req" ? entity[field] : undefined;
392
+ if (value !== undefined)
393
+ props.push(`${field}=${toPrologString(value)}`);
394
+ }
395
+ if (entity.type === "req" && entity.exempts_claims) {
396
+ props.push(`exempts_claims=[${entity.exempts_claims.map(toPrologAtom).join(",")}]`);
397
+ }
398
+ // Provenance travels as a JSON object string, like proof_contract.
399
+ if (entity.origin !== undefined) {
400
+ props.push(`origin=${toPrologString(JSON.stringify(entity.origin))}`);
401
+ }
357
402
  if (sourceFile)
358
403
  props.push(`sourceFile=${toPrologString(sourceFile)}`);
359
404
  if (entity.type === "symbol") {
@@ -1,6 +1,7 @@
1
1
  import type { Diagnostic, SyncSummary } from "../diagnostics.js";
2
2
  import { acquireSymbolCompilerLock } from "../operations/mutation/symbol-compiler-lock.js";
3
3
  import { PrologProcess } from "../prolog.js";
4
+ import { type BranchAttachment } from "../utils/branch-resolver.js";
4
5
  import type { PendingSourceReceiptSnapshot } from "./sync/discovery.js";
5
6
  export declare class SyncError extends Error {
6
7
  constructor(message: string);
@@ -42,6 +43,13 @@ export declare function syncCommand(options?: {
42
43
  recoveryBackupPath?: string;
43
44
  /** Workspace to operate on when invoked through MCP or another host. */
44
45
  workspaceRoot?: string;
46
+ /**
47
+ * Internal: compile the read-only snapshot of a detached checkout into
48
+ * the attachment from resolveReadBranchAttachment instead of a branch KB.
49
+ */
50
+ detachedSnapshot?: BranchAttachment;
51
+ /** Keep stdout clean for a host's own output; stderr still reports. */
52
+ quiet?: boolean;
45
53
  }, runtime?: SyncCommandRuntime): Promise<SyncResult>;
46
54
  export { normalizeMarkdownPath } from "./sync/discovery.js";
47
55
  //# sourceMappingURL=sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA0B7C,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AA2BxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAqDD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA6DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CA6nCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AA2BxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAqDD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA6DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CA0pCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -27,7 +27,7 @@ import { acquireSymbolCompilerLock, releaseSymbolCompilerLock, } from "../operat
27
27
  import { analyzeSemanticAdvisorInput } from "../operations/semantic-advisor/analyze-prose.js";
28
28
  import { validateSemanticInventoryBoundary } from "../operations/semantic-advisor/ingestion-boundary.js";
29
29
  import { PrologProcess } from "../prolog.js";
30
- import { resolveBranchAttachment } from "../utils/branch-resolver.js";
30
+ import { detachedHeadWriteRefusal, resolveBranchAttachment, } from "../utils/branch-resolver.js";
31
31
  import { branchStoreManifestPath, branchStorePath, ensureBranchStoreManifest, expectedBranchStoreManifest, } from "../utils/branch-store-locator.js";
32
32
  import { loadEntityPaths } from "../utils/config.js";
33
33
  import { SYNC_CACHE_TTL_MS, SYNC_CACHE_VERSION, SYNC_COMPILER_FINGERPRINT, hashFile, hashManifestWithCoordinates, hashNormalized, readSyncCache, toCacheKey, writeSyncCache, } from "./sync/cache.js";
@@ -267,6 +267,9 @@ export function maybePushDocsNotIndexedDiagnostic(diagnostics, performedFullRein
267
267
  // implements REQ-003, REQ-007
268
268
  export async function syncCommand(options = {}, runtime = {}) {
269
269
  const validateOnly = options.validateOnly ?? false;
270
+ const info = options.quiet
271
+ ? () => undefined
272
+ : (...args) => console.log(...args);
270
273
  const rebuild = options.rebuild ?? false;
271
274
  const recoveryBackupPath = options.recoveryBackupPath;
272
275
  const workspaceRoot = path.resolve(options.workspaceRoot ?? process.cwd());
@@ -299,12 +302,21 @@ export async function syncCommand(options = {}, runtime = {}) {
299
302
  }
300
303
  assertNoUnresolvedGitConflicts(workspaceRoot);
301
304
  // Branch resolution
302
- const branchResult = resolveBranchAttachment(workspaceRoot);
305
+ if (options.detachedSnapshot !== undefined &&
306
+ options.detachedSnapshot.kind !== "detached_snapshot") {
307
+ throw new SyncError("Only a detached HEAD snapshot attachment can be compiled explicitly");
308
+ }
309
+ const branchResult = options.detachedSnapshot ?? resolveBranchAttachment(workspaceRoot);
303
310
  if ("error" in branchResult) {
304
- const diagnostic = branchErrorToDiagnostic(branchResult.code, branchResult.error);
311
+ // A detached HEAD has no branch KB to compile; name the way out and
312
+ // that reads keep working from the checkout's read-only snapshot.
313
+ const reason = branchResult.code === "DETACHED_HEAD"
314
+ ? detachedHeadWriteRefusal("kibi sync", workspaceRoot)
315
+ : branchResult.error;
316
+ const diagnostic = branchErrorToDiagnostic(branchResult.code, reason);
305
317
  diagnostics.push(diagnostic);
306
- console.error(`Failed to resolve active branch: ${branchResult.error}`);
307
- throw new SyncError(`Failed to resolve active branch: ${branchResult.error}`);
318
+ console.error(`Failed to resolve active branch: ${reason}`);
319
+ throw new SyncError(`Failed to resolve active branch: ${reason}`);
308
320
  }
309
321
  if (branchResult.migrationRequired && !validateOnly) {
310
322
  throw new SyncError(`Sync blocked: KB is attached through legacy branch storage for '${branchResult.gitBranch}'. Run 'kibi branch migrate --from ${branchResult.kbBranch} --to ${branchResult.gitBranch} --apply' first.`);
@@ -393,7 +405,7 @@ export async function syncCommand(options = {}, runtime = {}) {
393
405
  compilerCacheIsFresh(syncCache, workspaceRoot, sourceFiles, nowMs) &&
394
406
  compilerCacheFilesMatch(syncCache, workspaceRoot, sourceFiles, relationshipShardFiles, fastPathSourceHashOf)) {
395
407
  await checkpointNoopSync(workspaceRoot, currentBranch);
396
- console.log("✓ Imported 0 entities, 0 relationships (no changes)");
408
+ info("✓ Imported 0 entities, 0 relationships (no changes)");
397
409
  return withOptionalCommit({
398
410
  branch: currentBranch,
399
411
  timestamp: new Date().toISOString(),
@@ -631,6 +643,9 @@ export async function syncCommand(options = {}, runtime = {}) {
631
643
  const results = useEntityDelta
632
644
  ? extractedResults.filter(({ entity }) => changedEntityIds.has(entity.id))
633
645
  : extractedResults;
646
+ // implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
647
+ // Every drifted inventory is reported in one run, not one per sync attempt.
648
+ const inventoryFailures = [];
634
649
  for (const result of extractedResults) {
635
650
  if (result.entity.type !== "req")
636
651
  continue;
@@ -654,11 +669,19 @@ export async function syncCommand(options = {}, runtime = {}) {
654
669
  previousSemanticHash !== boundary.sourceHash) ||
655
670
  advertisedContract;
656
671
  if (enforceBoundary && boundary.errors.length > 0) {
657
- throw new SyncError(`${key}: proposition-complete ingestion failed: ${boundary.errors.join("; ")}. Run kb_semantic_advisor with the complete requirement prose and preserve its inventory contract.`);
672
+ inventoryFailures.push(`${key}: proposition-complete ingestion failed: ${boundary.errors.join("; ")}.`);
673
+ continue;
658
674
  }
659
675
  nextSemanticHashes[key] = boundary.sourceHash;
660
676
  nextSemanticContracts[key] = advertisedContract;
661
677
  }
678
+ if (inventoryFailures.length > 0) {
679
+ throw new SyncError([
680
+ `${inventoryFailures.length} requirement(s) failed proposition-complete ingestion:`,
681
+ ...inventoryFailures.map((failure) => ` ${failure}`),
682
+ "Run 'kibi migrate' to re-derive inventories that drifted with the semantic advisor (it lists any that need a manual fix), or run kb_model mode analyze (CLI: semantic-advisor) with the complete requirement prose and preserve its inventory contract.",
683
+ ].join("\n"));
684
+ }
662
685
  // Collect INVALID_AUTHORING diagnostics
663
686
  for (const err of errors) {
664
687
  const error = new Error(err.message);
@@ -732,7 +755,7 @@ export async function syncCommand(options = {}, runtime = {}) {
732
755
  semanticContracts: evictedSemanticContracts,
733
756
  compilerFingerprint: SYNC_COMPILER_FINGERPRINT,
734
757
  });
735
- console.log("✓ Imported 0 entities, 0 relationships (no changes)");
758
+ info("✓ Imported 0 entities, 0 relationships (no changes)");
736
759
  return withOptionalCommit({
737
760
  branch: currentBranch,
738
761
  timestamp: new Date().toISOString(),
@@ -748,7 +771,7 @@ export async function syncCommand(options = {}, runtime = {}) {
748
771
  const livePath = branchStorePath(workspaceRoot, currentBranch);
749
772
  const kbExists = existsSync(livePath);
750
773
  maybePushKbMissingDiagnostic(diagnostics, kbExists, rebuild, currentBranch, livePath);
751
- // implements REQ-core-journaled-engine-delta-sync
774
+ // implements REQ-core-journaled-engine-persistence
752
775
  // Normal syncs are compiled directly into the long-lived single-writer
753
776
  // engine. Rebuilds retain generation replacement semantics, and injected
754
777
  // Prolog runtimes keep the staging path used by the contract fixtures.
@@ -759,6 +782,9 @@ export async function syncCommand(options = {}, runtime = {}) {
759
782
  workspaceRoot,
760
783
  branch: currentBranch,
761
784
  timeout: 120_000,
785
+ // Compilation reads (source lookups before retracts) must finish;
786
+ // operator read limits are for interactive queries.
787
+ readLimits: null,
762
788
  });
763
789
  const engineProlog = engine;
764
790
  try {
@@ -884,7 +910,7 @@ export async function syncCommand(options = {}, runtime = {}) {
884
910
  entityCount < markdownFiles.length) {
885
911
  diagnostics.push(createDocsNotIndexedDiagnostic(markdownFiles.length, entityCount));
886
912
  }
887
- console.log(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships (removed ${removedCount} entities)`);
913
+ info(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships (removed ${removedCount} entities)`);
888
914
  const commit = getCurrentCommit();
889
915
  const summary = withOptionalCommit({
890
916
  branch: currentBranch,
@@ -896,7 +922,7 @@ export async function syncCommand(options = {}, runtime = {}) {
896
922
  failures: diagnostics,
897
923
  durationMs: Date.now() - startTime,
898
924
  }, commit);
899
- console.log(formatSyncSummary(summary));
925
+ info(formatSyncSummary(summary));
900
926
  return { ...summary, exitCode: 0 };
901
927
  }
902
928
  finally {
@@ -980,7 +1006,7 @@ export async function syncCommand(options = {}, runtime = {}) {
980
1006
  exitCode: 1,
981
1007
  }, getCurrentCommit());
982
1008
  }
983
- console.log(`OK: Validation passed (${entityCount} entities)`);
1009
+ info(`OK: Validation passed (${entityCount} entities)`);
984
1010
  return withOptionalCommit({
985
1011
  branch: currentBranch,
986
1012
  timestamp: new Date().toISOString(),
@@ -1073,7 +1099,7 @@ export async function syncCommand(options = {}, runtime = {}) {
1073
1099
  });
1074
1100
  published = true;
1075
1101
  maybePushDocsNotIndexedDiagnostic(diagnostics, performedFullReindex, markdownFiles.length, entityCount);
1076
- console.log(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships`);
1102
+ info(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships`);
1077
1103
  const commit = getCurrentCommit();
1078
1104
  const summary = withOptionalCommit({
1079
1105
  branch: currentBranch,
@@ -1085,7 +1111,7 @@ export async function syncCommand(options = {}, runtime = {}) {
1085
1111
  failures: diagnostics,
1086
1112
  durationMs: Date.now() - startTime,
1087
1113
  }, commit);
1088
- console.log(formatSyncSummary(summary));
1114
+ info(formatSyncSummary(summary));
1089
1115
  return { ...summary, exitCode: 0 };
1090
1116
  }
1091
1117
  catch (error) {
@@ -1112,9 +1138,9 @@ export async function syncCommand(options = {}, runtime = {}) {
1112
1138
  durationMs: Date.now() - startTime,
1113
1139
  }, commit);
1114
1140
  if (diagnostics.length > 0) {
1115
- console.log("\nDiagnostics:");
1141
+ info("\nDiagnostics:");
1116
1142
  for (const d of diagnostics) {
1117
- console.log(` [${d.category}] ${d.severity}: ${d.message}`);
1143
+ info(` [${d.category}] ${d.severity}: ${d.message}`);
1118
1144
  }
1119
1145
  }
1120
1146
  throw error;