kibi-cli 2.36.0 → 2.39.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 (224) hide show
  1. package/dist/cli-json-command.d.ts.map +1 -1
  2. package/dist/cli-json-command.js +4 -0
  3. package/dist/cli-operation-metadata.d.ts +1 -1
  4. package/dist/cli-operation-metadata.js +1 -1
  5. package/dist/cli-register-foundation.d.ts.map +1 -1
  6. package/dist/cli-register-foundation.js +2 -1
  7. package/dist/cli-register-maintenance.d.ts.map +1 -1
  8. package/dist/cli-register-maintenance.js +5 -0
  9. package/dist/cli-register-reporting.d.ts.map +1 -1
  10. package/dist/cli-register-reporting.js +1 -0
  11. package/dist/cli-validate.d.ts.map +1 -1
  12. package/dist/cli-validate.js +21 -2
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +19 -1
  15. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  16. package/dist/commands/aggregated-checks.js +89 -16
  17. package/dist/commands/coverage.d.ts +1 -0
  18. package/dist/commands/coverage.d.ts.map +1 -1
  19. package/dist/commands/coverage.js +40 -0
  20. package/dist/commands/doctor.d.ts +5 -0
  21. package/dist/commands/doctor.d.ts.map +1 -1
  22. package/dist/commands/doctor.js +70 -35
  23. package/dist/commands/github-init.d.ts.map +1 -1
  24. package/dist/commands/github-init.js +4 -2
  25. package/dist/commands/hook-managers.d.ts +43 -0
  26. package/dist/commands/hook-managers.d.ts.map +1 -0
  27. package/dist/commands/hook-managers.js +426 -0
  28. package/dist/commands/init.d.ts +1 -0
  29. package/dist/commands/init.d.ts.map +1 -1
  30. package/dist/commands/init.js +40 -5
  31. package/dist/commands/migrate.d.ts.map +1 -1
  32. package/dist/commands/migrate.js +9 -3
  33. package/dist/commands/sync/persistence.d.ts.map +1 -1
  34. package/dist/commands/sync/persistence.js +49 -1
  35. package/dist/commands/telemetry.d.ts +7 -0
  36. package/dist/commands/telemetry.d.ts.map +1 -0
  37. package/dist/commands/telemetry.js +23 -0
  38. package/dist/decision-firmness.d.ts.map +1 -1
  39. package/dist/decision-firmness.js +11 -14
  40. package/dist/engine-limits.d.ts.map +1 -1
  41. package/dist/engine-limits.js +8 -10
  42. package/dist/entity-body-context.d.ts.map +1 -1
  43. package/dist/entity-body-context.js +39 -36
  44. package/dist/extractors/markdown.d.ts +6 -0
  45. package/dist/extractors/markdown.d.ts.map +1 -1
  46. package/dist/extractors/markdown.js +21 -0
  47. package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
  48. package/dist/extractors/symbol-coordinates.js +23 -4
  49. package/dist/firm-decision-edit.d.ts.map +1 -1
  50. package/dist/firm-decision-edit.js +1 -3
  51. package/dist/intent-search.d.ts +5 -1
  52. package/dist/intent-search.d.ts.map +1 -1
  53. package/dist/intent-search.js +118 -33
  54. package/dist/logic/ir.d.ts.map +1 -1
  55. package/dist/logic/ir.js +82 -108
  56. package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
  57. package/dist/operations/bootstrap/discovery-evidence.js +44 -2
  58. package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
  59. package/dist/operations/bootstrap/discovery.js +1 -0
  60. package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
  61. package/dist/operations/bootstrap/guidance-actions.js +2 -1
  62. package/dist/operations/bootstrap/plugin-offers.d.ts +11 -2
  63. package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
  64. package/dist/operations/bootstrap/plugin-offers.js +48 -9
  65. package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
  66. package/dist/operations/proof/claim-bindings.js +1 -0
  67. package/dist/operations/proof/code-certificates.d.ts +2 -0
  68. package/dist/operations/proof/code-certificates.d.ts.map +1 -1
  69. package/dist/operations/proof/code-certificates.js +34 -14
  70. package/dist/operations/proof/code-models.d.ts.map +1 -1
  71. package/dist/operations/proof/code-models.js +19 -5
  72. package/dist/operations/proof/code-runner.d.ts +16 -0
  73. package/dist/operations/proof/code-runner.d.ts.map +1 -1
  74. package/dist/operations/proof/code-runner.js +42 -6
  75. package/dist/operations/proof/explain.d.ts +63 -0
  76. package/dist/operations/proof/explain.d.ts.map +1 -1
  77. package/dist/operations/proof/explain.js +162 -0
  78. package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
  79. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  80. package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
  81. package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
  82. package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
  83. package/dist/operations/semantic-advisor/case-preview.js +216 -0
  84. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  85. package/dist/operations/semantic-advisor/shared.js +3 -0
  86. package/dist/operations/semantic-advisor/types.d.ts +23 -0
  87. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  88. package/dist/plugins/approved-source-analyzers.generated.d.ts +11 -8
  89. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
  90. package/dist/plugins/approved-source-analyzers.generated.js +11 -8
  91. package/dist/plugins/compose-search-hints.d.ts +29 -0
  92. package/dist/plugins/compose-search-hints.d.ts.map +1 -0
  93. package/dist/plugins/compose-search-hints.js +94 -0
  94. package/dist/plugins/external-allowlist.d.ts +7 -0
  95. package/dist/plugins/external-allowlist.d.ts.map +1 -1
  96. package/dist/plugins/external-allowlist.js +11 -0
  97. package/dist/plugins/registry.d.ts +8 -1
  98. package/dist/plugins/registry.d.ts.map +1 -1
  99. package/dist/plugins/registry.js +22 -3
  100. package/dist/plugins/source-classification.d.ts +2 -2
  101. package/dist/plugins/source-classification.d.ts.map +1 -1
  102. package/dist/plugins/source-classification.js +25 -1
  103. package/dist/prolog/codec.d.ts.map +1 -1
  104. package/dist/prolog/codec.js +10 -20
  105. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
  106. package/dist/public/impact/coverage-depth-quality.js +32 -16
  107. package/dist/public/impact/full-kb-quality.d.ts +6 -0
  108. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  109. package/dist/public/impact/full-kb-quality.js +8 -3
  110. package/dist/public/impact/requirement-quality.d.ts.map +1 -1
  111. package/dist/public/impact/requirement-quality.js +56 -29
  112. package/dist/public/operations/catalog.d.ts +44 -4
  113. package/dist/public/operations/catalog.d.ts.map +1 -1
  114. package/dist/public/operations/check-executor.d.ts +6 -0
  115. package/dist/public/operations/check-executor.d.ts.map +1 -1
  116. package/dist/public/operations/check-executor.js +34 -2
  117. package/dist/public/operations/discovery-executors.d.ts +5 -1
  118. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  119. package/dist/public/operations/discovery-executors.js +65 -4
  120. package/dist/public/operations/evidence-floor.d.ts +8 -1
  121. package/dist/public/operations/evidence-floor.d.ts.map +1 -1
  122. package/dist/public/operations/evidence-floor.js +3 -4
  123. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  124. package/dist/public/operations/migration-plan.js +41 -10
  125. package/dist/public/operations/node-ports.d.ts.map +1 -1
  126. package/dist/public/operations/node-ports.js +3 -1
  127. package/dist/public/operations/repair-plan.d.ts +46 -0
  128. package/dist/public/operations/repair-plan.d.ts.map +1 -1
  129. package/dist/public/operations/repair-plan.js +110 -1
  130. package/dist/public/operations/schema6-check-actions.js +1 -1
  131. package/dist/public/operations/source-analysis-cache.d.ts +22 -0
  132. package/dist/public/operations/source-analysis-cache.d.ts.map +1 -0
  133. package/dist/public/operations/source-analysis-cache.js +157 -0
  134. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  135. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  136. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  137. package/dist/public/operations/specs/check.d.ts +1 -1
  138. package/dist/public/operations/specs/discovery.d.ts +7 -2
  139. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  140. package/dist/public/operations/specs/discovery.js +7 -2
  141. package/dist/public/operations/specs/mutation-schemas.d.ts +36 -1
  142. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  143. package/dist/public/operations/specs/mutation-schemas.js +30 -0
  144. package/dist/public/operations/specs/upsert.d.ts +36 -1
  145. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  146. package/dist/public/operations/symbol-granularity-check.d.ts +3 -1
  147. package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -1
  148. package/dist/public/operations/symbol-granularity-check.js +21 -7
  149. package/dist/public/proof-protocol.d.ts +6 -1
  150. package/dist/public/proof-protocol.d.ts.map +1 -1
  151. package/dist/public/proof-protocol.js +12 -3
  152. package/dist/public/proof-sources.d.ts +2 -0
  153. package/dist/public/proof-sources.d.ts.map +1 -1
  154. package/dist/public/proof-sources.js +32 -6
  155. package/dist/public/schemas/entity.d.ts.map +1 -1
  156. package/dist/public/schemas/entity.js +59 -0
  157. package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
  158. package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
  159. package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
  160. package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  161. package/dist/public/skills/kibi-usage/SKILL.md +50 -3
  162. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
  163. package/dist/public/skills/kibi-usage/resources/proof.md +13 -5
  164. package/dist/public/skills/kibi-usage/resources/workflows.md +10 -0
  165. package/dist/relationships/shards.d.ts +2 -0
  166. package/dist/relationships/shards.d.ts.map +1 -1
  167. package/dist/relationships/shards.js +25 -1
  168. package/dist/schemas/entity.schema.json +98 -1
  169. package/dist/search-answer.d.ts +3 -2
  170. package/dist/search-answer.d.ts.map +1 -1
  171. package/dist/search-answer.js +57 -4
  172. package/dist/search-hints.d.ts +58 -0
  173. package/dist/search-hints.d.ts.map +1 -0
  174. package/dist/search-hints.js +187 -0
  175. package/dist/search-ranking.d.ts +7 -0
  176. package/dist/search-ranking.d.ts.map +1 -1
  177. package/dist/search-ranking.js +54 -56
  178. package/dist/search-token-cache.d.ts +30 -0
  179. package/dist/search-token-cache.d.ts.map +1 -0
  180. package/dist/search-token-cache.js +86 -0
  181. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  182. package/dist/traceability/impact-knowledge.js +2 -0
  183. package/dist/traceability/temp-kb.d.ts.map +1 -1
  184. package/dist/traceability/temp-kb.js +11 -1
  185. package/dist/types/entities.d.ts +12 -0
  186. package/dist/types/entities.d.ts.map +1 -1
  187. package/dist/usage-telemetry.d.ts +20 -0
  188. package/dist/usage-telemetry.d.ts.map +1 -0
  189. package/dist/usage-telemetry.js +93 -0
  190. package/dist/utils/branch-resolver.d.ts.map +1 -1
  191. package/dist/utils/branch-resolver.js +1 -0
  192. package/dist/utils/rule-registry.generated.d.ts +5 -0
  193. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  194. package/dist/utils/rule-registry.generated.js +6 -0
  195. package/package.json +5 -4
  196. package/schema/entities.pl +12 -0
  197. package/src/public/impact/coverage-depth-quality.ts +59 -21
  198. package/src/public/impact/full-kb-quality.ts +15 -1
  199. package/src/public/impact/requirement-quality.ts +95 -38
  200. package/src/public/operations/check-executor.ts +41 -1
  201. package/src/public/operations/discovery-executors.ts +92 -4
  202. package/src/public/operations/evidence-floor.ts +15 -3
  203. package/src/public/operations/migration-plan.ts +41 -9
  204. package/src/public/operations/node-ports.ts +3 -1
  205. package/src/public/operations/repair-plan.ts +152 -1
  206. package/src/public/operations/schema6-check-actions.ts +1 -1
  207. package/src/public/operations/source-analysis-cache.ts +196 -0
  208. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  209. package/src/public/operations/specs/discovery.ts +8 -2
  210. package/src/public/operations/specs/mutation-schemas.ts +34 -0
  211. package/src/public/operations/symbol-granularity-check.ts +25 -5
  212. package/src/public/proof-protocol-types.d.ts +1 -1
  213. package/src/public/proof-protocol.ts +18 -4
  214. package/src/public/proof-sources.ts +37 -6
  215. package/src/public/schemas/entity.ts +65 -0
  216. package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
  217. package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
  218. package/src/public/skills/kibi-decisions/SKILL.md +7 -2
  219. package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  220. package/src/public/skills/kibi-usage/SKILL.md +50 -3
  221. package/src/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
  222. package/src/public/skills/kibi-usage/resources/proof.md +13 -5
  223. package/src/public/skills/kibi-usage/resources/workflows.md +10 -0
  224. package/src/schemas/entity.schema.json +98 -1
@@ -14,4 +14,11 @@ export declare function allowsExternalSemanticClassifier(operationName: string):
14
14
  */
15
15
  export declare const EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS: readonly ["kb_model_requirement"];
16
16
  export declare function allowsExternalVocabularyAlignment(operationName: string): boolean;
17
+ /**
18
+ * Operations that may call external kibi.search-hints.v1 providers. Hints are
19
+ * advice next to a search answer; checks, proofs and every write stay
20
+ * builtin-only.
21
+ */
22
+ export declare const EXTERNAL_SEARCH_HINTS_OPERATIONS: readonly ["kb_search"];
23
+ export declare function allowsExternalSearchHints(operationName: string): boolean;
17
24
  //# sourceMappingURL=external-allowlist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-allowlist.d.ts","sourceRoot":"","sources":["../../src/plugins/external-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,uCAAuC,uDAG1C,CAAC;AAGX,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC;AAK3D,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED;;;;GAIG;AAEH,eAAO,MAAM,wCAAwC,mCAE3C,CAAC;AAGX,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT"}
1
+ {"version":3,"file":"external-allowlist.d.ts","sourceRoot":"","sources":["../../src/plugins/external-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,uCAAuC,uDAG1C,CAAC;AAGX,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC;AAK3D,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED;;;;GAIG;AAEH,eAAO,MAAM,wCAAwC,mCAE3C,CAAC;AAGX,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT;AAED;;;;GAIG;AAEH,eAAO,MAAM,gCAAgC,wBAAyB,CAAC;AAGvE,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAIxE"}
@@ -27,3 +27,14 @@ export const EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS = [
27
27
  export function allowsExternalVocabularyAlignment(operationName) {
28
28
  return EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS.includes(operationName);
29
29
  }
30
+ /**
31
+ * Operations that may call external kibi.search-hints.v1 providers. Hints are
32
+ * advice next to a search answer; checks, proofs and every write stay
33
+ * builtin-only.
34
+ */
35
+ // implements REQ-kibi-search-hints-host
36
+ export const EXTERNAL_SEARCH_HINTS_OPERATIONS = ["kb_search"];
37
+ // implements REQ-kibi-search-hints-host
38
+ export function allowsExternalSearchHints(operationName) {
39
+ return EXTERNAL_SEARCH_HINTS_OPERATIONS.includes(operationName);
40
+ }
@@ -1,4 +1,4 @@
1
- import { type CapabilityId, type KibiPluginV1, type OntologyPackV1, type PluginMode, type PluginPermissions, type PluginProviderStamp, type ProjectKibiConfig, type SemanticClassifierV1, type SymbolExtractorV1, type SymbolExtractorV2, type VocabularyAlignmentV1 } from "kibi-plugin-sdk";
1
+ import { type CapabilityId, type KibiPluginV1, type OntologyPackV1, type PluginMode, type PluginPermissions, type PluginProviderStamp, type ProjectKibiConfig, type SearchHintsV1, type SemanticClassifierV1, type SymbolExtractorV1, type SymbolExtractorV2, type VocabularyAlignmentV1 } from "kibi-plugin-sdk";
2
2
  import { type LoadPluginOptions, loadPluginPackage } from "./load-plugin.js";
3
3
  export type BuiltinPluginFactory = () => KibiPluginV1 | Promise<KibiPluginV1>;
4
4
  export type CapabilityProviderBinding<T> = Readonly<{
@@ -32,6 +32,12 @@ export type CapabilityRegistryOptions = Readonly<{
32
32
  loadPlugin?: (workspaceRoot: string, packageName: string, options?: LoadPluginOptions) => Promise<Awaited<ReturnType<typeof loadPluginPackage>>>;
33
33
  loadPluginOptions?: LoadPluginOptions;
34
34
  }>;
35
+ /**
36
+ * Search hints have no builtin answer: without a configured provider there
37
+ * are no hints. A builtin package that predates the capability resolves to
38
+ * this host no-op instead of failing the search.
39
+ */
40
+ export declare const NO_SEARCH_HINTS: SearchHintsV1;
35
41
  /**
36
42
  * Minimal builtin used when no factory is injected and the builtin package is
37
43
  * not yet wired. Satisfies kibi.plugin.v1 validation.
@@ -61,6 +67,7 @@ export declare class CapabilityRegistry {
61
67
  resolveSymbolExtractors(): Promise<CapabilityModeResolution<SymbolExtractorV1>>;
62
68
  resolveSymbolExtractorsV2(): Promise<CapabilityModeResolution<SymbolExtractorV2>>;
63
69
  resolveVocabularyAlignment(): Promise<CapabilityModeResolution<VocabularyAlignmentV1>>;
70
+ resolveSearchHints(): Promise<CapabilityModeResolution<SearchHintsV1>>;
64
71
  resolveCapability(capabilityId: CapabilityId): Promise<CapabilityModeResolution<unknown>>;
65
72
  /**
66
73
  * Canonical providers only (builtin + optional replace + augment).
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,YAAY,EAGjB,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAKtB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,KAAK,qBAAqB,EAG3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK7E,MAAM,MAAM,oBAAoB,GAAG,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAG9E,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI,QAAQ,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,CAAC,CAAC;IACd,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC,CAAC;AAGH,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,QAAQ,CAAC;IACjD,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC;IACtC,wDAAwD;IACxD,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7C,0DAA0D;IAC1D,OAAO,EAAE,SAAS,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,+DAA+D;IAC/D,MAAM,EAAE,SAAS,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;CACjD,CAAC,CAAC;AAGH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,sEAAsE;IACtE,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,kDAAkD;IAClD,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,iBAAiB,CAAC;IAC1D,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CACX,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,iBAAiB,KACxB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC5D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC,CAAC;AAmBH;;;GAGG;AAEH,wBAAgB,uBAAuB,IAAI,YAAY,CAgEtD;AA4GD;;;;GAIG;AAEH,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+C;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAEzB;IACF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgC;IAClE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAE/D,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IACJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG5B;gBAEQ,OAAO,EAAE,yBAAyB;IASxC,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC;IAOzC,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAQ9C,0BAA0B,IAAI,OAAO,CACzC,wBAAwB,CAAC,oBAAoB,CAAC,CAC/C;IAMK,oBAAoB,IAAI,OAAO,CACnC,wBAAwB,CAAC,cAAc,CAAC,CACzC;IAMK,uBAAuB,IAAI,OAAO,CACtC,wBAAwB,CAAC,iBAAiB,CAAC,CAC5C;IAOK,yBAAyB,IAAI,OAAO,CACxC,wBAAwB,CAAC,iBAAiB,CAAC,CAC5C;IAMK,0BAA0B,IAAI,OAAO,CACzC,wBAAwB,CAAC,qBAAqB,CAAC,CAChD;IAMK,iBAAiB,CACrB,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAc7C;;;OAGG;IACH,kBAAkB,CAAC,CAAC,EAClB,UAAU,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACtC,SAAS,yBAAyB,CAAC,CAAC,CAAC,EAAE;YAO5B,yBAAyB;YAyFzB,mBAAmB;CAsBlC;AAED;;GAEG;AAEH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IAEpE,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1D,WAAW,CACT,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,eAAe,CAAC,GACzD,kBAAkB;IAWrB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAI9D,KAAK,IAAI,IAAI;CAGd;AAGD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CAEpB;AAGD,wBAAgB,6BAA6B,IAAI,uBAAuB,CAEvE;AAGD,MAAM,MAAM,+BAA+B,GAAG,yBAAyB,GAAG;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,uBAAuB,CAAC;CAC1C,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,wBAAwB,CACtC,sBAAsB,EAAE,MAAM,GAAG,+BAA+B,EAChE,OAAO,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,eAAe,CAAC,GAAG;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,uBAAuB,CAAC;CAC1C,GACA,kBAAkB,CAoBpB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
- import { CHECK_POLICY_CAPABILITY_ID, CHECK_POLICY_CONTRACT_VERSION, KIBI_PLUGIN_API_VERSION, ONTOLOGY_PACK_CAPABILITY_ID, SEMANTIC_CLASSIFIER_CAPABILITY_ID, SYMBOL_EXTRACTOR_CAPABILITY_ID, SYMBOL_EXTRACTOR_V2_CAPABILITY_ID, VOCABULARY_ALIGNMENT_CAPABILITY_ID, defineKibiPlugin, validateKibiPlugin, } from "kibi-plugin-sdk";
18
+ import { CHECK_POLICY_CAPABILITY_ID, CHECK_POLICY_CONTRACT_VERSION, KIBI_PLUGIN_API_VERSION, ONTOLOGY_PACK_CAPABILITY_ID, SEARCH_HINTS_CAPABILITY_ID, SEMANTIC_CLASSIFIER_CAPABILITY_ID, SYMBOL_EXTRACTOR_CAPABILITY_ID, SYMBOL_EXTRACTOR_V2_CAPABILITY_ID, VOCABULARY_ALIGNMENT_CAPABILITY_ID, defineKibiPlugin, validateKibiPlugin, } from "kibi-plugin-sdk";
19
19
  import { loadPluginPackage } from "./load-plugin.js";
20
20
  import { readProjectKibiConfig } from "./project-config.js";
21
21
  import { PluginResolutionError } from "./resolve-package.js";
@@ -26,6 +26,18 @@ const CAPABILITY_SLOT = {
26
26
  [SYMBOL_EXTRACTOR_V2_CAPABILITY_ID]: "symbolExtractorV2",
27
27
  [VOCABULARY_ALIGNMENT_CAPABILITY_ID]: "vocabularyAlignment",
28
28
  [CHECK_POLICY_CAPABILITY_ID]: "checkPolicy",
29
+ [SEARCH_HINTS_CAPABILITY_ID]: "searchHints",
30
+ };
31
+ /**
32
+ * Search hints have no builtin answer: without a configured provider there
33
+ * are no hints. A builtin package that predates the capability resolves to
34
+ * this host no-op instead of failing the search.
35
+ */
36
+ // implements REQ-kibi-search-hints-host
37
+ export const NO_SEARCH_HINTS = {
38
+ id: "kibi-host.search-hints.none",
39
+ model: "none",
40
+ hint: () => ({ hints: [] }),
29
41
  };
30
42
  /**
31
43
  * Minimal builtin used when no factory is injected and the builtin package is
@@ -214,6 +226,10 @@ export class CapabilityRegistry {
214
226
  async resolveVocabularyAlignment() {
215
227
  return this.resolveCapability(VOCABULARY_ALIGNMENT_CAPABILITY_ID);
216
228
  }
229
+ // implements REQ-kibi-search-hints-host
230
+ async resolveSearchHints() {
231
+ return this.resolveCapability(SEARCH_HINTS_CAPABILITY_ID);
232
+ }
217
233
  async resolveCapability(capabilityId) {
218
234
  const cached = this.capabilityCache.get(capabilityId);
219
235
  if (cached)
@@ -240,7 +256,10 @@ export class CapabilityRegistry {
240
256
  }
241
257
  async buildCapabilityResolution(capabilityId) {
242
258
  const builtinPlugin = await this.getBuiltinPlugin();
243
- const builtinCapability = capabilityFromPlugin(builtinPlugin, capabilityId);
259
+ const builtinCapability = capabilityFromPlugin(builtinPlugin, capabilityId) ??
260
+ (capabilityId === SEARCH_HINTS_CAPABILITY_ID
261
+ ? NO_SEARCH_HINTS
262
+ : undefined);
244
263
  if (!builtinCapability) {
245
264
  throw new PluginResolutionError("BUILTIN_MISSING_CAPABILITY", `Builtin plugin '${builtinPlugin.id}' does not provide ${capabilityId}`);
246
265
  }
@@ -255,7 +274,7 @@ export class CapabilityRegistry {
255
274
  [builtinPlugin.id, "kibi-plugin-builtin"],
256
275
  ]);
257
276
  const providerIds = new Set([
258
- capabilityFromPlugin(builtinPlugin, capabilityId)?.id ?? builtinPlugin.id,
277
+ builtinCapability.id ?? builtinPlugin.id,
259
278
  ]);
260
279
  for (const entry of relevant) {
261
280
  const modeConfig = entry.capabilities[capabilityId];
@@ -1,11 +1,11 @@
1
1
  export type SourceClassification = Readonly<{
2
2
  kind: "language";
3
3
  language: string;
4
- source: "extension" | "shebang" | "explicit";
4
+ source: "extension" | "shebang" | "explicit" | "content";
5
5
  }> | Readonly<{
6
6
  kind: "file-level";
7
7
  language: string;
8
- source: "extension" | "shebang" | "explicit";
8
+ source: "extension" | "shebang" | "explicit" | "content";
9
9
  reason: string;
10
10
  }> | Readonly<{
11
11
  kind: "ambiguous";
@@ -1 +1 @@
1
- {"version":3,"file":"source-classification.d.ts","sourceRoot":"","sources":["../../src/plugins/source-classification.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;CAC9C,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAsGP;;;;GAIG;AAEH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,6EAA6E;AAE7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED,wEAAwE;AAExE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED,+EAA+E;AAE/E,wBAAgB,oBAAoB,IAAI,SAAS,MAAM,EAAE,CAExD;AAuQD,qGAAqG;AACrG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,oBAAoB,CA2JtB"}
1
+ {"version":3,"file":"source-classification.d.ts","sourceRoot":"","sources":["../../src/plugins/source-classification.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;CAC1D,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAwGP;;;;GAIG;AAEH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,6EAA6E;AAE7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED,wEAAwE;AAExE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED,+EAA+E;AAE/E,wBAAgB,oBAAoB,IAAI,SAAS,MAAM,EAAE,CAExD;AA2RD,qGAAqG;AACrG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,oBAAoB,CAiKtB"}
@@ -1,4 +1,5 @@
1
1
  const MAX_SHEBANG_LENGTH = 512;
2
+ const MAX_CONTENT_SNIFF_LENGTH = 65_536;
2
3
  const MAX_SHEBANG_TOKENS = 16;
3
4
  const MAX_TOKEN_LENGTH = 128;
4
5
  const EXTENSIONS = {
@@ -33,6 +34,7 @@ const EXTENSIONS = {
33
34
  ".mjs": { kind: "language", language: "javascript" },
34
35
  ".mts": { kind: "language", language: "typescript" },
35
36
  ".php": { kind: "language", language: "php" },
37
+ ".plt": { kind: "language", language: "prolog" },
36
38
  ".pl": {
37
39
  kind: "ambiguous",
38
40
  language: "perl-or-prolog",
@@ -112,7 +114,6 @@ const FILE_LEVEL_LANGUAGES = new Set([
112
114
  "html",
113
115
  "json",
114
116
  "perl",
115
- "prolog",
116
117
  "shell",
117
118
  "sql",
118
119
  "yaml",
@@ -341,6 +342,24 @@ function shebangFor(content) {
341
342
  }
342
343
  return interpreterFor(words[0]);
343
344
  }
345
+ // Lines only Prolog source starts with: a directive, a clause or DCG rule
346
+ // whose head is an atom or compound term, or a one-line fact.
347
+ const PROLOG_LINE = /^(?::-\s|[a-z][A-Za-z0-9_]*(?:\([^\n]*\))?\s*(?::-|-->)(?:\s|$)|[a-z][A-Za-z0-9_]*\([^\n;]*\)\.[ \t]*(?:%[^\n]*)?$)/m;
348
+ // Lines only Perl source starts with.
349
+ const PERL_LINE = /^(?:\s*use\s+(?:strict|warnings|utf8|[A-Z][\w:]*)\b[^\n]*;|\s*package\s+[A-Za-z_][\w:]*\s*;|\s*sub\s+[A-Za-z_]\w*\s*\{|\s*my\s+[$@%]|=(?:pod|head1)\b|__(?:END|DATA)__$)/m;
350
+ /**
351
+ * Resolves a `.pl` file without a shebang to Prolog or Perl when only one of
352
+ * them matches its leading content. Both or neither leaves it ambiguous.
353
+ */
354
+ // implements REQ-multilingual-language-catalog
355
+ function perlOrPrologByContent(content) {
356
+ const prefix = content.slice(0, MAX_CONTENT_SNIFF_LENGTH);
357
+ const prolog = PROLOG_LINE.test(prefix);
358
+ const perl = PERL_LINE.test(prefix);
359
+ if (prolog === perl)
360
+ return undefined;
361
+ return prolog ? "prolog" : "perl";
362
+ }
344
363
  function classificationForLanguage(language, source) {
345
364
  if (FILE_LEVEL_LANGUAGES.has(language)) {
346
365
  return {
@@ -398,6 +417,11 @@ export function classifySource(filePath, content, explicitLanguageHint) {
398
417
  return classificationForLanguage(explicit, "explicit");
399
418
  }
400
419
  if (extension?.kind === "ambiguous") {
420
+ const contentLanguage = shebang === undefined && extension.language === "perl-or-prolog"
421
+ ? perlOrPrologByContent(content)
422
+ : undefined;
423
+ if (contentLanguage !== undefined)
424
+ return classificationForLanguage(contentLanguage, "content");
401
425
  if (shebang === undefined) {
402
426
  return {
403
427
  kind: "ambiguous",
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/prolog/codec.ts"],"names":[],"mappings":"AAUA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAU5D;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAO9B;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAClC,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG,IAAI,CAEV;AAID,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAoCT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED,wBAAgB,sBAAsB,CAEpC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqB3E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuD3E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA6D5D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7E;AAuFD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtE;AAYD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAenD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmBlE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAoBzE;AAyCD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CA6DjE"}
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/prolog/codec.ts"],"names":[],"mappings":"AAUA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAU5D;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAO9B;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAClC,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG,IAAI,CAEV;AAID,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAoCT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED,wBAAgB,sBAAsB,CAEpC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqB3E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuD3E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA6D5D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7E;AA2ED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtE;AAYD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAenD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmBlE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAoBzE;AAyCD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CA6DjE"}
@@ -274,27 +274,25 @@ export function splitTopLevelGeneral(str, delimiter) {
274
274
  // implements REQ-009
275
275
  return scanTopLevelGeneral(str, delimiter).parts;
276
276
  }
277
+ // Parts are sliced from the input rather than built a character at a time:
278
+ // candidate pages run to megabytes, and per-character concatenation made
279
+ // scanning them most of a search's parsing time.
277
280
  function scanTopLevelGeneral(str, delimiter) {
278
281
  const results = [];
279
- let current = "";
282
+ let partStart = 0;
280
283
  let quote = null;
281
284
  const delimiters = [];
282
285
  let balanced = true;
283
286
  for (let i = 0; i < str.length; i++) {
284
287
  const char = str[i];
285
288
  if (quote !== null) {
286
- current += char;
287
289
  if (char === "\\") {
288
- const escaped = str[i + 1];
289
- if (escaped !== undefined) {
290
- current += escaped;
290
+ if (i + 1 < str.length)
291
291
  i++;
292
- }
293
292
  }
294
293
  else if (char === quote) {
295
294
  const doubledPrologQuote = quote === "'" && str[i + 1] === "'";
296
295
  if (doubledPrologQuote) {
297
- current += str[i + 1] ?? "";
298
296
  i++;
299
297
  }
300
298
  else {
@@ -305,12 +303,10 @@ function scanTopLevelGeneral(str, delimiter) {
305
303
  }
306
304
  if (char === "'" || char === '"') {
307
305
  quote = char;
308
- current += char;
309
306
  continue;
310
307
  }
311
308
  if (char === "[" || char === "(" || char === "{") {
312
309
  delimiters.push(char);
313
- current += char;
314
310
  continue;
315
311
  }
316
312
  if (char === "]" || char === ")" || char === "}") {
@@ -321,25 +317,19 @@ function scanTopLevelGeneral(str, delimiter) {
321
317
  else {
322
318
  delimiters.pop();
323
319
  }
324
- current += char;
325
320
  continue;
326
321
  }
327
322
  if (delimiters.length === 0 &&
328
323
  delimiter.length > 0 &&
329
324
  str.startsWith(delimiter, i)) {
330
- if (current) {
331
- results.push(current);
332
- current = "";
333
- }
325
+ if (i > partStart)
326
+ results.push(str.slice(partStart, i));
334
327
  i += delimiter.length - 1;
328
+ partStart = i + 1;
335
329
  }
336
- else {
337
- current += char;
338
- }
339
- }
340
- if (current) {
341
- results.push(current);
342
330
  }
331
+ if (str.length > partStart)
332
+ results.push(str.slice(partStart));
343
333
  return {
344
334
  parts: results,
345
335
  balanced: balanced && quote === null && delimiters.length === 0,
@@ -1 +1 @@
1
- {"version":3,"file":"coverage-depth-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/coverage-depth-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAsIpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAI1E;AAgLD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,SAAS,gBAAgB,EAAE,EAC5C,kBAAkB,GAAE,WAAW,CAC7B,MAAM,EACN,QAAQ,CAAC;IACP,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC,CACS,GACZ,SAAS,iBAAiB,EAAE,CAmB9B;AAID;;;;;GAKG;AAEH,wBAAgB,oCAAoC,CAClD,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAC3C,SAAS,iBAAiB,EAAE,CA2D9B"}
1
+ {"version":3,"file":"coverage-depth-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/coverage-depth-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAgLpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAI1E;AA2KD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,SAAS,gBAAgB,EAAE,EAC5C,kBAAkB,GAAE,WAAW,CAC7B,MAAM,EACN,QAAQ,CAAC;IACP,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC,CACS,GACZ,SAAS,iBAAiB,EAAE,CAoB9B;AAID;;;;;GAKG;AAEH,wBAAgB,oCAAoC,CAClD,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAC3C,SAAS,iBAAiB,EAAE,CA2D9B"}
@@ -1,4 +1,29 @@
1
1
  import { COARSE_GRANULARITY_REASONS } from "../symbol-granularity.generated.js";
2
+ function incomingKey(type, relationshipType, targetId) {
3
+ return `${type}\0${relationshipType}\0${targetId}`;
4
+ }
5
+ function coverageIndex(manifestResults) {
6
+ const incomingByTarget = new Map();
7
+ // A result linking the same target twice is listed twice; every reader
8
+ // dedupes by entity id.
9
+ for (const result of manifestResults) {
10
+ for (const relationship of result.relationships) {
11
+ const key = incomingKey(result.entity.type, relationship.type, relationship.to);
12
+ const list = incomingByTarget.get(key);
13
+ if (list === undefined)
14
+ incomingByTarget.set(key, [result.entity]);
15
+ else
16
+ list.push(result.entity);
17
+ }
18
+ }
19
+ return {
20
+ resultsById: new Map(manifestResults.map((manifestResult) => [
21
+ manifestResult.entity.id,
22
+ manifestResult,
23
+ ])),
24
+ incomingByTarget,
25
+ };
26
+ }
2
27
  function entitiesById(manifestResults) {
3
28
  return new Map(manifestResults.map((result) => [result.entity.id, result.entity]));
4
29
  }
@@ -11,14 +36,7 @@ function outgoingTargets(lookup) {
11
36
  });
12
37
  }
13
38
  function incomingSources(lookup) {
14
- return lookup.manifestResults.flatMap((result) => {
15
- if (result.entity.type !== lookup.type)
16
- return [];
17
- return result.relationships.some((relationship) => relationship.type === lookup.relationshipType &&
18
- relationship.to === lookup.targetId)
19
- ? [result.entity]
20
- : [];
21
- });
39
+ return (lookup.index.incomingByTarget.get(incomingKey(lookup.type, lookup.relationshipType, lookup.targetId)) ?? []);
22
40
  }
23
41
  function uniqueEntities(entities) {
24
42
  return [
@@ -129,11 +147,8 @@ function createDiagnostic(coverage, proofEvidence) {
129
147
  },
130
148
  };
131
149
  }
132
- function coverageForRequirement(result, manifestResults, entities) {
133
- const resultsById = new Map(manifestResults.map((manifestResult) => [
134
- manifestResult.entity.id,
135
- manifestResult,
136
- ]));
150
+ function coverageForRequirement(result, index, entities) {
151
+ const resultsById = index.resultsById;
137
152
  const scenarios = outgoingTargets({
138
153
  result,
139
154
  relationshipType: "specified_by",
@@ -154,7 +169,7 @@ function coverageForRequirement(result, manifestResults, entities) {
154
169
  entities,
155
170
  }),
156
171
  ...incomingSources({
157
- manifestResults,
172
+ index,
158
173
  targetId: result.entity.id,
159
174
  relationshipType: "validates",
160
175
  type: "test",
@@ -164,7 +179,7 @@ function coverageForRequirement(result, manifestResults, entities) {
164
179
  const scenarioResult = resultsById.get(scenario.id);
165
180
  return [
166
181
  ...incomingSources({
167
- manifestResults,
182
+ index,
168
183
  targetId: scenario.id,
169
184
  relationshipType: "validates",
170
185
  type: "test",
@@ -215,11 +230,12 @@ function isReviewableRequirement(requirement, superseded) {
215
230
  export function createCoverageDepthQualityDiagnostics(manifestResults, proofByRequirement = new Map()) {
216
231
  const entities = entitiesById(manifestResults);
217
232
  const superseded = supersededRequirementIds(manifestResults);
233
+ const index = coverageIndex(manifestResults);
218
234
  return manifestResults
219
235
  .filter((result) => result.entity.type === "req" &&
220
236
  isReviewableRequirement(result.entity, superseded))
221
237
  .flatMap((result) => {
222
- const diagnostic = createDiagnostic(coverageForRequirement(result, manifestResults, entities), proofByRequirement.get(result.entity.id));
238
+ const diagnostic = createDiagnostic(coverageForRequirement(result, index, entities), proofByRequirement.get(result.entity.id));
223
239
  return diagnostic === undefined ? [] : [diagnostic];
224
240
  })
225
241
  .toSorted((left, right) => (left.entityId ?? "").localeCompare(right.entityId ?? ""));
@@ -9,6 +9,12 @@ type FullKbQualityDiagnosticsOptions = {
9
9
  readonly now?: Date;
10
10
  readonly proofSnapshot?: string;
11
11
  readonly checkedAt?: string;
12
+ /**
13
+ * The per-contract receipt bindings kb_coverage uses (a Prolog
14
+ * TestId -> binding hash dict), or null for strict snapshot binding. Read
15
+ * lazily so a check without proof evidence never pays for it.
16
+ */
17
+ readonly proofTestBindings?: () => Promise<string | null>;
12
18
  };
13
19
  export declare function loadKbExtractionResults(prolog: Pick<PrologPort, "query" | "queryEntities">): Promise<ExtractionResult[]>;
14
20
  export declare function passingE2eStage(passingE2e: unknown): Readonly<Record<string, unknown>> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"full-kb-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/full-kb-quality.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAatC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAcjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,KAAK,+BAA+B,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAqgBF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,GAClD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8C7B;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,GAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAM/C;AA2ID,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAmCvC"}
1
+ {"version":3,"file":"full-kb-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/full-kb-quality.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAatC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAcjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,KAAK,+BAA+B,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3D,CAAC;AAqgBF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,GAClD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8C7B;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,GAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAM/C;AAkJD,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAoCvC"}
@@ -450,7 +450,7 @@ export function passingE2eStage(passingE2e) {
450
450
  function stringArrayField(value) {
451
451
  return Array.isArray(value) ? value.map(String) : undefined;
452
452
  }
453
- async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot, checkedAt) {
453
+ async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot, checkedAt, proofTestBindings) {
454
454
  if (proofSnapshot === undefined ||
455
455
  checkedAt === undefined ||
456
456
  requirementCount === 0) {
@@ -458,11 +458,16 @@ async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot
458
458
  }
459
459
  let payload;
460
460
  try {
461
+ // Judge receipts with the binding kb_coverage uses; under strict snapshot
462
+ // binding any unrelated change since kibi prove would read every receipt
463
+ // as stale and bring back the weak-depth review.
464
+ const bindings = (await proofTestBindings?.()) ?? null;
465
+ const binding = bindings === null ? "strict_snapshot, _{}" : `per_contract, ${bindings}`;
461
466
  // W1 push-down: the slim evidence projection returns only the fields the
462
467
  // quality diagnostics consume, keeping the response far below the output
463
468
  // capacity limit on large KBs (the full coverage report rows were the
464
469
  // original ENOBUFS offender).
465
- payload = await runOperationJsonQuery(prolog, "discovery.pl", `discovery:coverage_evidence_json(${toPrologList([])}, ${toPrologAtom(proofSnapshot)}, ${toPrologAtom(checkedAt)}, ${PROOF_RECEIPT_MAX_AGE_SECONDS}, JsonString)`, "Quality diagnostic coverage evidence");
470
+ payload = await runOperationJsonQuery(prolog, "discovery.pl", `discovery:coverage_evidence_json(${toPrologList([])}, ${binding}, ${toPrologAtom(proofSnapshot)}, ${toPrologAtom(checkedAt)}, ${PROOF_RECEIPT_MAX_AGE_SECONDS}, JsonString)`, "Quality diagnostic coverage evidence");
466
471
  }
467
472
  catch {
468
473
  // Quality diagnostics must fail closed when the optional proof readback is
@@ -542,7 +547,7 @@ export async function collectFullKbQualityDiagnostics(options) {
542
547
  loadKbExtractionResults(options.prolog),
543
548
  collectTelemetryDiagnostics(options.workspaceRoot, options.now ?? new Date()),
544
549
  ]);
545
- const proofEvidence = await loadCoverageProofEvidence(options.prolog, manifestResults.filter((result) => result.entity.type === "req").length, options.proofSnapshot, options.checkedAt);
550
+ const proofEvidence = await loadCoverageProofEvidence(options.prolog, manifestResults.filter((result) => result.entity.type === "req").length, options.proofSnapshot, options.checkedAt, options.proofTestBindings);
546
551
  const coverageDepthDiagnostics = createCoverageDepthQualityDiagnostics(manifestResults, proofEvidence);
547
552
  const diagnostics = [
548
553
  ...telemetryDiagnostics,
@@ -1 +1 @@
1
- {"version":3,"file":"requirement-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/requirement-quality.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAC;AA2PvE,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,oCAAoC,GAC5C,oBAAoB,EAAE,CAMxB"}
1
+ {"version":3,"file":"requirement-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/requirement-quality.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAC;AAoTvE,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,oCAAoC,GAC5C,oBAAoB,EAAE,CAMxB"}
@@ -42,41 +42,67 @@ function targetHasType(targetId, type, typesByEntityId) {
42
42
  const targetType = typesByEntityId.get(targetId);
43
43
  return targetType === undefined || targetType === type;
44
44
  }
45
- function collectFanout(requirementId, results, typesByEntityId) {
46
- const implementingSymbolIds = [];
47
- const scenarioIds = [];
48
- const testIds = [];
49
- const dependentRequirementIds = [];
45
+ /** One pass over every relationship, so each requirement's fanout is a lookup. */
46
+ function fanoutIndex(results) {
47
+ const relationshipsByEntityId = new Map();
48
+ const implementerIdsByRequirementId = new Map();
49
+ const dependentRequirementIdsByRequirementId = new Map();
50
+ const append = (index, key, value) => {
51
+ const list = index.get(key);
52
+ if (list === undefined)
53
+ index.set(key, [value]);
54
+ else
55
+ list.push(value);
56
+ };
50
57
  for (const result of results) {
58
+ const relationships = relationshipsByEntityId.get(result.entity.id);
59
+ if (relationships === undefined) {
60
+ relationshipsByEntityId.set(result.entity.id, [...result.relationships]);
61
+ }
62
+ else {
63
+ relationships.push(...result.relationships);
64
+ }
51
65
  for (const relationship of result.relationships) {
52
- if (relationship.type === "implements" &&
53
- relationship.to === requirementId) {
54
- implementingSymbolIds.push(result.entity.id);
55
- }
56
- if (result.entity.id === requirementId &&
57
- relationship.type === "specified_by" &&
58
- targetHasType(relationship.to, "scenario", typesByEntityId)) {
59
- scenarioIds.push(relationship.to);
66
+ if (relationship.type === "implements") {
67
+ append(implementerIdsByRequirementId, relationship.to, result.entity.id);
60
68
  }
61
- if (result.entity.id === requirementId &&
62
- (relationship.type === "verified_by" ||
63
- relationship.type === "covered_by") &&
64
- targetHasType(relationship.to, "test", typesByEntityId)) {
65
- testIds.push(relationship.to);
66
- }
67
- if (relationship.type === "depends_on") {
68
- if (result.entity.id === requirementId &&
69
- targetHasType(relationship.to, "req", typesByEntityId)) {
70
- dependentRequirementIds.push(relationship.to);
71
- }
72
- if (relationship.to === requirementId && result.entity.type === "req") {
73
- dependentRequirementIds.push(result.entity.id);
74
- }
69
+ if (relationship.type === "depends_on" && result.entity.type === "req") {
70
+ append(dependentRequirementIdsByRequirementId, relationship.to, result.entity.id);
75
71
  }
76
72
  }
77
73
  }
78
74
  return {
79
- implementingSymbolIds: sortedUnique(implementingSymbolIds),
75
+ relationshipsByEntityId,
76
+ implementerIdsByRequirementId,
77
+ dependentRequirementIdsByRequirementId,
78
+ };
79
+ }
80
+ function collectFanout(requirementId, index, typesByEntityId) {
81
+ const scenarioIds = [];
82
+ const testIds = [];
83
+ const dependentRequirementIds = [];
84
+ // rationale: every requirement this is called for is in the index, so the
85
+ // fallback list is never read.
86
+ // Stryker disable next-line ArrayDeclaration
87
+ const relationships = index.relationshipsByEntityId.get(requirementId) ?? [];
88
+ for (const relationship of relationships) {
89
+ if (relationship.type === "specified_by" &&
90
+ targetHasType(relationship.to, "scenario", typesByEntityId)) {
91
+ scenarioIds.push(relationship.to);
92
+ }
93
+ if ((relationship.type === "verified_by" ||
94
+ relationship.type === "covered_by") &&
95
+ targetHasType(relationship.to, "test", typesByEntityId)) {
96
+ testIds.push(relationship.to);
97
+ }
98
+ if (relationship.type === "depends_on" &&
99
+ targetHasType(relationship.to, "req", typesByEntityId)) {
100
+ dependentRequirementIds.push(relationship.to);
101
+ }
102
+ }
103
+ dependentRequirementIds.push(...(index.dependentRequirementIdsByRequirementId.get(requirementId) ?? []));
104
+ return {
105
+ implementingSymbolIds: sortedUnique(index.implementerIdsByRequirementId.get(requirementId) ?? []),
80
106
  scenarioIds: sortedUnique(scenarioIds),
81
107
  testIds: sortedUnique(testIds),
82
108
  dependentRequirementIds: sortedUnique(dependentRequirementIds),
@@ -96,10 +122,11 @@ function isUmbrellaRequirement(result) {
96
122
  }
97
123
  function createBroadRequirementDiagnostics(results) {
98
124
  const typesByEntityId = entityTypeById(results);
125
+ const index = fanoutIndex(results);
99
126
  return results.flatMap((result) => {
100
127
  if (!isCurrentRequirement(result))
101
128
  return [];
102
- const fanout = collectFanout(result.entity.id, results, typesByEntityId);
129
+ const fanout = collectFanout(result.entity.id, index, typesByEntityId);
103
130
  if (!exceedsBroadThreshold(fanout))
104
131
  return [];
105
132
  if (isUmbrellaRequirement(result))