kibi-cli 2.31.1 → 2.35.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 (302) hide show
  1. package/dist/cli-register-proof.d.ts.map +1 -1
  2. package/dist/cli-register-proof.js +19 -7
  3. package/dist/cli-register-reporting.d.ts.map +1 -1
  4. package/dist/cli-register-reporting.js +2 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +5 -1
  7. package/dist/commands/check-generated.d.ts +5 -1
  8. package/dist/commands/check-generated.d.ts.map +1 -1
  9. package/dist/commands/check-generated.js +24 -35
  10. package/dist/commands/check.d.ts +1 -0
  11. package/dist/commands/check.d.ts.map +1 -1
  12. package/dist/commands/check.js +14 -5
  13. package/dist/commands/discovery-table.d.ts.map +1 -1
  14. package/dist/commands/discovery-table.js +51 -4
  15. package/dist/commands/doctor.js +19 -4
  16. package/dist/commands/init-helpers.d.ts.map +1 -1
  17. package/dist/commands/init-helpers.js +8 -5
  18. package/dist/commands/migrate.d.ts.map +1 -1
  19. package/dist/commands/migrate.js +109 -5
  20. package/dist/commands/prove.d.ts +48 -1
  21. package/dist/commands/prove.d.ts.map +1 -1
  22. package/dist/commands/prove.js +293 -8
  23. package/dist/commands/report.d.ts +1 -0
  24. package/dist/commands/report.d.ts.map +1 -1
  25. package/dist/commands/report.js +70 -5
  26. package/dist/commands/signoff.d.ts.map +1 -1
  27. package/dist/commands/signoff.js +20 -1
  28. package/dist/commands/sync/manifest.d.ts +10 -1
  29. package/dist/commands/sync/manifest.d.ts.map +1 -1
  30. package/dist/commands/sync/manifest.js +106 -17
  31. package/dist/commands/sync/persistence.d.ts.map +1 -1
  32. package/dist/commands/sync/persistence.js +16 -5
  33. package/dist/commands/sync.d.ts.map +1 -1
  34. package/dist/commands/sync.js +19 -0
  35. package/dist/diagnostics.js +1 -1
  36. package/dist/engine.js +1 -1
  37. package/dist/extractors/markdown.d.ts +4 -2
  38. package/dist/extractors/markdown.d.ts.map +1 -1
  39. package/dist/extractors/markdown.js +17 -0
  40. package/dist/extractors/symbol-coordinates.js +2 -2
  41. package/dist/extractors/symbols-coordinator.d.ts +2 -4
  42. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  43. package/dist/extractors/symbols-coordinator.js +1 -2
  44. package/dist/operations/bootstrap/candidate-helpers.d.ts +3 -0
  45. package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
  46. package/dist/operations/bootstrap/candidate-helpers.js +4 -0
  47. package/dist/operations/migration/evidence-floor.d.ts +41 -0
  48. package/dist/operations/migration/evidence-floor.d.ts.map +1 -0
  49. package/dist/operations/migration/evidence-floor.js +230 -0
  50. package/dist/operations/migration/proof-contract-claims.d.ts +72 -0
  51. package/dist/operations/migration/proof-contract-claims.d.ts.map +1 -0
  52. package/dist/operations/migration/proof-contract-claims.js +215 -0
  53. package/dist/operations/migration/schema6.d.ts +6 -0
  54. package/dist/operations/migration/schema6.d.ts.map +1 -1
  55. package/dist/operations/migration/schema6.js +92 -0
  56. package/dist/operations/migration/symbol-coordinates-refresh.d.ts +3 -2
  57. package/dist/operations/migration/symbol-coordinates-refresh.d.ts.map +1 -1
  58. package/dist/operations/migration/symbol-coordinates-refresh.js +4 -3
  59. package/dist/operations/migration/untrack-symbol-coordinates.d.ts +23 -0
  60. package/dist/operations/migration/untrack-symbol-coordinates.d.ts.map +1 -0
  61. package/dist/operations/migration/untrack-symbol-coordinates.js +67 -0
  62. package/dist/operations/modeling/requirement-modeler.d.ts.map +1 -1
  63. package/dist/operations/modeling/requirement-modeler.js +48 -1
  64. package/dist/operations/modeling/requirement-types.d.ts +2 -1
  65. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  66. package/dist/operations/modeling/requirement-utils.d.ts +1 -1
  67. package/dist/operations/modeling/requirement-utils.d.ts.map +1 -1
  68. package/dist/operations/modeling/requirement-utils.js +8 -1
  69. package/dist/operations/mutation/omitted-properties.d.ts +11 -0
  70. package/dist/operations/mutation/omitted-properties.d.ts.map +1 -0
  71. package/dist/operations/mutation/omitted-properties.js +76 -0
  72. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  73. package/dist/operations/mutation/serialization.js +1 -0
  74. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  75. package/dist/operations/mutation/source-authoring.js +39 -20
  76. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  77. package/dist/operations/mutation/strict-fact.js +6 -2
  78. package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
  79. package/dist/operations/mutation/symbol-granularity.js +5 -3
  80. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  81. package/dist/operations/mutation/upsert.js +7 -1
  82. package/dist/operations/mutation/validation.d.ts +2 -0
  83. package/dist/operations/mutation/validation.d.ts.map +1 -1
  84. package/dist/operations/mutation/validation.js +4 -0
  85. package/dist/operations/proof/claim-bindings.d.ts +41 -0
  86. package/dist/operations/proof/claim-bindings.d.ts.map +1 -0
  87. package/dist/operations/proof/claim-bindings.js +364 -0
  88. package/dist/operations/proof/code-certificates.d.ts +155 -0
  89. package/dist/operations/proof/code-certificates.d.ts.map +1 -0
  90. package/dist/operations/proof/code-certificates.js +894 -0
  91. package/dist/operations/proof/code-models.d.ts +96 -0
  92. package/dist/operations/proof/code-models.d.ts.map +1 -0
  93. package/dist/operations/proof/code-models.js +601 -0
  94. package/dist/operations/proof/code-runner.d.ts +40 -0
  95. package/dist/operations/proof/code-runner.d.ts.map +1 -0
  96. package/dist/operations/proof/code-runner.js +164 -0
  97. package/dist/operations/proof/code-scope.d.ts +14 -1
  98. package/dist/operations/proof/code-scope.d.ts.map +1 -1
  99. package/dist/operations/proof/code-scope.js +44 -2
  100. package/dist/operations/proof/compact-receipts.d.ts.map +1 -1
  101. package/dist/operations/proof/compact-receipts.js +4 -3
  102. package/dist/operations/proof/explain.d.ts +32 -0
  103. package/dist/operations/proof/explain.d.ts.map +1 -1
  104. package/dist/operations/proof/explain.js +91 -0
  105. package/dist/operations/proof/ingest-proof.d.ts +9 -1
  106. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  107. package/dist/operations/proof/ingest-proof.js +42 -2
  108. package/dist/operations/proof/receipt-compaction.d.ts +2 -0
  109. package/dist/operations/proof/receipt-compaction.d.ts.map +1 -1
  110. package/dist/operations/proof/receipt-compaction.js +6 -2
  111. package/dist/operations/proof/regular-language.d.ts +89 -0
  112. package/dist/operations/proof/regular-language.d.ts.map +1 -0
  113. package/dist/operations/proof/regular-language.js +943 -0
  114. package/dist/operations/proof/source-code-readers.d.ts +12 -0
  115. package/dist/operations/proof/source-code-readers.d.ts.map +1 -0
  116. package/dist/operations/proof/source-code-readers.js +699 -0
  117. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  118. package/dist/operations/semantic-advisor/analyze-prose.js +2 -1
  119. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  120. package/dist/operations/semantic-advisor/shared.js +4 -0
  121. package/dist/operations/semantic-advisor/strict-count-rules.d.ts.map +1 -1
  122. package/dist/operations/semantic-advisor/strict-count-rules.js +8 -2
  123. package/dist/operations/semantic-advisor/strict-rules.d.ts +8 -0
  124. package/dist/operations/semantic-advisor/strict-rules.d.ts.map +1 -1
  125. package/dist/operations/semantic-advisor/strict-rules.js +234 -4
  126. package/dist/operations/semantic-advisor/types.d.ts +3 -2
  127. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  128. package/dist/plugins/approved-source-analyzers.generated.d.ts +6 -6
  129. package/dist/plugins/approved-source-analyzers.generated.js +6 -6
  130. package/dist/prolog.d.ts.map +1 -1
  131. package/dist/prolog.js +13 -3
  132. package/dist/proof/command-test-report.d.ts +4 -3
  133. package/dist/proof/command-test-report.d.ts.map +1 -1
  134. package/dist/proof/command-test-report.js +4 -10
  135. package/dist/proof/evaluate.d.ts.map +1 -1
  136. package/dist/proof/evaluate.js +18 -2
  137. package/dist/proof/inspect.d.ts.map +1 -1
  138. package/dist/proof/inspect.js +58 -0
  139. package/dist/proof/producers/playwright-reporter.d.ts +3 -0
  140. package/dist/proof/producers/playwright-reporter.d.ts.map +1 -1
  141. package/dist/proof/producers/playwright-reporter.js +25 -2
  142. package/dist/proof/step-runner.d.ts +36 -0
  143. package/dist/proof/step-runner.d.ts.map +1 -0
  144. package/dist/proof/step-runner.js +234 -0
  145. package/dist/public/evidence-levels.d.ts +12 -0
  146. package/dist/public/evidence-levels.d.ts.map +1 -0
  147. package/dist/public/evidence-levels.js +19 -0
  148. package/dist/public/impact/coverage-depth-quality.d.ts +7 -0
  149. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
  150. package/dist/public/impact/coverage-depth-quality.js +59 -0
  151. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  152. package/dist/public/impact/full-kb-quality.js +3 -1
  153. package/dist/public/operations/catalog.d.ts +315 -11
  154. package/dist/public/operations/catalog.d.ts.map +1 -1
  155. package/dist/public/operations/check-executor.d.ts +2 -0
  156. package/dist/public/operations/check-executor.d.ts.map +1 -1
  157. package/dist/public/operations/check-executor.js +6 -0
  158. package/dist/public/operations/evidence-floor.d.ts +48 -0
  159. package/dist/public/operations/evidence-floor.d.ts.map +1 -0
  160. package/dist/public/operations/evidence-floor.js +143 -0
  161. package/dist/public/operations/migration-plan.d.ts +19 -5
  162. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  163. package/dist/public/operations/migration-plan.js +22 -5
  164. package/dist/public/operations/node-ports.d.ts.map +1 -1
  165. package/dist/public/operations/node-ports.js +4 -1
  166. package/dist/public/operations/proof-contract-claims.d.ts +26 -0
  167. package/dist/public/operations/proof-contract-claims.d.ts.map +1 -0
  168. package/dist/public/operations/proof-contract-claims.js +71 -0
  169. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  170. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  171. package/dist/public/operations/specs/check-rules.generated.js +3 -1
  172. package/dist/public/operations/specs/check.d.ts +1 -1
  173. package/dist/public/operations/specs/composite.d.ts +16 -3
  174. package/dist/public/operations/specs/composite.d.ts.map +1 -1
  175. package/dist/public/operations/specs/modeling.d.ts +16 -3
  176. package/dist/public/operations/specs/modeling.d.ts.map +1 -1
  177. package/dist/public/operations/specs/modeling.js +22 -3
  178. package/dist/public/operations/specs/mutation-schemas.d.ts +289 -7
  179. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  180. package/dist/public/operations/specs/mutation-schemas.js +28 -4
  181. package/dist/public/operations/specs/proof.d.ts +9 -0
  182. package/dist/public/operations/specs/proof.d.ts.map +1 -1
  183. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  184. package/dist/public/operations/specs/reporting.js +19 -10
  185. package/dist/public/operations/specs/upsert.d.ts +289 -7
  186. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  187. package/dist/public/proof-certificates.d.ts +163 -0
  188. package/dist/public/proof-certificates.d.ts.map +1 -0
  189. package/dist/public/proof-certificates.js +419 -0
  190. package/dist/public/proof-protocol.d.ts +259 -3
  191. package/dist/public/proof-protocol.d.ts.map +1 -1
  192. package/dist/public/proof-protocol.js +524 -3
  193. package/dist/public/proof-receipt.d.ts +90 -6
  194. package/dist/public/proof-receipt.d.ts.map +1 -1
  195. package/dist/public/proof-receipt.js +88 -7
  196. package/dist/public/proof-sources.d.ts +102 -0
  197. package/dist/public/proof-sources.d.ts.map +1 -0
  198. package/dist/public/proof-sources.js +1292 -0
  199. package/dist/public/schemas/entity.d.ts.map +1 -1
  200. package/dist/public/schemas/entity.js +39 -2
  201. package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
  202. package/dist/public/skills/kibi-commit-review/SKILL.md +8 -8
  203. package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +12 -7
  204. package/dist/public/skills/kibi-decisions/SKILL.md +13 -2
  205. package/dist/public/skills/kibi-decisions/resources/decision-records.md +9 -1
  206. package/dist/public/skills/kibi-freshness/SKILL.md +5 -1
  207. package/dist/public/skills/kibi-traceability/SKILL.md +12 -1
  208. package/dist/public/skills/kibi-usage/SKILL.md +8 -4
  209. package/dist/public/skills/kibi-usage/resources/proof.md +221 -20
  210. package/dist/public/skills/kibi-usage/resources/workflows.md +4 -4
  211. package/dist/report/html-report.css +83 -11
  212. package/dist/report/html-report.d.ts +8 -0
  213. package/dist/report/html-report.d.ts.map +1 -1
  214. package/dist/report/html-report.js +214 -22
  215. package/dist/report/report-view.d.ts +2 -2
  216. package/dist/report/report-view.d.ts.map +1 -1
  217. package/dist/report/report-view.js +8 -0
  218. package/dist/schemas/entity.schema.json +404 -5
  219. package/dist/search-answer.d.ts.map +1 -1
  220. package/dist/search-answer.js +1 -0
  221. package/dist/signoff/html.d.ts.map +1 -1
  222. package/dist/signoff/html.js +3 -0
  223. package/dist/signoff/markdown.d.ts.map +1 -1
  224. package/dist/signoff/markdown.js +3 -0
  225. package/dist/signoff/model.d.ts +20 -0
  226. package/dist/signoff/model.d.ts.map +1 -1
  227. package/dist/signoff/model.js +20 -1
  228. package/dist/traceability/evidence-model.d.ts +13 -12
  229. package/dist/traceability/evidence-model.d.ts.map +1 -1
  230. package/dist/traceability/evidence-model.js +1 -1
  231. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  232. package/dist/traceability/impact-knowledge.js +1 -0
  233. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  234. package/dist/traceability/staged-diagnostics.js +24 -20
  235. package/dist/traceability/staged-impact-contract.d.ts +4 -4
  236. package/dist/traceability/staged-impact-contract.js +9 -9
  237. package/dist/traceability/staged-symbols-manifest.d.ts +11 -3
  238. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  239. package/dist/traceability/staged-symbols-manifest.js +47 -140
  240. package/dist/traceability/temp-kb.d.ts.map +1 -1
  241. package/dist/traceability/temp-kb.js +1 -0
  242. package/dist/types/entities.d.ts +5 -2
  243. package/dist/types/entities.d.ts.map +1 -1
  244. package/dist/utils/merge-driver-setup.d.ts +8 -1
  245. package/dist/utils/merge-driver-setup.d.ts.map +1 -1
  246. package/dist/utils/merge-driver-setup.js +23 -2
  247. package/dist/utils/rule-registry.generated.d.ts +10 -0
  248. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  249. package/dist/utils/rule-registry.generated.js +12 -0
  250. package/dist/utils/schema-version.d.ts +1 -1
  251. package/dist/utils/schema-version.d.ts.map +1 -1
  252. package/dist/utils/schema-version.js +7 -1
  253. package/dist/utils/strict-modeling.d.ts +3 -2
  254. package/dist/utils/strict-modeling.d.ts.map +1 -1
  255. package/dist/utils/strict-modeling.js +37 -4
  256. package/dist/workspace-cwd.d.ts +15 -0
  257. package/dist/workspace-cwd.d.ts.map +1 -0
  258. package/dist/workspace-cwd.js +86 -0
  259. package/package.json +6 -2
  260. package/schema/entities.pl +6 -0
  261. package/schema/validation.pl +7 -2
  262. package/src/public/evidence-levels.ts +23 -0
  263. package/src/public/impact/coverage-depth-quality.ts +73 -0
  264. package/src/public/impact/full-kb-quality.ts +6 -1
  265. package/src/public/operations/check-executor.ts +13 -0
  266. package/src/public/operations/evidence-floor.ts +203 -0
  267. package/src/public/operations/migration-plan.ts +39 -6
  268. package/src/public/operations/node-ports.ts +3 -1
  269. package/src/public/operations/proof-contract-claims.ts +103 -0
  270. package/src/public/operations/specs/check-rules.generated.ts +3 -1
  271. package/src/public/operations/specs/modeling.ts +24 -5
  272. package/src/public/operations/specs/mutation-schemas.ts +30 -4
  273. package/src/public/operations/specs/reporting.ts +20 -10
  274. package/src/public/proof-certificates.ts +566 -0
  275. package/src/public/proof-protocol-types.d.ts +69 -1
  276. package/src/public/proof-protocol.ts +694 -3
  277. package/src/public/proof-receipt.ts +133 -7
  278. package/src/public/proof-sources.ts +1656 -0
  279. package/src/public/schemas/entity.ts +51 -3
  280. package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
  281. package/src/public/skills/kibi-commit-review/SKILL.md +8 -8
  282. package/src/public/skills/kibi-commit-review/resources/staged-gate.md +12 -7
  283. package/src/public/skills/kibi-decisions/SKILL.md +13 -2
  284. package/src/public/skills/kibi-decisions/resources/decision-records.md +9 -1
  285. package/src/public/skills/kibi-freshness/SKILL.md +5 -1
  286. package/src/public/skills/kibi-traceability/SKILL.md +12 -1
  287. package/src/public/skills/kibi-usage/SKILL.md +8 -4
  288. package/src/public/skills/kibi-usage/resources/proof.md +221 -20
  289. package/src/public/skills/kibi-usage/resources/workflows.md +4 -4
  290. package/src/schemas/entity.schema.json +404 -5
  291. package/dist/commands/proof-impact.d.ts +0 -7
  292. package/dist/commands/proof-impact.d.ts.map +0 -1
  293. package/dist/commands/proof-impact.js +0 -39
  294. package/dist/operations/proof/baseline-diff.d.ts +0 -41
  295. package/dist/operations/proof/baseline-diff.d.ts.map +0 -1
  296. package/dist/operations/proof/baseline-diff.js +0 -153
  297. package/dist/operations/proof/impact.d.ts +0 -51
  298. package/dist/operations/proof/impact.d.ts.map +0 -1
  299. package/dist/operations/proof/impact.js +0 -138
  300. package/dist/traceability/reviewed-coordinate-refresh.d.ts +0 -10
  301. package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +0 -1
  302. package/dist/traceability/reviewed-coordinate-refresh.js +0 -49
@@ -0,0 +1,164 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { spawnSync } from "node:child_process";
19
+ import { existsSync } from "node:fs";
20
+ import path from "node:path";
21
+ /**
22
+ * How Kibi runs a small evaluator script against the workspace's own code:
23
+ * the TypeScript and JavaScript runners (bun, the workspace's tsx, node with
24
+ * type stripping) and the Python interpreters a project uses. The proof kinds
25
+ * that read a model from the code (exhaustive domains, rule tables, state
26
+ * machines, patterns, data schemas, route tables) all load code this way.
27
+ */
28
+ // Node's type stripping resolves only exact specifiers. TypeScript apps
29
+ // import relative modules without an extension, or with `.js` for a `.ts`
30
+ // file; this resolve hook retries those as the TypeScript files they name.
31
+ export const TS_RESOLVE_HOOKS = `
32
+ const SUFFIXES = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", "/index.ts", "/index.tsx", "/index.js"];
33
+ export async function resolve(specifier, context, next) {
34
+ try {
35
+ return await next(specifier, context);
36
+ } catch (error) {
37
+ if (error?.code !== "ERR_MODULE_NOT_FOUND" || !/^\\.\\.?\\//.test(specifier)) throw error;
38
+ const base = specifier.replace(/\\.[cm]?js$/, "");
39
+ for (const suffix of SUFFIXES) {
40
+ try {
41
+ return await next(base + suffix, context);
42
+ } catch {}
43
+ }
44
+ throw error;
45
+ }
46
+ }
47
+ `;
48
+ export function workspaceBin(workspaceRoot, name) {
49
+ let dir = path.resolve(workspaceRoot);
50
+ for (;;) {
51
+ const candidate = path.join(dir, "node_modules", ".bin", name);
52
+ if (existsSync(candidate))
53
+ return candidate;
54
+ if (path.dirname(dir) === dir)
55
+ return null;
56
+ dir = path.dirname(dir);
57
+ }
58
+ }
59
+ /**
60
+ * The Python interpreters a domain loads with, most specific first: the
61
+ * KIBI_PYTHON override, the active virtualenv, a project virtualenv (`.venv`
62
+ * or `venv`) between the domain file and the workspace root, then python3
63
+ * and python on PATH. The system interpreter usually cannot import the
64
+ * project's dependencies, so a project environment comes before it.
65
+ */
66
+ // implements REQ-kibi-code-proof-kinds
67
+ export function pythonDomainInterpreters(workspaceRoot, sourceFile, env = process.env) {
68
+ const interpreters = [];
69
+ const add = (candidate) => {
70
+ if (candidate && !interpreters.includes(candidate))
71
+ interpreters.push(candidate);
72
+ };
73
+ add(env.KIBI_PYTHON?.trim() || undefined);
74
+ const venvPython = (venv) => [
75
+ path.join(venv, "bin", "python"),
76
+ path.join(venv, "Scripts", "python.exe"),
77
+ ].find((candidate) => existsSync(candidate));
78
+ if (env.VIRTUAL_ENV)
79
+ add(venvPython(env.VIRTUAL_ENV));
80
+ const root = path.resolve(workspaceRoot);
81
+ let dir = path.dirname(path.resolve(root, sourceFile));
82
+ for (;;) {
83
+ for (const name of [".venv", "venv"])
84
+ add(venvPython(path.join(dir, name)));
85
+ if (dir === root || path.dirname(dir) === dir)
86
+ break;
87
+ if (!dir.startsWith(`${root}${path.sep}`))
88
+ break;
89
+ dir = path.dirname(dir);
90
+ }
91
+ add("python3");
92
+ add("python");
93
+ return interpreters;
94
+ }
95
+ /** The line of a runner's stderr that names the failure. */
96
+ function failureLine(stderr, python) {
97
+ const lines = stderr
98
+ .trim()
99
+ .split("\n")
100
+ .map((line) => line.trim())
101
+ .filter((line) => line !== "");
102
+ // A Python traceback names the exception on its last line.
103
+ return (python ? lines.at(-1) : lines[0]) ?? "";
104
+ }
105
+ /**
106
+ * Run an evaluator script against the workspace code and return the JSON it
107
+ * prints last. A TypeScript or JavaScript file runs with bun when it is on
108
+ * PATH, else the workspace's tsx, else node's type stripping (which retries
109
+ * extensionless relative imports as TypeScript files); a Python file (`.py`)
110
+ * runs with the first interpreter pythonDomainInterpreters finds. A runner
111
+ * whose output `accept` rejects (or that fails to start) yields to the next.
112
+ */
113
+ // implements REQ-kibi-non-numeric-proof-kinds
114
+ export function runCodeEvaluator(workspaceRoot, sourceFile, scripts, args, accept = () => true, options = {}) {
115
+ const python = /\.py$/i.test(sourceFile);
116
+ const tsx = python ? null : workspaceBin(workspaceRoot, "tsx");
117
+ const runners = python
118
+ ? pythonDomainInterpreters(workspaceRoot, sourceFile).map((interpreter) => [
119
+ interpreter,
120
+ ["-c", scripts.python],
121
+ ])
122
+ : (options.runners ?? ["bun", "tsx", "node"]).flatMap((runner) => {
123
+ if (runner === "bun")
124
+ return [["bun", ["-e", scripts.js]]];
125
+ if (runner === "tsx")
126
+ return tsx === null
127
+ ? []
128
+ : [[tsx, ["--eval", scripts.js, "--"]]];
129
+ return [
130
+ [
131
+ process.execPath,
132
+ [
133
+ "--experimental-strip-types",
134
+ "--no-warnings",
135
+ "--input-type=module",
136
+ "-e",
137
+ scripts.js,
138
+ ],
139
+ ],
140
+ ];
141
+ });
142
+ let failure = "";
143
+ for (const [command, argv] of runners) {
144
+ const run = spawnSync(command, [...argv, ...args], {
145
+ cwd: workspaceRoot,
146
+ encoding: "utf8",
147
+ timeout: 60_000,
148
+ maxBuffer: 64 * 1024 * 1024,
149
+ });
150
+ if (run.error)
151
+ continue;
152
+ const line = (run.stdout ?? "").trim().split("\n").pop() ?? "";
153
+ try {
154
+ const parsed = JSON.parse(line);
155
+ if (accept(parsed))
156
+ return { ok: true, value: parsed, python };
157
+ }
158
+ catch {
159
+ // Fall through to the next runner.
160
+ }
161
+ failure = failureLine(run.stderr ?? "", python);
162
+ }
163
+ return { ok: false, failure, python };
164
+ }
@@ -1,5 +1,6 @@
1
1
  import type { PrologPort } from "../../public/operations/runtime-types.js";
2
- import type { ProofContract } from "../../public/proof-protocol.js";
2
+ import { type SourceSpec } from "../../public/proof-sources.js";
3
+ import { type ProofContract } from "../../public/proof-protocol.js";
3
4
  /**
4
5
  * Which symbols a proof receipt's per-contract binding covers. Receipt ingest
5
6
  * (which writes `binding_hash`) and coverage (which checks it) must derive
@@ -22,6 +23,8 @@ export declare function loadCoveredBySymbolsByTest(prolog: Pick<PrologPort, "que
22
23
  * make every receipt of that test silently fall back to snapshot matching.
23
24
  */
24
25
  export declare function receiptBindingContract(raw: unknown): ProofContract | null;
26
+ /** Every project source a contract reads: its source, source counts and source domains. */
27
+ export declare function contractSources(contract: ProofContract): SourceSpec[];
25
28
  export type ReceiptBindingInput = Readonly<{
26
29
  workspaceRoot: string;
27
30
  readFile: (absolutePath: string) => Promise<string>;
@@ -42,4 +45,14 @@ export type ReceiptBindingInput = Readonly<{
42
45
  * therefore carry the same binding.
43
46
  */
44
47
  export declare function currentReceiptBindingHash(input: ReceiptBindingInput): Promise<string | undefined>;
48
+ /**
49
+ * The binding hashes a receipt of this test may carry and still be current:
50
+ * the current hash first, then the hash Kibi wrote before relationship links
51
+ * left the binding (when it differs). The test document is hashed without
52
+ * `proof_receipts` and without `links`: links to scenarios or requirements
53
+ * change what the test is evidence for, not what the code does, so editing
54
+ * them never stales a receipt. Receipts written under the earlier binding
55
+ * stay current until the test's own inputs change.
56
+ */
57
+ export declare function currentReceiptBindingHashes(input: ReceiptBindingInput): Promise<readonly string[] | undefined>;
45
58
  //# sourceMappingURL=code-scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-scope.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-scope.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAKpE;;;;;;;;;;;GAWG;AAEH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,MAAM,EAAE,CAoBV;AAED,4EAA4E;AAE5E,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAiBjD;AAQD;;;;;GAKG;AAEH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAkBzE;AAGD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AAEH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuB7B"}
1
+ {"version":3,"file":"code-scope.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/code-scope.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAAE,KAAK,UAAU,EAAsB,MAAM,+BAA+B,CAAC;AACpF,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,gCAAgC,CAAC;AAKxC;;;;;;;;;;;GAWG;AAEH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,EACjB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,MAAM,EAAE,CAoBV;AAED,4EAA4E;AAE5E,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAiBjD;AAQD;;;;;GAKG;AAEH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAmBzE;AAED,2FAA2F;AAE3F,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,EAAE,CAQrE;AAGD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AAEH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE7B;AAED;;;;;;;;GAQG;AAEH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAuCxC"}
@@ -11,6 +11,8 @@ import { join } from "node:path";
11
11
  import { resolveBoundSymbolScope } from "../../extractors/manifest.js";
12
12
  import { normalizeEntityId, parseTriples } from "../../prolog/codec.js";
13
13
  import { receiptBindingHash } from "../../public/proof-fingerprint.js";
14
+ import { sourceDependencies } from "../../public/proof-sources.js";
15
+ import { optionalProofContractFields, } from "../../public/proof-protocol.js";
14
16
  import { normalizeRepoRelativePath } from "../../utils/repo-relative-path.js";
15
17
  import { resolveContainedSourcePath } from "../mutation/source-authoring.js";
16
18
  import { removeFrontmatterBlock } from "./receipt-document.js";
@@ -94,8 +96,23 @@ export function receiptBindingContract(raw) {
94
96
  };
95
97
  }),
96
98
  success_policy: contract.success_policy,
99
+ ...optionalProofContractFields(contract),
97
100
  };
98
101
  }
102
+ /** Every project source a contract reads: its source, source counts and source domains. */
103
+ // implements REQ-kibi-source-proof-kinds
104
+ export function contractSources(contract) {
105
+ const specs = [];
106
+ if (contract.source !== undefined)
107
+ specs.push(contract.source);
108
+ for (const entry of contract.value_source ?? [])
109
+ if ("source" in entry)
110
+ specs.push(entry.source);
111
+ for (const entry of Object.values(contract.domains ?? {}))
112
+ if ("source" in entry)
113
+ specs.push(entry.source);
114
+ return specs;
115
+ }
99
116
  /**
100
117
  * The current per-contract binding hash of one proof-bearing test, or
101
118
  * undefined when the test has no markdown source the binding can hash.
@@ -110,6 +127,19 @@ export function receiptBindingContract(raw) {
110
127
  */
111
128
  // implements REQ-kibi-fresh-verification-receipts-v2
112
129
  export async function currentReceiptBindingHash(input) {
130
+ return (await currentReceiptBindingHashes(input))?.[0];
131
+ }
132
+ /**
133
+ * The binding hashes a receipt of this test may carry and still be current:
134
+ * the current hash first, then the hash Kibi wrote before relationship links
135
+ * left the binding (when it differs). The test document is hashed without
136
+ * `proof_receipts` and without `links`: links to scenarios or requirements
137
+ * change what the test is evidence for, not what the code does, so editing
138
+ * them never stales a receipt. Receipts written under the earlier binding
139
+ * stay current until the test's own inputs change.
140
+ */
141
+ // implements REQ-kibi-fresh-verification-receipts-v2
142
+ export async function currentReceiptBindingHashes(input) {
113
143
  const contract = receiptBindingContract(input.test.proof_contract);
114
144
  if (!contract)
115
145
  return undefined;
@@ -122,9 +152,21 @@ export async function currentReceiptBindingHash(input) {
122
152
  try {
123
153
  const absolute = resolveContainedSourcePath(input.workspaceRoot, relative);
124
154
  const authored = await input.readFile(absolute);
125
- const stripped = removeFrontmatterBlock(authored, "proof_receipts");
155
+ const withoutReceipts = removeFrontmatterBlock(authored, "proof_receipts") ?? authored;
156
+ const withoutLinks = removeFrontmatterBlock(withoutReceipts, "links") ?? withoutReceipts;
126
157
  const codeScope = resolveBoundSymbolScope(join(input.workspaceRoot, ".kb", "symbols.yaml"), receiptCodeScopeSymbolIds(contract, input.test.proof_bindings, input.coveredBySymbols));
127
- return receiptBindingHash(contract, stripped ?? authored, codeScope);
158
+ // A contract that reads project sources stales when what it reads
159
+ // changes: each file's contents and the set of files a glob matches.
160
+ const scope = [
161
+ ...codeScope,
162
+ ...contractSources(contract).flatMap((spec) => sourceDependencies(input.workspaceRoot, spec).map((dependency) => ({
163
+ symbolId: dependency.id,
164
+ sourceHash: dependency.hash,
165
+ }))),
166
+ ];
167
+ const current = receiptBindingHash(contract, withoutLinks, scope);
168
+ const legacy = receiptBindingHash(contract, withoutReceipts, scope);
169
+ return legacy === current ? [current] : [current, legacy];
128
170
  }
129
171
  catch {
130
172
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"compact-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/compact-receipts.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAUjF,OAAO,EACL,+BAA+B,EAGhC,MAAM,yBAAyB,CAAC;AAIjC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAGH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,OAAO,+BAA+B,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC5C,OAAO,EAAE,SAAS,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CAClE,CAAC,CAAC;AAWH;;;;;;GAMG;AAEH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,YAAY,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,EAC1D,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;;GAOG;AAEH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CA+FD"}
1
+ {"version":3,"file":"compact-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/compact-receipts.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAUjF,OAAO,EACL,+BAA+B,EAGhC,MAAM,yBAAyB,CAAC;AAIjC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAGH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,OAAO,+BAA+B,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC5C,OAAO,EAAE,SAAS,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;CAClE,CAAC,CAAC;AAWH;;;;;;GAMG;AAEH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,YAAY,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,EAC1D,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;;;;GAOG;AAEH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAiGD"}
@@ -21,7 +21,7 @@ import { proofReceiptHistoryErrors } from "../../public/proof-receipt.js";
21
21
  import { projectEntityProperties } from "../mutation/entity-projection.js";
22
22
  import { resolveContainedSourcePath } from "../mutation/source-authoring.js";
23
23
  import { executeUpsert } from "../mutation/upsert.js";
24
- import { currentReceiptBindingHash, loadCoveredBySymbolsByTest, } from "./code-scope.js";
24
+ import { currentReceiptBindingHashes, loadCoveredBySymbolsByTest, } from "./code-scope.js";
25
25
  import { PROOF_RECEIPT_COMPACTION_POLICY, compactProofReceipts, isOrderedReceiptSubsequence, } from "./receipt-compaction.js";
26
26
  import { patchReceiptsIntoDocument } from "./receipt-document.js";
27
27
  function receiptRecords(value) {
@@ -109,15 +109,16 @@ export async function executeCompactReceipts(args, context) {
109
109
  });
110
110
  continue;
111
111
  }
112
- const bindingHash = await currentReceiptBindingHash({
112
+ const [bindingHash, ...legacyBindingHashes] = (await currentReceiptBindingHashes({
113
113
  workspaceRoot: context.workspaceRoot,
114
114
  readFile: (absolute) => fs.readFile(absolute),
115
115
  test,
116
116
  coveredBySymbols: coveredBy.get(testId) ?? [],
117
- });
117
+ })) ?? [];
118
118
  const { kept, removed } = compactProofReceipts(receipts, {
119
119
  codeSnapshot: snapshot,
120
120
  ...(bindingHash === undefined ? {} : { bindingHash }),
121
+ ...(legacyBindingHashes.length > 0 ? { legacyBindingHashes } : {}),
121
122
  });
122
123
  if (removed === 0)
123
124
  continue;
@@ -30,12 +30,44 @@ export type ProofExplainSymbolBlock = {
30
30
  readonly reasonText?: string;
31
31
  readonly coverageCandidates: readonly ProofCoverageCandidate[];
32
32
  };
33
+ export type ClaimSummary = Readonly<{
34
+ applicable: number;
35
+ proved: number;
36
+ attested: number;
37
+ tested: number;
38
+ unresolved: number;
39
+ }>;
40
+ export type ClaimExplainEntry = Readonly<{
41
+ claimKey: string;
42
+ status: string;
43
+ applicable: boolean;
44
+ level: string | null;
45
+ blocker?: string;
46
+ bindings: readonly Readonly<{
47
+ test: string;
48
+ kind: string;
49
+ binding: string;
50
+ scope: string;
51
+ reason?: string;
52
+ }>[];
53
+ }>;
33
54
  export type RequirementProofExplainView = {
34
55
  readonly kind: "requirement";
35
56
  readonly id: string;
36
57
  readonly proofVersion: string;
37
58
  readonly proofStatus: string;
38
59
  readonly proofGaps: readonly string[];
60
+ readonly evidenceLevel?: string;
61
+ /** Tests whose receipt claimed proved but whose certificate no longer re-checks. */
62
+ readonly certificateRejections?: readonly {
63
+ test: string;
64
+ reason: string;
65
+ }[];
66
+ /** How many applicable claims reach each level, and which are not proved. */
67
+ readonly claimSummary?: ClaimSummary;
68
+ readonly unprovedClaims?: readonly string[];
69
+ /** One entry per inventory claim, with the certificate bindings behind it. */
70
+ readonly claims?: readonly ClaimExplainEntry[];
39
71
  readonly scenarios: readonly {
40
72
  id: string;
41
73
  tests: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/explain.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,0CAA0C,CAAC;AAQlD,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,QAAQ,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvD,QAAQ,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IACxE,QAAQ,CAAC,KAAK,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACjD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,2BAA2B,EAAE,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACxB,2BAA2B,GAC3B,sBAAsB,CAAC;AA8E3B,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,2BAA2B,CAsE7B;AAGD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,sBAAsB,CAcxB;AAGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAGjE;AAgGD,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,OAAO,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAcxC;AAwBD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAC9C,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAmBvE"}
1
+ {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/explain.ts"],"names":[],"mappings":"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"}
@@ -134,12 +134,98 @@ export function projectRequirementExplain(proof) {
134
134
  proofVersion: asString(proof.proofVersion),
135
135
  proofStatus: asString(proof.proofStatus),
136
136
  proofGaps: asStringArray(proof.proofGaps),
137
+ ...(typeof proof.evidenceLevel === "string"
138
+ ? { evidenceLevel: proof.evidenceLevel }
139
+ : {}),
140
+ ...(Array.isArray(proof.certificateRejections)
141
+ ? {
142
+ certificateRejections: proof.certificateRejections.map((row) => {
143
+ const entry = asRecord(row);
144
+ return {
145
+ test: asString(entry.test),
146
+ reason: asString(entry.reason),
147
+ };
148
+ }),
149
+ }
150
+ : {}),
151
+ ...claimFields(proof),
137
152
  scenarios,
138
153
  tests,
139
154
  productionSymbols: explanations.filter((item) => !structuralIds.has(item.symbolId)),
140
155
  structuralSymbols: explanations.filter((item) => structuralIds.has(item.symbolId)),
141
156
  };
142
157
  }
158
+ function claimFields(proof) {
159
+ const summary = asRecord(proof.claimSummary);
160
+ const count = (key) => typeof summary[key] === "number" ? summary[key] : 0;
161
+ return {
162
+ ...(proof.claimSummary !== undefined
163
+ ? {
164
+ claimSummary: {
165
+ applicable: count("applicable"),
166
+ proved: count("proved"),
167
+ attested: count("attested"),
168
+ tested: count("tested"),
169
+ unresolved: count("unresolved"),
170
+ },
171
+ }
172
+ : {}),
173
+ ...(Array.isArray(proof.unprovedClaims)
174
+ ? { unprovedClaims: asStringArray(proof.unprovedClaims) }
175
+ : {}),
176
+ ...(Array.isArray(proof.claimEvidence)
177
+ ? {
178
+ claims: proof.claimEvidence.map((item) => {
179
+ const entry = asRecord(item);
180
+ return {
181
+ claimKey: asString(entry.claimKey),
182
+ status: asString(entry.status),
183
+ applicable: asBoolean(entry.applicable),
184
+ level: typeof entry.level === "string" ? entry.level : null,
185
+ ...(typeof entry.blocker === "string"
186
+ ? { blocker: entry.blocker }
187
+ : {}),
188
+ bindings: (Array.isArray(entry.bindings)
189
+ ? entry.bindings
190
+ : []).map((raw) => {
191
+ const binding = asRecord(raw);
192
+ return {
193
+ test: asString(binding.test),
194
+ kind: asString(binding.kind),
195
+ binding: asString(binding.binding),
196
+ scope: asString(binding.scope),
197
+ ...(typeof binding.reason === "string"
198
+ ? { reason: binding.reason }
199
+ : {}),
200
+ };
201
+ }),
202
+ };
203
+ }),
204
+ }
205
+ : {}),
206
+ };
207
+ }
208
+ function renderClaims(view) {
209
+ if (view.claims === undefined)
210
+ return [];
211
+ const summary = view.claimSummary;
212
+ const lines = [
213
+ "",
214
+ summary === undefined
215
+ ? "Claims"
216
+ : `Claims (${summary.proved}/${summary.applicable} proved, ${summary.attested} attested, ${summary.tested} tested, ${summary.unresolved} unresolved)`,
217
+ ];
218
+ if (view.claims.length === 0)
219
+ lines.push(" (none)");
220
+ for (const claim of view.claims) {
221
+ lines.push(claim.applicable
222
+ ? ` ${claim.claimKey} ${claim.level ?? "unverified"} (${claim.status})${claim.blocker ? ` blocked by ${claim.blocker}` : ""}`
223
+ : ` ${claim.claimKey} not applicable (${claim.status})`);
224
+ for (const binding of claim.bindings)
225
+ lines.push(` ${binding.test} ${binding.kind}: ${binding.binding}${binding.binding === "derived" ? ` (${binding.scope})` : ""}${binding.reason ? `: ${binding.reason}` : ""}`);
226
+ }
227
+ return lines;
228
+ }
143
229
  // implements REQ-kibi-verification-evidence-contract
144
230
  export function projectSymbolExplain(payload) {
145
231
  const proofs = Array.isArray(payload.proofs)
@@ -168,6 +254,11 @@ function renderRequirementExplain(view) {
168
254
  `proofVersion: ${view.proofVersion}`,
169
255
  `proofStatus: ${view.proofStatus}`,
170
256
  `proofGaps: ${view.proofGaps.join(", ") || "(none)"}`,
257
+ ...(view.evidenceLevel === undefined
258
+ ? []
259
+ : [`evidenceLevel: ${view.evidenceLevel}`]),
260
+ ...(view.certificateRejections ?? []).map((row) => `certificate rejected for ${row.test}: ${row.reason}`),
261
+ ...renderClaims(view),
171
262
  "",
172
263
  "Scenarios",
173
264
  ];
@@ -1,6 +1,6 @@
1
1
  import { type ProofGap } from "../../proof/evaluate.js";
2
2
  import type { OperationContext } from "../../public/operations/runtime-types.js";
3
- import { type ProofReceipt } from "../../public/proof-receipt.js";
3
+ import { type ClaimBinding, type ProofReceipt } from "../../public/proof-receipt.js";
4
4
  export type IngestProofArgs = Readonly<{
5
5
  snapshot: string;
6
6
  artifact: Readonly<Record<string, unknown>>;
@@ -16,6 +16,14 @@ export type IngestProofTestResult = Readonly<{
16
16
  /** Superseded receipts the ingest compaction dropped from the history. */
17
17
  compacted: number;
18
18
  gaps: readonly ProofGap[];
19
+ /** How the receipt's certificate binds to each claim its contract names. */
20
+ claimBindings?: readonly ClaimBinding[];
21
+ /** The contract's proof kind (e2e when the contract names none). */
22
+ kind?: string;
23
+ /** The evidence level the receipt supports: proved or tested. */
24
+ evidenceLevel?: string;
25
+ /** Why the test's certificate did not re-check, for a certificate kind. */
26
+ certificateRejection?: string;
19
27
  }>;
20
28
  export type IngestProofResult = Readonly<{
21
29
  artifactDigest: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ingest-proof.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/ingest-proof.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,QAAQ,EAEd,MAAM,yBAAyB,CAAC;AAOjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAiBjF,OAAO,EAEL,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAkBvC,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC3B,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC3C,CAAC,CAAC;AAEH,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,iBAAiB,CAAC;CACtC,CAAC;AAolBF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAuC5B"}
1
+ {"version":3,"file":"ingest-proof.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/ingest-proof.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,QAAQ,EAEd,MAAM,yBAAyB,CAAC;AAOjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAkBjF,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAoBvC,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC1B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC3C,CAAC,CAAC;AAEH,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,iBAAiB,CAAC;CACtC,CAAC;AA8nBF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAuC5B"}
@@ -5,7 +5,7 @@ import { loadProofIntegrations, resolveIntegration, toExecution, } from "../../p
5
5
  import { loadEntities } from "../../public/operations/discovery-entities.js";
6
6
  import { readWorkspaceSnapshot } from "../../public/operations/workspace-snapshot.js";
7
7
  import { environmentHash as canonicalEnvironmentHash, effectiveProofFingerprint, jsonDigest, proofContractHash, } from "../../public/proof-fingerprint.js";
8
- import { PROOF_CONTRACT_VERSION, PROOF_RECEIPT_VERSION, proofBindingsErrors, proofRunArtifactErrors, } from "../../public/proof-protocol.js";
8
+ import { PROOF_CONTRACT_VERSION, PROOF_RECEIPT_VERSION, optionalProofContractFields, proofBindingsErrors, proofRunArtifactErrors, } from "../../public/proof-protocol.js";
9
9
  import { MAX_PROOF_RECEIPTS, proofReceiptCurrentBindingErrors, proofReceiptHistoryErrors, } from "../../public/proof-receipt.js";
10
10
  import { projectEntityProperties } from "../mutation/entity-projection.js";
11
11
  import { resolveContainedSourcePath } from "../mutation/source-authoring.js";
@@ -14,6 +14,8 @@ import { executeUpsert } from "../mutation/upsert.js";
14
14
  import { acquireWorkspaceMutationLock, releaseWorkspaceMutationLock, } from "../mutation/workspace-mutation-lock.js";
15
15
  import { MutationRollbackFailureError } from "../mutation/saga.js";
16
16
  import { patchReceiptsIntoDocument } from "./receipt-document.js";
17
+ import { judgeClaimBindings, receiptEvidenceLevel } from "./claim-bindings.js";
18
+ import { checkCodeCertificate } from "./code-certificates.js";
17
19
  async function rollbackUncommittedReceipts(pending, originalError, lifecycle) {
18
20
  const failures = [];
19
21
  for (const entry of pending) {
@@ -66,6 +68,7 @@ function parseContract(test) {
66
68
  })
67
69
  : [],
68
70
  success_policy: success_policy,
71
+ ...optionalProofContractFields(candidate),
69
72
  };
70
73
  if (!contract || contract.version !== PROOF_CONTRACT_VERSION)
71
74
  throw new Error(`Proof ingest failed: test ${String(test.id)} has no proof_contract (${PROOF_CONTRACT_VERSION})`);
@@ -253,6 +256,18 @@ async function executeIngestProofUnlocked(args, context, lifecycle) {
253
256
  test,
254
257
  coveredBySymbols: coveredBy.get(testId) ?? [],
255
258
  });
259
+ const verdict = await checkCodeCertificate(context, {
260
+ testId,
261
+ contract,
262
+ outcome: evaluation.outcome,
263
+ certificate: (artifact.certificates ?? []).find((entry) => entry.test_id === testId),
264
+ });
265
+ const claimBindings = await judgeClaimBindings(context, {
266
+ testId,
267
+ contract,
268
+ verdict,
269
+ coveredBySymbols: coveredBy.get(testId) ?? [],
270
+ });
256
271
  const receipt = {
257
272
  version: PROOF_RECEIPT_VERSION,
258
273
  receipt_id: `PR-${jsonDigest({
@@ -281,6 +296,9 @@ async function executeIngestProofUnlocked(args, context, lifecycle) {
281
296
  ...result,
282
297
  })),
283
298
  ...(evaluation.gaps.length > 0 ? { gaps: evaluation.gaps } : {}),
299
+ ...verdict,
300
+ evidence_level: receiptEvidenceLevel(verdict.evidence_level, claimBindings),
301
+ ...(claimBindings !== undefined ? { claim_bindings: claimBindings } : {}),
284
302
  };
285
303
  prepared.push({
286
304
  testId,
@@ -292,6 +310,26 @@ async function executeIngestProofUnlocked(args, context, lifecycle) {
292
310
  });
293
311
  }
294
312
  const results = [];
313
+ // implements REQ-kibi-code-proof-kinds
314
+ // What each receipt says about its proof kind, evidence level, certificate
315
+ // and claim bindings, so the caller sees a rejected certificate at ingest.
316
+ const bindingsOf = new Map(prepared.map((entry) => [
317
+ entry.testId,
318
+ {
319
+ ...(entry.receipt.claim_bindings === undefined
320
+ ? {}
321
+ : { claimBindings: entry.receipt.claim_bindings }),
322
+ ...(typeof entry.receipt.kind === "string"
323
+ ? { kind: entry.receipt.kind }
324
+ : {}),
325
+ ...(typeof entry.receipt.evidence_level === "string"
326
+ ? { evidenceLevel: entry.receipt.evidence_level }
327
+ : {}),
328
+ ...(typeof entry.receipt.certificate_rejection === "string"
329
+ ? { certificateRejection: entry.receipt.certificate_rejection }
330
+ : {}),
331
+ },
332
+ ]));
295
333
  const pendingCommits = [];
296
334
  let passed = 0;
297
335
  let failed = 0;
@@ -316,6 +354,7 @@ async function executeIngestProofUnlocked(args, context, lifecycle) {
316
354
  receiptCount: existing.length,
317
355
  compacted: 0,
318
356
  gaps: evaluation.gaps,
357
+ ...bindingsOf.get(testId),
319
358
  });
320
359
  continue;
321
360
  }
@@ -448,11 +487,12 @@ async function executeIngestProofUnlocked(args, context, lifecycle) {
448
487
  receiptCount: entry.receiptCount,
449
488
  compacted: entry.compacted,
450
489
  gaps: entry.gaps,
490
+ ...bindingsOf.get(entry.testId),
451
491
  });
452
492
  }
453
493
  }
454
494
  const summary = passed > 0
455
- ? `Proved ${passed} test(s)${failed > 0 ? `, ${failed} failed` : ""}${unchanged > 0 ? `, ${unchanged} unchanged` : ""}.`
495
+ ? `Passed ${passed} test(s)${failed > 0 ? `, ${failed} failed` : ""}${unchanged > 0 ? `, ${unchanged} unchanged` : ""}.`
456
496
  : `No passing proof: ${failed} failed, ${unchanged} unchanged.`;
457
497
  return {
458
498
  content: [{ type: "text", text: `Ingested proof evidence. ${summary}` }],
@@ -7,6 +7,8 @@ export declare const PROOF_RECEIPT_COMPACTION_POLICY: "kibi.proof-receipt-compac
7
7
  export type ReceiptCompactionAnchor = Readonly<{
8
8
  codeSnapshot?: string;
9
9
  bindingHash?: string;
10
+ /** Earlier binding hashes a current receipt may still carry. */
11
+ legacyBindingHashes?: readonly string[];
10
12
  }>;
11
13
  export type ReceiptCompaction = Readonly<{
12
14
  kept: readonly Readonly<Record<string, unknown>>[];
@@ -1 +1 @@
1
- {"version":3,"file":"receipt-compaction.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/receipt-compaction.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,+BAA+B,EAC1C,kCAA2C,CAAC;AAE9C;;;;GAIG;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,KAAK,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuBjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,EAAE,uBAAuB,GAC9B,iBAAiB,CA0CnB;AAED;;;;GAIG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,OAAO,CAcT"}
1
+ {"version":3,"file":"receipt-compaction.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/receipt-compaction.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,+BAA+B,EAC1C,kCAA2C,CAAC;AAE9C;;;;GAIG;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,KAAK,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuBjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,EAAE,uBAAuB,GAC9B,iBAAiB,CA6CnB;AAED;;;;GAIG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,OAAO,CAcT"}