kibi-cli 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/dist/cli-json-command.d.ts +6 -0
  2. package/dist/cli-json-command.d.ts.map +1 -1
  3. package/dist/cli-json-command.js +37 -9
  4. package/dist/cli-operation-loader.d.ts.map +1 -1
  5. package/dist/cli-operation-loader.js +7 -0
  6. package/dist/cli-operation-metadata.d.ts +12 -4
  7. package/dist/cli-operation-metadata.d.ts.map +1 -1
  8. package/dist/cli-operation-metadata.js +14 -4
  9. package/dist/cli-protocol.d.ts +14 -0
  10. package/dist/cli-protocol.d.ts.map +1 -1
  11. package/dist/cli-protocol.js +31 -2
  12. package/dist/cli-register-proof.d.ts.map +1 -1
  13. package/dist/cli-register-proof.js +13 -0
  14. package/dist/commands/check.d.ts.map +1 -1
  15. package/dist/commands/check.js +11 -2
  16. package/dist/commands/discovery-shared.d.ts.map +1 -1
  17. package/dist/commands/discovery-shared.js +8 -2
  18. package/dist/commands/engine.d.ts.map +1 -1
  19. package/dist/commands/engine.js +4 -2
  20. package/dist/commands/gc.d.ts.map +1 -1
  21. package/dist/commands/gc.js +7 -0
  22. package/dist/commands/init-helpers.d.ts.map +1 -1
  23. package/dist/commands/init-helpers.js +0 -1
  24. package/dist/commands/migrate.d.ts.map +1 -1
  25. package/dist/commands/migrate.js +281 -14
  26. package/dist/commands/proof-compact.d.ts +9 -0
  27. package/dist/commands/proof-compact.d.ts.map +1 -0
  28. package/dist/commands/proof-compact.js +58 -0
  29. package/dist/commands/prove.d.ts +38 -0
  30. package/dist/commands/prove.d.ts.map +1 -1
  31. package/dist/commands/prove.js +222 -47
  32. package/dist/commands/sync/persistence.d.ts.map +1 -1
  33. package/dist/commands/sync/persistence.js +61 -16
  34. package/dist/commands/sync.d.ts +8 -0
  35. package/dist/commands/sync.d.ts.map +1 -1
  36. package/dist/commands/sync.js +42 -16
  37. package/dist/diagnostics.js +1 -1
  38. package/dist/engine-limits.d.ts +74 -0
  39. package/dist/engine-limits.d.ts.map +1 -0
  40. package/dist/engine-limits.js +201 -0
  41. package/dist/engine.d.ts +10 -0
  42. package/dist/engine.d.ts.map +1 -1
  43. package/dist/engine.js +57 -9
  44. package/dist/extractors/manifest.d.ts +8 -0
  45. package/dist/extractors/manifest.d.ts.map +1 -1
  46. package/dist/extractors/manifest.js +34 -5
  47. package/dist/extractors/markdown.d.ts +8 -0
  48. package/dist/extractors/markdown.d.ts.map +1 -1
  49. package/dist/extractors/markdown.js +57 -0
  50. package/dist/extractors/relationships.d.ts.map +1 -1
  51. package/dist/extractors/relationships.js +2 -0
  52. package/dist/intent-search.d.ts +4 -1
  53. package/dist/intent-search.d.ts.map +1 -1
  54. package/dist/intent-search.js +186 -33
  55. package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
  56. package/dist/operations/bootstrap/candidate-helpers.js +8 -1
  57. package/dist/operations/bootstrap/candidates.d.ts.map +1 -1
  58. package/dist/operations/bootstrap/candidates.js +54 -38
  59. package/dist/operations/bootstrap/generate.d.ts +2 -0
  60. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  61. package/dist/operations/bootstrap/generate.js +87 -33
  62. package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -1
  63. package/dist/operations/bootstrap/intent-claims.js +12 -4
  64. package/dist/operations/bootstrap/markdown-candidates.d.ts +2 -0
  65. package/dist/operations/bootstrap/markdown-candidates.d.ts.map +1 -1
  66. package/dist/operations/bootstrap/markdown-candidates.js +32 -10
  67. package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
  68. package/dist/operations/bootstrap/presentation.js +6 -2
  69. package/dist/operations/bootstrap/requirement-claims.d.ts +1 -0
  70. package/dist/operations/bootstrap/requirement-claims.d.ts.map +1 -1
  71. package/dist/operations/bootstrap/requirement-claims.js +13 -1
  72. package/dist/operations/bootstrap/validation.d.ts +4 -0
  73. package/dist/operations/bootstrap/validation.d.ts.map +1 -0
  74. package/dist/operations/bootstrap/validation.js +20 -0
  75. package/dist/operations/migration/inventory-rederive.d.ts +81 -0
  76. package/dist/operations/migration/inventory-rederive.d.ts.map +1 -0
  77. package/dist/operations/migration/inventory-rederive.js +484 -0
  78. package/dist/operations/migration/kb-sources.d.ts +53 -0
  79. package/dist/operations/migration/kb-sources.d.ts.map +1 -0
  80. package/dist/operations/migration/kb-sources.js +233 -0
  81. package/dist/operations/migration/origin-backfill.d.ts +39 -0
  82. package/dist/operations/migration/origin-backfill.d.ts.map +1 -0
  83. package/dist/operations/migration/origin-backfill.js +164 -0
  84. package/dist/operations/migration/polarity-values.d.ts +10 -0
  85. package/dist/operations/migration/polarity-values.d.ts.map +1 -0
  86. package/dist/operations/migration/polarity-values.js +60 -0
  87. package/dist/operations/migration/schema6.d.ts +59 -0
  88. package/dist/operations/migration/schema6.d.ts.map +1 -0
  89. package/dist/operations/migration/schema6.js +379 -0
  90. package/dist/operations/migration/source-paths.d.ts +131 -0
  91. package/dist/operations/migration/source-paths.d.ts.map +1 -0
  92. package/dist/operations/migration/source-paths.js +308 -0
  93. package/dist/operations/migration/superseded-closure.d.ts +54 -0
  94. package/dist/operations/migration/superseded-closure.d.ts.map +1 -0
  95. package/dist/operations/migration/superseded-closure.js +187 -0
  96. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
  97. package/dist/operations/modeling/logic-modeling.js +3 -5
  98. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  99. package/dist/operations/modeling/model-requirement.js +225 -67
  100. package/dist/operations/mutation/contradictions.d.ts +16 -0
  101. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  102. package/dist/operations/mutation/contradictions.js +32 -0
  103. package/dist/operations/mutation/delete.d.ts.map +1 -1
  104. package/dist/operations/mutation/delete.js +15 -7
  105. package/dist/operations/mutation/origin.d.ts +21 -0
  106. package/dist/operations/mutation/origin.d.ts.map +1 -0
  107. package/dist/operations/mutation/origin.js +78 -0
  108. package/dist/operations/mutation/plan-apply-journal.d.ts +182 -0
  109. package/dist/operations/mutation/plan-apply-journal.d.ts.map +1 -0
  110. package/dist/operations/mutation/plan-apply-journal.js +613 -0
  111. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +3 -1
  112. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -1
  113. package/dist/operations/mutation/predicate-vocabulary-guard.js +13 -2
  114. package/dist/operations/mutation/relationships.d.ts +5 -5
  115. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  116. package/dist/operations/mutation/relationships.js +31 -11
  117. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  118. package/dist/operations/mutation/serialization.js +3 -1
  119. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  120. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  121. package/dist/operations/mutation/source-authoring.js +7 -1
  122. package/dist/operations/mutation/types.d.ts +14 -0
  123. package/dist/operations/mutation/types.d.ts.map +1 -1
  124. package/dist/operations/mutation/upsert.d.ts +30 -3
  125. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  126. package/dist/operations/mutation/upsert.js +105 -35
  127. package/dist/operations/mutation/validate-upsert.d.ts +6 -0
  128. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  129. package/dist/operations/mutation/validate-upsert.js +34 -30
  130. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  131. package/dist/operations/planning/apply-plan.js +751 -144
  132. package/dist/operations/planning/compile-intent.d.ts +34 -1
  133. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  134. package/dist/operations/planning/compile-intent.js +314 -98
  135. package/dist/operations/proof/code-scope.d.ts +28 -0
  136. package/dist/operations/proof/code-scope.d.ts.map +1 -1
  137. package/dist/operations/proof/code-scope.js +72 -0
  138. package/dist/operations/proof/compact-receipts.d.ts +49 -0
  139. package/dist/operations/proof/compact-receipts.d.ts.map +1 -0
  140. package/dist/operations/proof/compact-receipts.js +160 -0
  141. package/dist/operations/proof/ingest-proof.d.ts +2 -0
  142. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  143. package/dist/operations/proof/ingest-proof.js +44 -23
  144. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  145. package/dist/operations/proof/prune-receipts.js +5 -9
  146. package/dist/operations/proof/receipt-compaction.d.ts +48 -0
  147. package/dist/operations/proof/receipt-compaction.d.ts.map +1 -0
  148. package/dist/operations/proof/receipt-compaction.js +121 -0
  149. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  150. package/dist/operations/semantic-advisor/analysis-receipt.js +12 -1
  151. package/dist/operations/semantic-advisor/analyze-prose.d.ts +2 -1
  152. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  153. package/dist/operations/semantic-advisor/analyze-prose.js +51 -5
  154. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  155. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  156. package/dist/operations/semantic-advisor/clauses.js +11 -1
  157. package/dist/operations/semantic-advisor/conditional-rules.d.ts +33 -0
  158. package/dist/operations/semantic-advisor/conditional-rules.d.ts.map +1 -0
  159. package/dist/operations/semantic-advisor/conditional-rules.js +262 -0
  160. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +3 -1
  161. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
  162. package/dist/operations/semantic-advisor/ingestion-boundary.js +14 -6
  163. package/dist/operations/semantic-advisor/plugin-orchestration.js +1 -1
  164. package/dist/prolog/codec.d.ts.map +1 -1
  165. package/dist/prolog/codec.js +2 -1
  166. package/dist/prolog.d.ts +9 -0
  167. package/dist/prolog.d.ts.map +1 -1
  168. package/dist/prolog.js +56 -10
  169. package/dist/proof/command-test-report.d.ts +74 -0
  170. package/dist/proof/command-test-report.d.ts.map +1 -0
  171. package/dist/proof/command-test-report.js +206 -0
  172. package/dist/public/branch-resolver.d.ts +1 -0
  173. package/dist/public/branch-resolver.d.ts.map +1 -1
  174. package/dist/public/branch-resolver.js +1 -0
  175. package/dist/public/entity-origin.d.ts +69 -0
  176. package/dist/public/entity-origin.d.ts.map +1 -0
  177. package/dist/public/entity-origin.js +142 -0
  178. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  179. package/dist/public/impact/full-kb-quality.js +1 -0
  180. package/dist/public/impact/requirement-quality.js +1 -1
  181. package/dist/public/operations/catalog.d.ts +130 -19
  182. package/dist/public/operations/catalog.d.ts.map +1 -1
  183. package/dist/public/operations/catalog.js +3 -0
  184. package/dist/public/operations/check-executor.d.ts.map +1 -1
  185. package/dist/public/operations/check-executor.js +8 -0
  186. package/dist/public/operations/contracts.d.ts +0 -5
  187. package/dist/public/operations/contracts.d.ts.map +1 -1
  188. package/dist/public/operations/contracts.js +63 -14
  189. package/dist/public/operations/discovery-entities.d.ts +15 -0
  190. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  191. package/dist/public/operations/discovery-entities.js +59 -0
  192. package/dist/public/operations/discovery-executors.d.ts +6 -1
  193. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  194. package/dist/public/operations/discovery-executors.js +65 -6
  195. package/dist/public/operations/index.d.ts +1 -0
  196. package/dist/public/operations/index.d.ts.map +1 -1
  197. package/dist/public/operations/index.js +1 -0
  198. package/dist/public/operations/migration-plan.d.ts +5 -0
  199. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  200. package/dist/public/operations/migration-plan.js +26 -1
  201. package/dist/public/operations/node-ports.d.ts.map +1 -1
  202. package/dist/public/operations/node-ports.js +24 -3
  203. package/dist/public/operations/origin-review.d.ts +51 -0
  204. package/dist/public/operations/origin-review.d.ts.map +1 -0
  205. package/dist/public/operations/origin-review.js +307 -0
  206. package/dist/public/operations/predicate-schema-conformance.js +1 -1
  207. package/dist/public/operations/repair-plan.d.ts.map +1 -1
  208. package/dist/public/operations/repair-plan.js +4 -0
  209. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  210. package/dist/public/operations/result-envelope.js +17 -5
  211. package/dist/public/operations/runtime-types.d.ts +9 -0
  212. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  213. package/dist/public/operations/schema6-check-actions.d.ts +127 -0
  214. package/dist/public/operations/schema6-check-actions.d.ts.map +1 -0
  215. package/dist/public/operations/schema6-check-actions.js +575 -0
  216. package/dist/public/operations/source-path-dangling.d.ts +17 -0
  217. package/dist/public/operations/source-path-dangling.d.ts.map +1 -0
  218. package/dist/public/operations/source-path-dangling.js +66 -0
  219. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  220. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  221. package/dist/public/operations/specs/check-rules.generated.js +15 -1
  222. package/dist/public/operations/specs/check.d.ts +2 -2
  223. package/dist/public/operations/specs/check.js +1 -1
  224. package/dist/public/operations/specs/composite.d.ts +351 -0
  225. package/dist/public/operations/specs/composite.d.ts.map +1 -0
  226. package/dist/public/operations/specs/composite.js +96 -0
  227. package/dist/public/operations/specs/discovery.d.ts +8 -3
  228. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  229. package/dist/public/operations/specs/discovery.js +8 -3
  230. package/dist/public/operations/specs/modeling.d.ts +2 -2
  231. package/dist/public/operations/specs/modeling.js +2 -2
  232. package/dist/public/operations/specs/mutation-schemas.d.ts +73 -8
  233. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  234. package/dist/public/operations/specs/mutation-schemas.js +43 -7
  235. package/dist/public/operations/specs/mutation.d.ts +1 -1
  236. package/dist/public/operations/specs/mutation.js +1 -1
  237. package/dist/public/operations/specs/planning.d.ts +2 -2
  238. package/dist/public/operations/specs/planning.js +4 -4
  239. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  240. package/dist/public/operations/specs/reporting.js +13 -26
  241. package/dist/public/operations/specs/upsert.d.ts +79 -9
  242. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  243. package/dist/public/operations/specs/upsert.js +6 -1
  244. package/dist/public/operations/types.d.ts +1 -1
  245. package/dist/public/operations/types.d.ts.map +1 -1
  246. package/dist/public/proof-receipt.d.ts +1 -0
  247. package/dist/public/proof-receipt.d.ts.map +1 -1
  248. package/dist/public/schemas/entity.d.ts.map +1 -1
  249. package/dist/public/schemas/entity.js +52 -0
  250. package/dist/public/schemas/relationship.d.ts.map +1 -1
  251. package/dist/public/schemas/relationship.js +2 -0
  252. package/dist/public/skills/kibi-bootstrap/SKILL.md +6 -1
  253. package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  254. package/dist/public/skills/kibi-usage/SKILL.md +68 -18
  255. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  256. package/dist/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
  257. package/dist/public/skills/kibi-usage/resources/logic-ir.md +2 -2
  258. package/dist/public/skills/kibi-usage/resources/operation-access.md +25 -1
  259. package/dist/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
  260. package/dist/public/skills/kibi-usage/resources/workflows.md +42 -25
  261. package/dist/public/telemetry-acceptance.d.ts +58 -2
  262. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  263. package/dist/public/telemetry-acceptance.js +136 -10
  264. package/dist/public/telemetry-remediation.d.ts.map +1 -1
  265. package/dist/public/telemetry-remediation.js +26 -10
  266. package/dist/relationships/shards.d.ts +13 -0
  267. package/dist/relationships/shards.d.ts.map +1 -1
  268. package/dist/relationships/shards.js +54 -28
  269. package/dist/runtime/cli-runtime.d.ts.map +1 -1
  270. package/dist/runtime/cli-runtime.js +44 -3
  271. package/dist/runtime/detached-snapshot.d.ts +38 -0
  272. package/dist/runtime/detached-snapshot.d.ts.map +1 -0
  273. package/dist/runtime/detached-snapshot.js +92 -0
  274. package/dist/schemas/entity.schema.json +122 -0
  275. package/dist/search-answer.d.ts +157 -0
  276. package/dist/search-answer.d.ts.map +1 -0
  277. package/dist/search-answer.js +846 -0
  278. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  279. package/dist/traceability/impact-knowledge.js +7 -0
  280. package/dist/traceability/symbol-extract.js +3 -3
  281. package/dist/traceability/temp-kb.d.ts.map +1 -1
  282. package/dist/traceability/temp-kb.js +12 -0
  283. package/dist/types/entities.d.ts +13 -0
  284. package/dist/types/entities.d.ts.map +1 -1
  285. package/dist/types/relationships.d.ts +1 -1
  286. package/dist/types/relationships.d.ts.map +1 -1
  287. package/dist/utils/branch-resolver.d.ts +37 -1
  288. package/dist/utils/branch-resolver.d.ts.map +1 -1
  289. package/dist/utils/branch-resolver.js +130 -3
  290. package/dist/utils/repo-relative-path.d.ts +18 -0
  291. package/dist/utils/repo-relative-path.d.ts.map +1 -0
  292. package/dist/utils/repo-relative-path.js +58 -0
  293. package/dist/utils/rule-registry.generated.d.ts +75 -3
  294. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  295. package/dist/utils/rule-registry.generated.js +89 -3
  296. package/dist/utils/schema-version.d.ts +1 -1
  297. package/dist/utils/schema-version.d.ts.map +1 -1
  298. package/dist/utils/schema-version.js +4 -3
  299. package/dist/utils/strict-modeling.d.ts +1 -1
  300. package/dist/utils/strict-modeling.d.ts.map +1 -1
  301. package/dist/utils/strict-modeling.js +23 -3
  302. package/package.json +3 -3
  303. package/schema/entities.pl +22 -0
  304. package/schema/relationships.pl +14 -0
  305. package/schema/validation.pl +45 -1
  306. package/src/public/branch-resolver.ts +1 -0
  307. package/src/public/entity-origin.ts +175 -0
  308. package/src/public/impact/full-kb-quality.ts +1 -0
  309. package/src/public/impact/requirement-quality.ts +1 -1
  310. package/src/public/operations/catalog.ts +3 -0
  311. package/src/public/operations/check-executor.ts +15 -0
  312. package/src/public/operations/contracts.ts +75 -15
  313. package/src/public/operations/discovery-entities.ts +74 -0
  314. package/src/public/operations/discovery-executors.ts +88 -10
  315. package/src/public/operations/index.ts +1 -0
  316. package/src/public/operations/migration-plan.ts +30 -1
  317. package/src/public/operations/node-ports.ts +24 -3
  318. package/src/public/operations/origin-review.ts +375 -0
  319. package/src/public/operations/predicate-schema-conformance.ts +1 -1
  320. package/src/public/operations/repair-plan.ts +4 -0
  321. package/src/public/operations/result-envelope.ts +18 -6
  322. package/src/public/operations/runtime-types.ts +9 -0
  323. package/src/public/operations/schema6-check-actions.ts +699 -0
  324. package/src/public/operations/source-path-dangling.ts +81 -0
  325. package/src/public/operations/specs/check-rules.generated.ts +15 -1
  326. package/src/public/operations/specs/check.ts +1 -1
  327. package/src/public/operations/specs/composite.ts +141 -0
  328. package/src/public/operations/specs/discovery.ts +9 -3
  329. package/src/public/operations/specs/modeling.ts +2 -2
  330. package/src/public/operations/specs/mutation-schemas.ts +49 -7
  331. package/src/public/operations/specs/mutation.ts +1 -1
  332. package/src/public/operations/specs/planning.ts +4 -4
  333. package/src/public/operations/specs/reporting.ts +13 -38
  334. package/src/public/operations/specs/upsert.ts +7 -1
  335. package/src/public/operations/types.ts +2 -0
  336. package/src/public/proof-receipt.ts +1 -0
  337. package/src/public/schemas/entity.ts +57 -0
  338. package/src/public/schemas/relationship.ts +2 -0
  339. package/src/public/skills/kibi-bootstrap/SKILL.md +6 -1
  340. package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  341. package/src/public/skills/kibi-usage/SKILL.md +68 -18
  342. package/src/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  343. package/src/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
  344. package/src/public/skills/kibi-usage/resources/logic-ir.md +2 -2
  345. package/src/public/skills/kibi-usage/resources/operation-access.md +25 -1
  346. package/src/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
  347. package/src/public/skills/kibi-usage/resources/workflows.md +42 -25
  348. package/src/public/telemetry-acceptance-types.d.ts +4 -1
  349. package/src/public/telemetry-acceptance.ts +204 -10
  350. package/src/public/telemetry-remediation.ts +39 -10
  351. package/src/schemas/entity.schema.json +122 -0
  352. package/src/schemas/relationship.schema.json +2 -0
@@ -30,6 +30,7 @@ export const DEFAULT_TELEMETRY_ACCEPTANCE_POLICY = {
30
30
  telemetryCompletenessMinimum: 0.95,
31
31
  validationBeforeUpsertMinimum: 1,
32
32
  advisorBeforeRequirementWriteMinimum: 1,
33
+ lookupBeforeFirstEditMinimum: 1,
33
34
  sourceLookupZeroResultMaximum: 0.2,
34
35
  preflightMaxAgeSeconds: 60 * 60,
35
36
  advisorMaxAgeSeconds: 24 * 60 * 60,
@@ -50,18 +51,67 @@ function isRecord(value: unknown): value is Record<string, unknown> {
50
51
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
51
52
  }
52
53
 
54
+ // implements REQ-kibi-telemetry-acceptance-gate-v2, REQ-claude-hook-usage-telemetry-v2
55
+ /**
56
+ * A row written by a host plugin hook (`interface: "hook"`). Hooks record
57
+ * agent activity around Kibi calls: which Kibi operation a tool call ran
58
+ * (`hook_action: "kb_usage"`) and which files an edit tool changed, with the
59
+ * requirements those files' symbols implement (`hook_action: "edited"`).
60
+ */
61
+ export interface TelemetryHookEvent extends TelemetryUsageEvent {
62
+ readonly interface?: string;
63
+ readonly host?: string;
64
+ readonly hook_action?: string;
65
+ readonly path?: string | null;
66
+ readonly requirement_ids?: readonly string[];
67
+ readonly kb_operation?: string | null;
68
+ }
69
+
70
+ // implements REQ-kibi-telemetry-acceptance-gate-v2, REQ-claude-hook-usage-telemetry-v2
71
+ /** A host hook row and where it sits relative to the operation events. */
72
+ export interface TelemetryHookRow {
73
+ readonly event: TelemetryHookEvent;
74
+ /** 1-based `.kb/usage.log` line (array position for in-memory events). */
75
+ readonly logLine: number;
76
+ /** Operation events that precede this row in the log. */
77
+ readonly operationsBefore: number;
78
+ }
79
+
80
+ // implements REQ-kibi-telemetry-acceptance-gate-v2, REQ-claude-hook-usage-telemetry-v2
81
+ /** Operation events and host hook rows of one usage log, kept apart. */
82
+ export interface TelemetryUsagePartition {
83
+ readonly operations: readonly TelemetryUsageEvent[];
84
+ /** 1-based `.kb/usage.log` line of each operation event. */
85
+ readonly operationLines: readonly number[];
86
+ readonly hookRows: readonly TelemetryHookRow[];
87
+ }
88
+
89
+ /**
90
+ * Hook rows and line numbers of every array `parseTelemetryUsageLog`
91
+ * returned. The array itself keeps its operation-only shape, so callers that
92
+ * pass it straight to the analyzers need no change.
93
+ */
94
+ const parsedUsageLogs = new WeakMap<
95
+ readonly TelemetryUsageEvent[],
96
+ Omit<TelemetryUsagePartition, "operations">
97
+ >();
98
+
53
99
  /**
54
100
  * Parse Kibi operation events from `.kb/usage.log`.
55
101
  *
56
102
  * Host plugin hooks share the log and tag their rows `interface: "hook"`.
57
103
  * Those rows describe agent activity around Kibi calls, not Kibi operations,
58
- * so they are dropped here: otherwise a busy editing session would push every
59
- * operation out of the bounded acceptance window.
104
+ * so they are left out of the returned array: otherwise a busy editing
105
+ * session would push every operation out of the bounded acceptance window.
106
+ * They stay attached to the array for `partitionTelemetryUsage`, which is how
107
+ * the `lookup_before_first_edit` metric reads them.
60
108
  */
61
109
  export function parseTelemetryUsageLog(
62
110
  contents: string,
63
111
  ): TelemetryUsageEvent[] {
64
112
  const events: TelemetryUsageEvent[] = [];
113
+ const operationLines: number[] = [];
114
+ const hookRows: TelemetryHookRow[] = [];
65
115
  for (const [index, line] of contents.split(/\r?\n/).entries()) {
66
116
  const trimmed = line.trim();
67
117
  if (!trimmed) continue;
@@ -79,12 +129,50 @@ export function parseTelemetryUsageLog(
79
129
  `Failed to parse .kb/usage.log line ${index + 1}: expected object`,
80
130
  );
81
131
  }
82
- if (parsed.interface === "hook") continue;
132
+ if (parsed.interface === "hook") {
133
+ hookRows.push({
134
+ event: parsed as TelemetryHookEvent,
135
+ logLine: index + 1,
136
+ operationsBefore: events.length,
137
+ });
138
+ continue;
139
+ }
83
140
  events.push(parsed as TelemetryUsageEvent);
141
+ operationLines.push(index + 1);
84
142
  }
143
+ parsedUsageLogs.set(events, { operationLines, hookRows });
85
144
  return events;
86
145
  }
87
146
 
147
+ // implements REQ-kibi-telemetry-acceptance-gate-v2, REQ-claude-hook-usage-telemetry-v2
148
+ /**
149
+ * Split events into Kibi operations and host hook rows. Arrays from
150
+ * `parseTelemetryUsageLog` carry their hook rows and log lines; any other
151
+ * array is split on `interface: "hook"`, with positions as line numbers.
152
+ */
153
+ export function partitionTelemetryUsage(
154
+ events: readonly TelemetryUsageEvent[],
155
+ ): TelemetryUsagePartition {
156
+ const parsed = parsedUsageLogs.get(events);
157
+ if (parsed !== undefined) return { operations: events, ...parsed };
158
+ const operations: TelemetryUsageEvent[] = [];
159
+ const operationLines: number[] = [];
160
+ const hookRows: TelemetryHookRow[] = [];
161
+ for (const [index, event] of events.entries()) {
162
+ if ((event as TelemetryHookEvent).interface === "hook") {
163
+ hookRows.push({
164
+ event: event as TelemetryHookEvent,
165
+ logLine: index + 1,
166
+ operationsBefore: operations.length,
167
+ });
168
+ } else {
169
+ operations.push(event);
170
+ operationLines.push(index + 1);
171
+ }
172
+ }
173
+ return { operations, operationLines, hookRows };
174
+ }
175
+
88
176
  function eventArgs(
89
177
  event: TelemetryUsageEvent,
90
178
  ): Readonly<Record<string, unknown>> {
@@ -372,6 +460,103 @@ function advisorBeforeRequirementWriteMetric(
372
460
  };
373
461
  }
374
462
 
463
+ // implements REQ-kibi-telemetry-acceptance-gate-v2
464
+ /** Kibi operations that count as looking up requirements before an edit. */
465
+ export const LOOKUP_BEFORE_EDIT_OPERATIONS = ["kb_query", "kb_search"] as const;
466
+
467
+ // implements REQ-kibi-telemetry-acceptance-gate-v2
468
+ /** The first requirement-linked edit of one host session. */
469
+ export interface FirstLinkedEdit {
470
+ /** `<host>:<session_id>` of the session. */
471
+ readonly session: string;
472
+ readonly edit: TelemetryHookRow;
473
+ /** True when kb_search or kb_query ran earlier in the same session. */
474
+ readonly lookedUp: boolean;
475
+ }
476
+
477
+ function hookSession(event: TelemetryHookEvent): string | undefined {
478
+ const sessionId = event.session_id;
479
+ if (typeof sessionId !== "string" || sessionId.length === 0) return undefined;
480
+ return `${event.host ?? "unknown"}:${sessionId}`;
481
+ }
482
+
483
+ // implements REQ-kibi-telemetry-acceptance-gate-v2, REQ-claude-hook-usage-telemetry-v2
484
+ /**
485
+ * For each host session, its first edit of a file whose symbols implement a
486
+ * requirement and whether a Kibi lookup (MCP or CLI) preceded it. Rows
487
+ * without a session id cannot be ordered within a session and are skipped;
488
+ * sessions whose first linked edit predates the evaluated window are left
489
+ * out.
490
+ */
491
+ export function firstLinkedEdits(
492
+ hookRows: readonly TelemetryHookRow[],
493
+ recentStart: number,
494
+ ): FirstLinkedEdit[] {
495
+ const lookedUp = new Set<string>();
496
+ const edited = new Set<string>();
497
+ const firstEdits: FirstLinkedEdit[] = [];
498
+ for (const row of hookRows) {
499
+ const session = hookSession(row.event);
500
+ if (session === undefined) continue;
501
+ const { hook_action: action, kb_operation: operation } = row.event;
502
+ if (
503
+ action === "kb_usage" &&
504
+ LOOKUP_BEFORE_EDIT_OPERATIONS.some((candidate) => candidate === operation)
505
+ ) {
506
+ lookedUp.add(session);
507
+ continue;
508
+ }
509
+ if (
510
+ action !== "edited" ||
511
+ edited.has(session) ||
512
+ !Array.isArray(row.event.requirement_ids) ||
513
+ row.event.requirement_ids.length === 0
514
+ ) {
515
+ continue;
516
+ }
517
+ edited.add(session);
518
+ if (row.operationsBefore < recentStart) continue;
519
+ firstEdits.push({ session, edit: row, lookedUp: lookedUp.has(session) });
520
+ }
521
+ return firstEdits;
522
+ }
523
+
524
+ function lookupBeforeFirstEditMetric(
525
+ hookRows: readonly TelemetryHookRow[],
526
+ recentStart: number,
527
+ policy: TelemetryAcceptancePolicy,
528
+ ): MutableMetric {
529
+ const firstEdits = firstLinkedEdits(hookRows, recentStart);
530
+ const attempts = firstEdits.length;
531
+ const guided = firstEdits.filter((entry) => entry.lookedUp).length;
532
+ const unguidedEditPaths = new Set(
533
+ firstEdits
534
+ .filter((entry) => !entry.lookedUp)
535
+ .map((entry) => entry.edit.event.path ?? "unknown path"),
536
+ );
537
+
538
+ const actual = rate(guided, attempts);
539
+ return {
540
+ id: "lookup_before_first_edit",
541
+ status: thresholdStatus(actual, ">=", policy.lookupBeforeFirstEditMinimum),
542
+ numerator: guided,
543
+ denominator: attempts,
544
+ ...(actual !== undefined ? { rate: actual } : {}),
545
+ threshold: {
546
+ operator: ">=",
547
+ value: policy.lookupBeforeFirstEditMinimum,
548
+ },
549
+ message:
550
+ attempts === 0
551
+ ? "No host hook recorded an edit of a requirement-linked file in the evaluated window."
552
+ : `${guided}/${attempts} sessions ran kb_search or kb_query before their first edit of a requirement-linked file.`,
553
+ evidence: {
554
+ unguidedEditPaths: [...unguidedEditPaths].sort().slice(0, 20),
555
+ lookupOperations: [...LOOKUP_BEFORE_EDIT_OPERATIONS],
556
+ },
557
+ };
558
+ }
559
+
375
560
  function sourceLookupMessage(
376
561
  zeroResults: number,
377
562
  lookups: number,
@@ -629,7 +814,8 @@ export function analyzeTelemetryAcceptance(
629
814
  now: Date = new Date(),
630
815
  policy: TelemetryAcceptancePolicy = DEFAULT_TELEMETRY_ACCEPTANCE_POLICY,
631
816
  ): TelemetryAcceptanceReport {
632
- const all = events.map((event, index) => ({
817
+ const { operations, hookRows } = partitionTelemetryUsage(events);
818
+ const all = operations.map((event, index) => ({
633
819
  event,
634
820
  index,
635
821
  time: timestampMillis(event.timestamp),
@@ -653,14 +839,15 @@ export function analyzeTelemetryAcceptance(
653
839
  telemetryCompletenessMetric(recent, policy),
654
840
  advisorBeforeRequirementWriteMetric(all, recentStart, policy),
655
841
  validationBeforeUpsertMetric(all, recentStart, policy),
842
+ lookupBeforeFirstEditMetric(hookRows, recentStart, policy),
656
843
  sourceLookupMetric(recent, policy),
657
844
  proofGapRecoveryMetric(recent),
658
845
  receiptFreshnessMetric(recent),
659
846
  repeatedMutationFailuresMetric(recent, policy),
660
847
  ];
661
848
  const diagnostics: string[] = [];
662
- if (events.length === 0) diagnostics.push("usage_log_empty");
663
- if (lastTime === null && events.length > 0) {
849
+ if (operations.length === 0) diagnostics.push("usage_log_empty");
850
+ if (lastTime === null && operations.length > 0) {
664
851
  diagnostics.push("usage_log_timestamps_unavailable");
665
852
  } else if (!fresh) {
666
853
  diagnostics.push(
@@ -676,9 +863,9 @@ export function analyzeTelemetryAcceptance(
676
863
  evaluatedAt: now.toISOString(),
677
864
  policy,
678
865
  scope: {
679
- totalEvents: events.length,
866
+ totalEvents: operations.length,
680
867
  evaluatedEvents: recent.length,
681
- truncated: events.length > recent.length,
868
+ truncated: operations.length > recent.length,
682
869
  firstTimestamp:
683
870
  firstTime === null ? null : new Date(firstTime).toISOString(),
684
871
  lastTimestamp:
@@ -713,14 +900,21 @@ const METRIC_DIAGNOSTICS: Readonly<
713
900
  severity: "warning",
714
901
  rank: 30,
715
902
  suggestion:
716
- "Run kb_semantic_advisor on the complete current requirement prose before its next upsert, preserve the returned source hash, and recheck telemetry.",
903
+ "Run kb_model with mode analyze (CLI: semantic-advisor) on the complete current requirement prose before its next upsert, preserve the returned source hash, and recheck telemetry.",
717
904
  },
718
905
  validation_before_upsert: {
719
906
  id: "mutation_validation_bypassed",
720
907
  severity: "warning",
721
908
  rank: 20,
722
909
  suggestion:
723
- "Run kb_validate_upsert for the exact payload no more than one hour before each sequential kb_upsert attempt.",
910
+ "Run kb_upsert with dryRun true (CLI: validate-upsert) for the exact payload no more than one hour before each sequential kb_upsert attempt.",
911
+ },
912
+ lookup_before_first_edit: {
913
+ id: "lookup_before_first_edit_bypassed",
914
+ severity: "warning",
915
+ rank: 35,
916
+ suggestion:
917
+ "Before a session's first edit of a requirement-linked file, run kb_search for the change (or kb_query with sourceFile for the file) and read the requirements it names; host hook rows in diagnostic mode record the order.",
724
918
  },
725
919
  source_lookup_zero_result_rate: {
726
920
  id: "source_lookup_zero_result_rate_high",
@@ -6,6 +6,8 @@ import {
6
6
  type TelemetryMetricId,
7
7
  type TelemetryUsageEvent,
8
8
  analyzeTelemetryAcceptance,
9
+ firstLinkedEdits,
10
+ partitionTelemetryUsage,
9
11
  } from "./telemetry-acceptance.js";
10
12
 
11
13
  export const TELEMETRY_REMEDIATION_VERSION =
@@ -46,6 +48,8 @@ export interface TelemetryRemediationReport {
46
48
  type IndexedEvent = {
47
49
  readonly event: TelemetryUsageEvent;
48
50
  readonly index: number;
51
+ /** 1-based `.kb/usage.log` line, counting host hook rows and blank lines. */
52
+ readonly logLine: number;
49
53
  readonly time: number | null;
50
54
  };
51
55
 
@@ -55,6 +59,7 @@ const RANKS: Readonly<
55
59
  repeated_mutation_failures: 10,
56
60
  validation_before_upsert: 20,
57
61
  advisor_before_requirement_write: 30,
62
+ lookup_before_first_edit: 35,
58
63
  e2e_receipt_freshness: 40,
59
64
  proof_gap_recovery: 50,
60
65
  source_lookup_zero_result_rate: 60,
@@ -138,7 +143,7 @@ function target(event: TelemetryUsageEvent): string {
138
143
 
139
144
  function reference(entry: IndexedEvent): TelemetryRemediationEventReference {
140
145
  return {
141
- logLine: entry.index + 1,
146
+ logLine: entry.logLine,
142
147
  requestId: entry.event.request_id ?? null,
143
148
  timestamp: entry.event.timestamp ?? null,
144
149
  tool: entry.event.tool ?? null,
@@ -155,7 +160,7 @@ function eventItem(
155
160
  action: string,
156
161
  ): TelemetryRemediationItem {
157
162
  return {
158
- id: `${metric}:line-${entry.index + 1}:${itemTarget}`,
163
+ id: `${metric}:line-${entry.logLine}:${itemTarget}`,
159
164
  rank: RANKS[metric],
160
165
  metric,
161
166
  scope: "event",
@@ -200,14 +205,18 @@ export function buildTelemetryRemediationReport(
200
205
  policy: TelemetryAcceptancePolicy = DEFAULT_TELEMETRY_ACCEPTANCE_POLICY,
201
206
  ): TelemetryRemediationReport {
202
207
  const acceptance = analyzeTelemetryAcceptance(events, now, policy);
203
- const all: IndexedEvent[] = events.map((event, index) => ({
208
+ const { operations, operationLines, hookRows } =
209
+ partitionTelemetryUsage(events);
210
+ const timeOf = (event: TelemetryUsageEvent): number | null =>
211
+ event.timestamp === undefined ||
212
+ !Number.isFinite(Date.parse(event.timestamp))
213
+ ? null
214
+ : Date.parse(event.timestamp);
215
+ const all: IndexedEvent[] = operations.map((event, index) => ({
204
216
  event,
205
217
  index,
206
- time:
207
- event.timestamp === undefined ||
208
- !Number.isFinite(Date.parse(event.timestamp))
209
- ? null
210
- : Date.parse(event.timestamp),
218
+ logLine: operationLines[index] ?? index + 1,
219
+ time: timeOf(event),
211
220
  }));
212
221
  const recentStart = Math.max(0, all.length - policy.eventLimit);
213
222
  const recent = all.slice(recentStart);
@@ -277,7 +286,7 @@ export function buildTelemetryRemediationReport(
277
286
  entry,
278
287
  target(entry.event),
279
288
  "No recent successful preflight matches this exact payload and correlation context.",
280
- "Run kb_validate_upsert for this exact payload in the same session/actor context before retrying once.",
289
+ "Run kb_upsert with dryRun true (CLI: validate-upsert) for this exact payload in the same session/actor context before retrying once.",
281
290
  ),
282
291
  );
283
292
  }
@@ -328,13 +337,33 @@ export function buildTelemetryRemediationReport(
328
337
  entry,
329
338
  requirementId,
330
339
  "No recent semantic-advisor event matches this requirement, source hash, and correlation context.",
331
- "Run kb_semantic_advisor on the complete prose in the same session/actor context before the next upsert.",
340
+ "Run kb_model with mode analyze (CLI: semantic-advisor) on the complete prose in the same session/actor context before the next upsert.",
332
341
  ),
333
342
  );
334
343
  }
335
344
  }
336
345
  }
337
346
 
347
+ if (isActionable(acceptance, "lookup_before_first_edit")) {
348
+ for (const { edit, lookedUp } of firstLinkedEdits(hookRows, recentStart)) {
349
+ if (lookedUp) continue;
350
+ items.push(
351
+ eventItem(
352
+ "lookup_before_first_edit",
353
+ {
354
+ event: edit.event,
355
+ index: edit.operationsBefore,
356
+ logLine: edit.logLine,
357
+ time: timeOf(edit.event),
358
+ },
359
+ edit.event.path ?? "unknown path",
360
+ "This session edited a requirement-linked file before any kb_search or kb_query.",
361
+ "Before the next edit of this file, run kb_search for the change or kb_query with this sourceFile, and read the requirements it names.",
362
+ ),
363
+ );
364
+ }
365
+ }
366
+
338
367
  if (isActionable(acceptance, "source_lookup_zero_result_rate")) {
339
368
  for (const entry of recent) {
340
369
  const sourceFile = args(entry.event).sourceFile;
@@ -478,6 +478,51 @@
478
478
  "text_ref": {
479
479
  "type": "string"
480
480
  },
481
+ "origin": {
482
+ "type": "object",
483
+ "required": [
484
+ "kind"
485
+ ],
486
+ "properties": {
487
+ "kind": {
488
+ "type": "string",
489
+ "enum": [
490
+ "human",
491
+ "agent",
492
+ "migration",
493
+ "import"
494
+ ],
495
+ "description": "Who authored the entity: human, agent, migration (backfilled by kibi migrate) or import."
496
+ },
497
+ "ref": {
498
+ "type": "string",
499
+ "minLength": 1,
500
+ "pattern": "\\S",
501
+ "description": "Source reference for the authored content: URL, document path, ticket, commit or conversation id."
502
+ },
503
+ "approved_by": {
504
+ "type": "string",
505
+ "minLength": 1,
506
+ "pattern": "\\S",
507
+ "description": "The person who reviewed and approved this entity's content. Distinct from the requirement-level approved_by of an exception."
508
+ },
509
+ "recorded_at": {
510
+ "type": "string",
511
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:[T ]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?)?$",
512
+ "description": "ISO-8601 time the provenance was recorded."
513
+ }
514
+ },
515
+ "additionalProperties": false
516
+ },
517
+ "expects": {
518
+ "type": "string",
519
+ "enum": [
520
+ "success",
521
+ "rejection",
522
+ "error"
523
+ ],
524
+ "description": "Scenario-only. The scenario's intended outcome. A scenario that expects success and assumes (via `assumes` facts) a value a current requirement forbids fails the scenario-feasibility check."
525
+ },
481
526
  "proof_exempt": {
482
527
  "type": "boolean",
483
528
  "description": "Requirement-only. Marks a current requirement as intentionally outside E2E-proof scope; requires proof_exempt_reason."
@@ -487,6 +532,33 @@
487
532
  "minLength": 1,
488
533
  "description": "Requirement-only. Required when proof_exempt is true; surfaces as the applicability reason in coverage rows."
489
534
  },
535
+ "approved_by": {
536
+ "type": "string",
537
+ "minLength": 1,
538
+ "pattern": "\\S",
539
+ "description": "Requirement-only. The human who approved this exception requirement. An exception (a requirement that exempts another and is specified_by a scenario) makes that success scenario feasible only when approved_by is set."
540
+ },
541
+ "approval_ref": {
542
+ "type": "string",
543
+ "minLength": 1,
544
+ "description": "Requirement-only. Optional reference to the approval decision record (ticket, ADR or review link) for an exception requirement."
545
+ },
546
+ "rationale": {
547
+ "type": "string",
548
+ "minLength": 1,
549
+ "pattern": "\\S",
550
+ "description": "Requirement-only. Why the requirement exists, in one or two sentences from whoever stated the intent. Explanation only: it is not part of the checked meaning."
551
+ },
552
+ "exempts_claims": {
553
+ "type": "array",
554
+ "minItems": 1,
555
+ "uniqueItems": true,
556
+ "items": {
557
+ "type": "string",
558
+ "pattern": "^CLAIM-[A-F0-9]{16}$"
559
+ },
560
+ "description": "Requirement-only. Narrows an exception requirement to individual clauses: the claim keys (from logic_claims) of the requirement it exempts whose constraints it waives. Without it the exception waives the whole exempted requirement."
561
+ },
490
562
  "semantic_text": {
491
563
  "type": "string",
492
564
  "description": "Requirement-only authored prose whose exact UTF-8 bytes anchor the semantic inventory without replacing text_ref evidence."
@@ -1155,6 +1227,15 @@
1155
1227
  "type": "string"
1156
1228
  }
1157
1229
  },
1230
+ "key_arguments": {
1231
+ "type": "array",
1232
+ "minItems": 1,
1233
+ "uniqueItems": true,
1234
+ "items": {
1235
+ "type": "string",
1236
+ "minLength": 1
1237
+ }
1238
+ },
1158
1239
  "aliases": {
1159
1240
  "type": "array",
1160
1241
  "items": {
@@ -1380,6 +1461,11 @@
1380
1461
  "argument_descriptions"
1381
1462
  ]
1382
1463
  },
1464
+ {
1465
+ "required": [
1466
+ "key_arguments"
1467
+ ]
1468
+ },
1383
1469
  {
1384
1470
  "required": [
1385
1471
  "aliases"
@@ -1546,11 +1632,47 @@
1546
1632
  "required": [
1547
1633
  "proof_exempt_reason"
1548
1634
  ]
1635
+ },
1636
+ {
1637
+ "required": [
1638
+ "approved_by"
1639
+ ]
1640
+ },
1641
+ {
1642
+ "required": [
1643
+ "approval_ref"
1644
+ ]
1645
+ },
1646
+ {
1647
+ "required": [
1648
+ "rationale"
1649
+ ]
1650
+ },
1651
+ {
1652
+ "required": [
1653
+ "exempts_claims"
1654
+ ]
1549
1655
  }
1550
1656
  ]
1551
1657
  }
1552
1658
  }
1553
1659
  },
1660
+ {
1661
+ "if": {
1662
+ "properties": {
1663
+ "type": {
1664
+ "const": "scenario"
1665
+ }
1666
+ }
1667
+ },
1668
+ "else": {
1669
+ "not": {
1670
+ "required": [
1671
+ "expects"
1672
+ ]
1673
+ }
1674
+ }
1675
+ },
1554
1676
  {
1555
1677
  "if": {
1556
1678
  "anyOf": [
@@ -23,6 +23,8 @@
23
23
  "consumes",
24
24
  "supersedes",
25
25
  "restates",
26
+ "assumes",
27
+ "exempts",
26
28
  "relates_to"
27
29
  ]
28
30
  },