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
@@ -143,6 +143,8 @@ function implementationOwned(stages) {
143
143
  return productionSymbols.every((symbol) => !missingCoordinates.has(symbol));
144
144
  }
145
145
  function passesProofGate(row, gate) {
146
+ if (gate === "proved")
147
+ return row.evidenceLevel === "proved";
146
148
  if (row.proofStatus === "tested")
147
149
  return true;
148
150
  const stages = record(row.proofStages);
@@ -174,10 +176,16 @@ function proofGates(rows) {
174
176
  "Production ownership is source-bound",
175
177
  ],
176
178
  ["e2e", "E2E", "A scenario-backed end-to-end test exists"],
177
- ["evidence", "Evidence", "Every strict proof stage passes now"],
179
+ ["evidence", "Tested", "Fresh passing receipts cover every scenario"],
180
+ ["proved", "Proved", "Every claim has a re-checked certificate"],
178
181
  ];
182
+ const claims = claimTotals(rows);
183
+ const claimDetail = claims.applicable === 0
184
+ ? ""
185
+ : ` · ${claims.proved.toLocaleString("en-US")} of ${claims.applicable.toLocaleString("en-US")} claims proved`;
179
186
  let candidates = [...rows];
180
- return definitions.map(([key, label, detail]) => {
187
+ return definitions.map(([key, label, baseDetail]) => {
188
+ const detail = key === "proved" ? `${baseDetail}${claimDetail}` : baseDetail;
181
189
  const remainingRows = candidates.filter((row) => passesProofGate(row, key));
182
190
  const gate = {
183
191
  key,
@@ -206,6 +214,25 @@ export function earliestUnmetGate(row) {
206
214
  return "tested";
207
215
  return firstFailingProofGate(["semantic", "scenario", "implementation", "e2e", "evidence"], (gate) => passesProofGate(row, gate));
208
216
  }
217
+ // The rail's last step: a tested requirement still short of a certificate
218
+ // for every claim stops at "proved". Signoff keeps earliestUnmetGate, where
219
+ // tested is the end of the strict chain.
220
+ function reportGate(row) {
221
+ const gate = earliestUnmetGate(row);
222
+ if (gate !== "tested")
223
+ return gate;
224
+ return passesProofGate(row, "proved") ? "tested" : "proved";
225
+ }
226
+ function claimTotals(rows) {
227
+ let proved = 0;
228
+ let applicable = 0;
229
+ for (const row of rows) {
230
+ const claims = record(row.claimSummary);
231
+ proved += count(claims.proved);
232
+ applicable += count(claims.applicable);
233
+ }
234
+ return { proved, applicable };
235
+ }
209
236
  function evidenceStage(passingE2e, testSources, repository) {
210
237
  const evidence = records(passingE2e.receiptEvidence);
211
238
  const passed = evidence.find((item) => item.state === "passed");
@@ -285,6 +312,7 @@ function requirementStages(row, repository) {
285
312
  const testSources = sourceCoordinates(record(stages.scenarioTests).sources);
286
313
  const productionSources = sourceCoordinates(productionSymbols.coordinates);
287
314
  const executableSources = sourceCoordinates(executableSymbols.coordinates);
315
+ const certificate = certificateStage(row);
288
316
  let implementationState = "failed";
289
317
  let implementationDetail = "No production symbol ownership";
290
318
  if (stageStatus(productionSymbols) === "passed" &&
@@ -342,6 +370,7 @@ function requirementStages(row, repository) {
342
370
  state: e2eState,
343
371
  },
344
372
  evidenceStage(passingE2e, testSources, repository),
373
+ ...(certificate === undefined ? [] : [certificate]),
345
374
  ];
346
375
  }
347
376
  function renderStage(stage) {
@@ -395,16 +424,36 @@ function renderContradiction(conflict) {
395
424
  <p>${escapeHtml(text(conflict.reason, "Two current requirements encode incompatible claims."))}</p>
396
425
  </div>`;
397
426
  }
427
+ /**
428
+ * The requirement's evidence floor, when it has one: required_evidence, or
429
+ * tested for a firm requirement. A floor of unverified accepts anything and
430
+ * reads as no floor.
431
+ */
432
+ // implements REQ-kibi-evidence-floors
433
+ function evidenceFloor(row) {
434
+ const floor = record(row.evidenceFloor);
435
+ const required = text(floor.required);
436
+ if (!required || required === "unverified")
437
+ return undefined;
438
+ return {
439
+ required,
440
+ source: text(floor.source, "explicit"),
441
+ status: text(floor.status, "below"),
442
+ };
443
+ }
398
444
  function rowSeverity(row) {
399
445
  const gaps = strings(row.proofGaps);
400
446
  if (gaps.includes("blocking_contradiction"))
401
447
  return 0;
402
- if (gaps.includes("stale_proof_receipt"))
448
+ if (evidenceFloor(row)?.status === "below")
403
449
  return 1;
404
- if (row.proofStatus !== "tested")
450
+ if (gaps.includes("stale_proof_receipt"))
405
451
  return 2;
406
- return 3;
452
+ if (row.proofStatus !== "tested")
453
+ return 3;
454
+ return 4;
407
455
  }
456
+ // implements REQ-kibi-html-health-report, REQ-kibi-evidence-floors
408
457
  function rowStates(row) {
409
458
  const states = new Set();
410
459
  const gaps = strings(row.proofGaps);
@@ -412,18 +461,95 @@ function rowStates(row) {
412
461
  states.add("tested");
413
462
  else
414
463
  states.add("attention");
464
+ if (row.evidenceLevel === "proved")
465
+ states.add("proved");
466
+ const floorStatus = evidenceFloor(row)?.status;
467
+ if (floorStatus === "below")
468
+ states.add("below_floor");
469
+ if (floorStatus === "pending_reproof")
470
+ states.add("pending_reproof");
415
471
  if (gaps.includes("stale_proof_receipt"))
416
472
  states.add("stale");
417
473
  if (gaps.includes("blocking_contradiction"))
418
474
  states.add("contradiction");
419
475
  return [...states].join(" ");
420
476
  }
477
+ const FLOOR_STATUS_LABELS = {
478
+ met: "met",
479
+ below: "below",
480
+ pending_reproof: "pending re-proof",
481
+ };
482
+ // implements REQ-kibi-evidence-floors
483
+ function renderFloorChip(floor) {
484
+ if (floor === undefined)
485
+ return "";
486
+ const origin = floor.source === "firmness"
487
+ ? "the default floor for a firm requirement"
488
+ : "set by required_evidence";
489
+ const status = FLOOR_STATUS_LABELS[floor.status] ?? humanize(floor.status);
490
+ return ` <span class="evidence-floor evidence-floor--${escapeHtml(floor.status)}" title="Evidence floor: ${escapeHtml(floor.required)}, ${escapeHtml(origin)}">floor ${escapeHtml(floor.required)}${floor.source === "explicit" ? "*" : ""} · ${escapeHtml(status)}</span>`;
491
+ }
492
+ /**
493
+ * Certificates a requirement's tests carry: the proof kinds that earned
494
+ * proved, and certificates or claim bindings that no longer re-check.
495
+ */
496
+ // implements REQ-kibi-code-proof-kinds
497
+ function certificateStage(row) {
498
+ const certificate = records(row.evidence).find((entry) => text(entry.kind) === "certificate");
499
+ const rejections = certificateRejectionLines(row);
500
+ const claims = record(row.claimSummary);
501
+ const applicable = count(claims.applicable);
502
+ const proved = count(claims.proved);
503
+ const claimText = applicable > 0 ? `${proved}/${applicable} claims proved` : "";
504
+ if (certificate !== undefined) {
505
+ const kinds = strings(certificate.kinds).join(", ");
506
+ const tests = strings(certificate.tests);
507
+ return {
508
+ label: "Certificate",
509
+ detail: escapeHtml([
510
+ `${kinds || "certificate"} · ${tests.length} ${tests.length === 1 ? "test" : "tests"}`,
511
+ claimText,
512
+ ]
513
+ .filter(Boolean)
514
+ .join(" · ")),
515
+ state: rejections.length > 0 ? "warning" : "passed",
516
+ };
517
+ }
518
+ if (rejections.length > 0) {
519
+ return {
520
+ label: "Certificate",
521
+ detail: escapeHtml(`${rejections.length} ${rejections.length === 1 ? "certificate does" : "certificates do"} not re-check`),
522
+ state: "failed",
523
+ };
524
+ }
525
+ if (proved > 0 || count(claims.attested) > 0) {
526
+ return {
527
+ label: "Certificate",
528
+ detail: escapeHtml(claimText),
529
+ state: "warning",
530
+ };
531
+ }
532
+ return undefined;
533
+ }
534
+ // implements REQ-kibi-code-proof-kinds
535
+ export function certificateRejectionLines(row) {
536
+ return [
537
+ ...records(row.certificateRejections).map((item) => `${text(item.test, "test")}: certificate rejected, ${text(item.reason, "no reason given")}`),
538
+ ...records(row.claimBindingRejections).map((item) => `${text(item.test, "test")}: binding for ${text(item.claimKey, "claim")} rejected, ${text(item.reason, "no reason given")}`),
539
+ ];
540
+ }
421
541
  function renderIssueList(codes, className, singular, plural) {
422
542
  if (codes.length === 0)
423
543
  return "";
424
544
  const label = `${codes.length} ${codes.length === 1 ? singular : plural}`;
425
545
  return `<details class="${className}"><summary>${escapeHtml(label)}</summary><ul>${codes.map((code) => `<li>${escapeHtml(humanize(code))}</li>`).join("")}</ul></details>`;
426
546
  }
547
+ function renderRejectionList(lines) {
548
+ if (lines.length === 0)
549
+ return "";
550
+ const label = `${lines.length} ${lines.length === 1 ? "certificate rejection" : "certificate rejections"}`;
551
+ return `<details class="proof-gaps certificate-rejections"><summary>${escapeHtml(label)}</summary><ul>${lines.map((line) => `<li>${escapeHtml(line)}</li>`).join("")}</ul></details>`;
552
+ }
427
553
  function renderRequirement(row, repository) {
428
554
  const id = text(row.id, "REQ-UNKNOWN");
429
555
  const title = text(row.title, "Untitled requirement");
@@ -439,42 +565,85 @@ function renderRequirement(row, repository) {
439
565
  : proofAdvisories;
440
566
  const conflicts = records(record(record(row.proofStages).contradictions).conflicts).filter((conflict) => text(conflict.status) === "contradiction");
441
567
  const stages = requirementStages(row, repository);
442
- const badgeLabel = proofStatus === "tested" ? "Tested" : "Needs attention";
443
568
  const evidenceLevel = text(row.evidenceLevel, "unverified");
569
+ const badgeLabel = proofStatus !== "tested"
570
+ ? "Needs attention"
571
+ : evidenceLevel === "proved"
572
+ ? "Proved"
573
+ : "Tested";
574
+ const floor = evidenceFloor(row);
575
+ const rejections = certificateRejectionLines(row);
576
+ const claims = claimsProvedLabel(row);
444
577
  const requirementSource = sourceCoordinate({
445
578
  path: text(record(record(row.proofStages).sourceCoordinates).requirementPath, text(row.source)),
446
579
  }) ?? sourceCoordinate({ path: text(row.source) });
447
- const gate = earliestUnmetGate(row);
580
+ const gate = reportGate(row);
448
581
  return `<article class="requirement requirement--${escapeHtml(proofStatus)}" data-state="${rowStates(row)}" data-gate="${escapeHtml(gate)}">
449
582
  <header class="requirement__header">
450
583
  <div>
451
- <div class="requirement__id">${linkedLabel(id, sourceWebUrl(repository, requirementSource))} <span class="evidence-level evidence-level--${escapeHtml(evidenceLevel)}" title="Evidence level">${escapeHtml(evidenceLevel)}</span></div>
584
+ <div class="requirement__id">${linkedLabel(id, sourceWebUrl(repository, requirementSource))} <span class="evidence-level evidence-level--${escapeHtml(evidenceLevel)}" title="Evidence level">${escapeHtml(evidenceLevel)}</span>${renderFloorChip(floor)}${claims === null ? "" : ` <span class="claims-proved" title="Requirement claims a re-checked certificate derives">${escapeHtml(claims)}</span>`}</div>
452
585
  <h3>${linkedLabel(title, sourceWebUrl(repository, requirementSource))}</h3>
453
586
  </div>
454
- <span class="proof-badge proof-badge--${escapeHtml(proofStatus)}">${escapeHtml(badgeLabel)}</span>
587
+ <span class="proof-badge proof-badge--${escapeHtml(badgeLabel === "Proved" ? "proved" : proofStatus)}">${escapeHtml(badgeLabel)}</span>
455
588
  </header>
456
589
  <ul class="stages">${stages.map(renderStage).join("")}</ul>
457
590
  ${conflicts.map(renderContradiction).join("")}
458
591
  ${renderIssueList(blockingGaps, "proof-gaps", "proof gap", "proof gaps")}
459
592
  ${renderIssueList(advisories, "proof-advisories", "advisory", "advisories")}
593
+ ${renderRejectionList(rejections)}
460
594
  </article>`;
461
595
  }
596
+ // implements REQ-kibi-claim-bound-proofs
597
+ function claimsProvedLabel(row) {
598
+ const summary = record(row.claimSummary);
599
+ const applicable = summary.applicable;
600
+ if (typeof applicable !== "number" || applicable === 0)
601
+ return null;
602
+ const proved = typeof summary.proved === "number" ? summary.proved : 0;
603
+ return `${proved}/${applicable} claims proved`;
604
+ }
462
605
  // implements REQ-kibi-evidence-levels
463
606
  function evidenceCount(rows, level) {
464
607
  return rows.filter((row) => text(row.evidenceLevel, "unverified") === level)
465
608
  .length;
466
609
  }
610
+ // implements REQ-kibi-kb-certificates
611
+ function renderKbCertificates(bundle) {
612
+ if (bundle === undefined)
613
+ return "";
614
+ const kinds = Object.entries(bundle.kinds)
615
+ .sort(([left], [right]) => left.localeCompare(right))
616
+ .map(([kind, total]) => `${total.toLocaleString("en-US")} ${humanize(kind).toLowerCase()}`)
617
+ .join(", ");
618
+ return `<p class="kb-certificates">KB consistency: ${bundle.count.toLocaleString("en-US")} ${bundle.count === 1 ? "certificate" : "certificates"}${kinds ? ` (${escapeHtml(kinds)})` : ""} · <a href="${escapeHtml(bundle.href)}">${escapeHtml(bundle.href)}</a> · re-check with <code>kibi check --certificates ${escapeHtml(bundle.href)}</code></p>`;
619
+ }
467
620
  function metric(label, value, tone = "") {
468
621
  return `<div class="metric${tone ? ` metric--${tone}` : ""}"><span>${escapeHtml(label)}</span><strong>${value.toLocaleString("en-US")}</strong></div>`;
469
622
  }
470
623
  function renderProofGate(gate, index) {
471
- const state = gate.remaining === 0 ? "blocked" : "active";
624
+ // Proved sits above the default tested floor, so stopping before it is not
625
+ // a block; floors that require proved show up as Below evidence floor.
626
+ const optional = gate.key === "proved";
627
+ const state = optional
628
+ ? "optional"
629
+ : gate.remaining === 0
630
+ ? "blocked"
631
+ : "active";
472
632
  const drop = gate.blocked === 0
473
633
  ? "No drop"
474
- : `−${gate.blocked.toLocaleString("en-US")} blocked here`;
475
- const accessible = `${gate.label}. ${gate.blocked} blocked here. Filter requirements whose earliest unmet proof gate is ${gate.label}.`;
634
+ : optional
635
+ ? `${gate.blocked.toLocaleString("en-US")} tested, not proved`
636
+ : `−${gate.blocked.toLocaleString("en-US")} blocked here`;
637
+ const stopped = optional
638
+ ? `${gate.blocked} tested, not proved`
639
+ : `${gate.blocked} blocked here`;
640
+ // A gate nobody stops at has nothing to show, so it is not a filter.
641
+ const empty = gate.blocked === 0;
642
+ const accessible = empty
643
+ ? `${gate.label}. No requirement stops here.`
644
+ : `${gate.label}. ${stopped}. Filter requirements whose earliest unmet proof gate is ${gate.label}.`;
476
645
  return `<li>
477
- <button type="button" class="proof-gate proof-gate--${state}" data-gate="${escapeHtml(gate.key)}" aria-pressed="false" aria-controls="requirements" aria-label="${escapeHtml(accessible)}">
646
+ <button type="button" class="proof-gate proof-gate--${state}" data-gate="${escapeHtml(gate.key)}" data-label="${escapeHtml(gate.label)}" aria-pressed="false" aria-controls="requirements" aria-label="${escapeHtml(accessible)}"${empty ? " disabled" : ""}>
478
647
  <div class="proof-gate__node"><span>${index + 1}</span></div>
479
648
  <div class="proof-gate__count">${gate.remaining.toLocaleString("en-US")}</div>
480
649
  <div class="proof-gate__label">${escapeHtml(gate.label)}</div>
@@ -519,8 +688,11 @@ function reportIdentity(input) {
519
688
  function renderFilters(counts) {
520
689
  const labels = {
521
690
  all: "All",
691
+ proved: "Proved",
522
692
  tested: "Tested",
523
693
  attention: "Needs attention",
694
+ below_floor: "Below floor",
695
+ pending_reproof: "Pending re-proof",
524
696
  stale: "Stale evidence",
525
697
  contradiction: "Contradictions",
526
698
  };
@@ -551,6 +723,8 @@ export function renderHtmlReport(input) {
551
723
  const staleEvidence = currentRows.filter((row) => strings(row.proofGaps).includes("stale_proof_receipt")).length;
552
724
  const withoutImplementation = currentRows.filter((row) => strings(row.proofGaps).includes("missing_production_symbol")).length;
553
725
  const contradictions = contradictionRows(currentRows);
726
+ const belowFloor = currentRows.filter((row) => evidenceFloor(row)?.status === "below").length;
727
+ const pendingReproof = currentRows.filter((row) => evidenceFloor(row)?.status === "pending_reproof").length;
554
728
  const unmappedProductionSymbols = Math.max(0, count(symbolSummary.uncovered) - count(symbolSummary.mixedRole));
555
729
  const generatedAt = input.generatedAt.toISOString();
556
730
  const snapshot = text(input.requirements.meta?.proofSnapshot);
@@ -563,7 +737,7 @@ export function renderHtmlReport(input) {
563
737
  const filterCounts = reportFilterCounts(currentRows.map((row) => ({
564
738
  text: `${text(row.id)} ${text(row.title)}`,
565
739
  states: rowStates(row).split(" ").filter(Boolean),
566
- earliestGate: earliestUnmetGate(row),
740
+ earliestGate: reportGate(row),
567
741
  })));
568
742
  const identity = reportIdentity({ ...input, repository });
569
743
  const faviconHref = renderKibiFaviconDataUri();
@@ -617,15 +791,19 @@ export function renderHtmlReport(input) {
617
791
  </section>
618
792
  <section class="metrics" aria-label="Requirement health summary">
619
793
  ${metric("Requirements", currentRequirements)}
794
+ ${metric("Proved by certificate", evidenceCount(currentRows, "proved"), evidenceCount(currentRows, "proved") ? "good" : "")}
620
795
  ${metric("Tested end to end", tested, "good")}
621
796
  ${metric("Asserted, no current test", evidenceCount(currentRows, "asserted"), evidenceCount(currentRows, "asserted") ? "warn" : "")}
622
797
  ${metric("Unverified", evidenceCount(currentRows, "unverified"), evidenceCount(currentRows, "unverified") ? "warn" : "")}
623
- ${metric("Missing scenarios", missingScenarios, missingScenarios ? "warn" : "")}
798
+ ${metric("Below evidence floor", belowFloor, belowFloor ? "bad" : "good")}
799
+ ${metric("Pending re-proof", pendingReproof, pendingReproof ? "warn" : "")}
624
800
  ${metric("Stale E2E evidence", staleEvidence, staleEvidence ? "warn" : "")}
625
- ${metric("Contradictions", contradictions.length, contradictions.length ? "bad" : "")}
626
- ${metric("Unmapped production symbols", unmappedProductionSymbols, unmappedProductionSymbols ? "bad" : "")}
801
+ ${metric("Missing scenarios", missingScenarios, missingScenarios ? "warn" : "")}
627
802
  ${metric("Requirements without implementation", withoutImplementation, withoutImplementation ? "warn" : "")}
803
+ ${metric("Unmapped production symbols", unmappedProductionSymbols, unmappedProductionSymbols ? "bad" : "")}
804
+ ${metric("Contradictions", contradictions.length, contradictions.length ? "bad" : "")}
628
805
  </section>
806
+ ${renderKbCertificates(input.kbCertificates)}
629
807
  <section>
630
808
  <div class="section-header">
631
809
  <div><p class="eyebrow">Proof ledger</p><h2>Requirements</h2></div>
@@ -637,6 +815,7 @@ export function renderHtmlReport(input) {
637
815
  ${renderFilters(filterCounts)}
638
816
  </div>
639
817
  </div>
818
+ <p class="gate-status" id="gate-status" aria-live="polite" hidden><span></span> <button type="button" class="gate-status__clear">Show all</button></p>
640
819
  <div class="requirements" id="requirements">${currentRows.map((row) => renderRequirement(row, repository)).join("")}</div>
641
820
  <div class="empty" id="empty" aria-live="polite">No requirements match this view.</div>
642
821
  </section>
@@ -653,6 +832,8 @@ export function renderHtmlReport(input) {
653
832
  const filters = [...document.querySelectorAll(".filter")];
654
833
  const gates = [...document.querySelectorAll(".proof-gate")];
655
834
  const empty = document.querySelector("#empty");
835
+ const gateStatus = document.querySelector("#gate-status");
836
+ const gateStatusText = gateStatus.querySelector("span");
656
837
  let activeFilter = "all";
657
838
  let activeGate = "all";
658
839
  const formatRelativeAge = (fromMs, nowMs) => {
@@ -689,7 +870,20 @@ export function renderHtmlReport(input) {
689
870
  if (!card.hidden) visible += 1;
690
871
  }
691
872
  empty.dataset.visible = String(visible === 0);
873
+ const selectedGate = gates.find((candidate) => candidate.dataset.gate === activeGate);
874
+ gateStatus.hidden = selectedGate === undefined;
875
+ if (selectedGate) {
876
+ gateStatusText.textContent = visible + (visible === 1 ? " requirement stops" : " requirements stop") + " at " + (selectedGate.dataset.label || activeGate) + ".";
877
+ }
692
878
  };
879
+ const selectGate = (selected) => {
880
+ activeGate = selected;
881
+ for (const candidate of gates) {
882
+ candidate.setAttribute("aria-pressed", String(candidate.dataset.gate === activeGate));
883
+ }
884
+ apply();
885
+ };
886
+ gateStatus.querySelector("button").addEventListener("click", () => selectGate("all"));
693
887
  search.addEventListener("input", apply);
694
888
  for (const filter of filters) {
695
889
  filter.addEventListener("click", () => {
@@ -701,11 +895,9 @@ export function renderHtmlReport(input) {
701
895
  for (const gate of gates) {
702
896
  gate.addEventListener("click", () => {
703
897
  const selected = gate.dataset.gate || "all";
704
- activeGate = activeGate === selected ? "all" : selected;
705
- for (const candidate of gates) {
706
- candidate.setAttribute("aria-pressed", String(candidate.dataset.gate === activeGate));
707
- }
708
- apply();
898
+ selectGate(activeGate === selected ? "all" : selected);
899
+ // The ledger sits below the fold; bring the filtered rows into view.
900
+ if (activeGate !== "all") gateStatus.scrollIntoView({ behavior: "smooth", block: "start" });
709
901
  });
710
902
  }
711
903
  refreshAges();
@@ -1,6 +1,6 @@
1
- export declare const REPORT_FILTERS: readonly ["all", "tested", "attention", "stale", "contradiction"];
1
+ export declare const REPORT_FILTERS: readonly ["all", "proved", "tested", "attention", "below_floor", "pending_reproof", "stale", "contradiction"];
2
2
  export type ReportFilter = (typeof REPORT_FILTERS)[number];
3
- export declare const PROOF_GATE_KEYS: readonly ["semantic", "scenario", "implementation", "e2e", "evidence"];
3
+ export declare const PROOF_GATE_KEYS: readonly ["semantic", "scenario", "implementation", "e2e", "evidence", "proved"];
4
4
  export type ProofGateKey = (typeof PROOF_GATE_KEYS)[number];
5
5
  export type RequirementView = Readonly<{
6
6
  text: string;
@@ -1 +1 @@
1
- {"version":3,"file":"report-view.d.ts","sourceRoot":"","sources":["../../src/report/report-view.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,mEAMjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,eAAO,MAAM,eAAe,wEAMlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,YAAY,GAAG,QAAQ,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,YAAY,GAAG,KAAK,CAAC;CAC5B,CAAC,CAAC;AAGH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,eAAe,GACpB,OAAO,CAQT;AAGD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,eAAe,EAAE,GAC/B,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CASxC"}
1
+ {"version":3,"file":"report-view.d.ts","sourceRoot":"","sources":["../../src/report/report-view.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,+GASjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,eAAO,MAAM,eAAe,kFAOlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,YAAY,GAAG,QAAQ,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,YAAY,GAAG,KAAK,CAAC;CAC5B,CAAC,CAAC;AAGH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,eAAe,GACpB,OAAO,CAQT;AAGD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,eAAe,EAAE,GAC/B,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAexC"}
@@ -1,7 +1,10 @@
1
1
  export const REPORT_FILTERS = [
2
2
  "all",
3
+ "proved",
3
4
  "tested",
4
5
  "attention",
6
+ "below_floor",
7
+ "pending_reproof",
5
8
  "stale",
6
9
  "contradiction",
7
10
  ];
@@ -11,6 +14,7 @@ export const PROOF_GATE_KEYS = [
11
14
  "implementation",
12
15
  "e2e",
13
16
  "evidence",
17
+ "proved",
14
18
  ];
15
19
  // implements REQ-kibi-html-health-report
16
20
  export function matchesReportView(row, view) {
@@ -24,8 +28,12 @@ export function matchesReportView(row, view) {
24
28
  export function reportFilterCounts(rows) {
25
29
  return {
26
30
  all: rows.length,
31
+ proved: rows.filter((row) => row.states.includes("proved")).length,
27
32
  tested: rows.filter((row) => row.states.includes("tested")).length,
28
33
  attention: rows.filter((row) => row.states.includes("attention")).length,
34
+ below_floor: rows.filter((row) => row.states.includes("below_floor"))
35
+ .length,
36
+ pending_reproof: rows.filter((row) => row.states.includes("pending_reproof")).length,
29
37
  stale: rows.filter((row) => row.states.includes("stale")).length,
30
38
  contradiction: rows.filter((row) => row.states.includes("contradiction"))
31
39
  .length,