kibi-cli 2.21.2 → 2.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/cli-register-foundation.d.ts.map +1 -1
  2. package/dist/cli-register-foundation.js +1 -0
  3. package/dist/commands/check.d.ts +0 -1
  4. package/dist/commands/check.d.ts.map +1 -1
  5. package/dist/commands/check.js +47 -111
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +108 -6
  8. package/dist/commands/init-helpers.d.ts +16 -2
  9. package/dist/commands/init-helpers.d.ts.map +1 -1
  10. package/dist/commands/init-helpers.js +52 -10
  11. package/dist/commands/init.d.ts +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +12 -1
  14. package/dist/commands/legacy-storage-migration.d.ts +46 -1
  15. package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
  16. package/dist/commands/legacy-storage-migration.js +219 -9
  17. package/dist/commands/migrate.d.ts +37 -0
  18. package/dist/commands/migrate.d.ts.map +1 -1
  19. package/dist/commands/migrate.js +72 -188
  20. package/dist/commands/sync/manifest.d.ts.map +1 -1
  21. package/dist/commands/sync/manifest.js +9 -0
  22. package/dist/extractors/symbols-coordinator.js +1 -0
  23. package/dist/intent-search.d.ts.map +1 -1
  24. package/dist/intent-search.js +28 -6
  25. package/dist/operations/migration/inventory-rederive.d.ts +40 -1
  26. package/dist/operations/migration/inventory-rederive.d.ts.map +1 -1
  27. package/dist/operations/migration/inventory-rederive.js +99 -8
  28. package/dist/operations/migration/requirement-status.d.ts +25 -0
  29. package/dist/operations/migration/requirement-status.d.ts.map +1 -0
  30. package/dist/operations/migration/requirement-status.js +105 -0
  31. package/dist/operations/migration/schema6.d.ts +25 -0
  32. package/dist/operations/migration/schema6.d.ts.map +1 -1
  33. package/dist/operations/migration/schema6.js +265 -7
  34. package/dist/operations/migration/symbol-legacy-links.d.ts +51 -0
  35. package/dist/operations/migration/symbol-legacy-links.d.ts.map +1 -0
  36. package/dist/operations/migration/symbol-legacy-links.js +319 -0
  37. package/dist/operations/mutation/context-warning.d.ts +12 -2
  38. package/dist/operations/mutation/context-warning.d.ts.map +1 -1
  39. package/dist/operations/mutation/context-warning.js +6 -6
  40. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  41. package/dist/operations/mutation/source-authoring.js +130 -35
  42. package/dist/operations/mutation/types.d.ts +2 -1
  43. package/dist/operations/mutation/types.d.ts.map +1 -1
  44. package/dist/operations/mutation/upsert.d.ts +17 -2
  45. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  46. package/dist/operations/mutation/upsert.js +28 -11
  47. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  48. package/dist/operations/mutation/validate-upsert.js +40 -8
  49. package/dist/operations/mutation/validation.d.ts.map +1 -1
  50. package/dist/operations/mutation/validation.js +43 -1
  51. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  52. package/dist/operations/planning/apply-plan.js +34 -10
  53. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
  54. package/dist/operations/semantic-advisor/ingestion-boundary.js +25 -1
  55. package/dist/operations/semantic-advisor/stored-ledger-drift.d.ts +19 -0
  56. package/dist/operations/semantic-advisor/stored-ledger-drift.d.ts.map +1 -0
  57. package/dist/operations/semantic-advisor/stored-ledger-drift.js +78 -0
  58. package/dist/public/impact/diagnostics.d.ts.map +1 -1
  59. package/dist/public/impact/diagnostics.js +24 -14
  60. package/dist/public/operations/catalog.d.ts +3 -3
  61. package/dist/public/operations/check-executor.d.ts.map +1 -1
  62. package/dist/public/operations/check-executor.js +3 -0
  63. package/dist/public/operations/contracts.d.ts.map +1 -1
  64. package/dist/public/operations/contracts.js +6 -1
  65. package/dist/public/operations/decision-firmness.d.ts +3 -1
  66. package/dist/public/operations/decision-firmness.d.ts.map +1 -1
  67. package/dist/public/operations/decision-firmness.js +13 -3
  68. package/dist/public/operations/discovery-executors.d.ts +2 -0
  69. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  70. package/dist/public/operations/discovery-executors.js +24 -2
  71. package/dist/public/operations/migration-plan.d.ts +15 -0
  72. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  73. package/dist/public/operations/migration-plan.js +130 -17
  74. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  75. package/dist/public/operations/result-envelope.js +27 -1
  76. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  77. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  78. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  79. package/dist/public/operations/specs/check.d.ts +1 -1
  80. package/dist/public/operations/specs/planning.d.ts +2 -2
  81. package/dist/public/operations/specs/planning.js +2 -2
  82. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  83. package/dist/public/operations/specs/semantic.js +26 -1
  84. package/dist/public/operations/symbol-granularity-check.d.ts +18 -0
  85. package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -0
  86. package/dist/public/operations/symbol-granularity-check.js +175 -0
  87. package/dist/public/skills/kibi-usage/SKILL.md +8 -3
  88. package/dist/public/symbol-granularity.d.ts +17 -0
  89. package/dist/public/symbol-granularity.d.ts.map +1 -1
  90. package/dist/public/symbol-granularity.js +21 -0
  91. package/dist/traceability/evidence-model.d.ts +7 -3
  92. package/dist/traceability/evidence-model.d.ts.map +1 -1
  93. package/dist/traceability/staged-symbols-manifest.js +6 -5
  94. package/dist/traceability/validate.d.ts +14 -1
  95. package/dist/traceability/validate.d.ts.map +1 -1
  96. package/dist/traceability/validate.js +41 -0
  97. package/dist/utils/rule-registry.generated.d.ts +5 -0
  98. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  99. package/dist/utils/rule-registry.generated.js +6 -0
  100. package/package.json +3 -3
  101. package/src/public/impact/diagnostics.ts +29 -17
  102. package/src/public/operations/check-executor.ts +7 -0
  103. package/src/public/operations/contracts.ts +6 -1
  104. package/src/public/operations/decision-firmness.ts +18 -2
  105. package/src/public/operations/discovery-executors.ts +28 -2
  106. package/src/public/operations/migration-plan.ts +147 -20
  107. package/src/public/operations/result-envelope.ts +34 -1
  108. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  109. package/src/public/operations/specs/planning.ts +2 -2
  110. package/src/public/operations/specs/semantic.ts +37 -2
  111. package/src/public/operations/symbol-granularity-check.ts +233 -0
  112. package/src/public/skills/kibi-usage/SKILL.md +8 -3
  113. package/src/public/symbol-granularity.ts +37 -0
@@ -1,11 +1,13 @@
1
1
  import { InputError } from "../../../cli-errors.js";
2
2
  import { analyzeSemanticAdvisorInputWithPlugins } from "../../../operations/semantic-advisor/plugin-orchestration.js";
3
+ import { storedLedgerDriftWarning } from "../../../operations/semantic-advisor/stored-ledger-drift.js";
3
4
  import type {
4
5
  SemanticAdvisorArgs,
5
6
  SemanticAdvisorOperationResult,
7
+ SemanticAdvisorReceipt,
6
8
  } from "../../../operations/semantic-advisor/types.js";
7
9
  import { publicCapabilityStamp } from "../../../plugins/compose-semantic-classifier.js";
8
- import type { OperationContext } from "../runtime-types.js";
10
+ import type { OperationContext, PrologPort } from "../runtime-types.js";
9
11
  import type { OperationSpec } from "../types.js";
10
12
 
11
13
  function requiredText(value: unknown): string {
@@ -24,6 +26,33 @@ function optionalString(value: unknown): string | undefined {
24
26
  return text || undefined;
25
27
  }
26
28
 
29
+ /**
30
+ * The stored-ledger comparison runs only for a requirement the caller named
31
+ * and only when the host can open the branch engine; analysis without a KB
32
+ * (a preview, a unit test, a workspace before `kibi sync`) stays as it was.
33
+ * A store that cannot be read is not an analysis failure, so the warning is
34
+ * simply absent then.
35
+ */
36
+ // implements REQ-kibi-proposition-complete-ingestion
37
+ async function storedLedgerWarnings(
38
+ args: SemanticAdvisorArgs,
39
+ text: string,
40
+ receipt: SemanticAdvisorReceipt,
41
+ context?: OperationContext,
42
+ ): Promise<readonly string[]> {
43
+ const id = optionalString(args.id);
44
+ if (!id || (optionalString(args.type) ?? "req") !== "req") return [];
45
+ try {
46
+ const prolog: PrologPort | undefined =
47
+ context?.prolog ?? (await context?.ensureProlog?.());
48
+ if (!prolog) return [];
49
+ const warning = await storedLedgerDriftWarning(prolog, id, text, receipt);
50
+ return warning ? [warning] : [];
51
+ } catch {
52
+ return [];
53
+ }
54
+ }
55
+
27
56
  export async function executeSemanticAdvisor(
28
57
  args: SemanticAdvisorArgs,
29
58
  context?: OperationContext,
@@ -57,6 +86,12 @@ export async function executeSemanticAdvisor(
57
86
  },
58
87
  );
59
88
  const result = orchestrated.analysis;
89
+ const ledgerWarnings = await storedLedgerWarnings(
90
+ args,
91
+ text,
92
+ result.receipt,
93
+ context,
94
+ );
60
95
  const pluginWarnings =
61
96
  orchestrated.stamps.length > 0
62
97
  ? [
@@ -114,7 +149,7 @@ export async function executeSemanticAdvisor(
114
149
  ],
115
150
  structuredContent: {
116
151
  receipt: result.receipt,
117
- warnings: [...result.warnings, ...pluginWarnings],
152
+ warnings: [...result.warnings, ...ledgerWarnings, ...pluginWarnings],
118
153
  ...(capabilityPlugins ? { capabilityPlugins } : {}),
119
154
  },
120
155
  };
@@ -0,0 +1,233 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ import { readFileSync, statSync } from "node:fs";
20
+ import * as path from "node:path";
21
+ import type { ExtractionResult } from "../../extractors/markdown.js";
22
+ import { createMaintenanceSourceAnalysisService } from "../../plugins/maintenance-source-analysis.js";
23
+ import {
24
+ normalizeEntityId,
25
+ parseEntityFromList,
26
+ parseListOfLists,
27
+ parseTriples,
28
+ } from "../../prolog/codec.js";
29
+ import {
30
+ type ExtractedSymbol,
31
+ extractSymbolsFromStagedFileAsync,
32
+ } from "../../traceability/symbol-extract.js";
33
+ import type { Violation } from "../../utils/rule-registry.js";
34
+ import { createSymbolGranularityDiagnostics } from "../impact/diagnostics.js";
35
+ import { createImpactManifestLookup } from "../impact/manifest.js";
36
+ import { normalizeSourceFile } from "../impact/source-changes.js";
37
+ import {
38
+ isAllowedGranularityReason,
39
+ isTraceabilityRelationshipType,
40
+ } from "../symbol-granularity.js";
41
+ import type { PrologPort } from "./runtime-types.js";
42
+
43
+ /**
44
+ * Full-check form of the staged gate's `symbol_granularity_violation`: a
45
+ * symbol with traceability relationships must not link its source file
46
+ * coarsely while narrower behavioral symbols are available, unless it carries
47
+ * an allowed granularity_reason.
48
+ */
49
+ // implements REQ-cli-check, REQ-cli-staged-impact-enforcement
50
+ export const SYMBOL_GRANULARITY_RULE = "symbol-granularity";
51
+
52
+ const SYMBOL_ROWS_QUERY =
53
+ "findall([Id,symbol,Fields], (kb_entity(Id, symbol, Props), include([Key=_]>>memberchk(Key, [title,status,source,sourceFile,granularity_reason]), Props, Fields)), Rows)";
54
+ const SYMBOL_RELATIONSHIPS_QUERY =
55
+ "findall([From,To,Type], (member(Type, [implements,covered_by,executable_for]), kb_relationship(Type, From, To), kb_entity(From, symbol, _)), Rels)";
56
+
57
+ function stringField(
58
+ entity: Record<string, unknown>,
59
+ key: string,
60
+ ): string | undefined {
61
+ const value = entity[key];
62
+ return typeof value === "string" && value.length > 0 ? value : undefined;
63
+ }
64
+
65
+ // implements REQ-cli-check
66
+ async function loadSymbolResults(
67
+ prolog: Pick<PrologPort, "query">,
68
+ workspaceRoot: string,
69
+ ): Promise<ExtractionResult[]> {
70
+ const rows = await prolog.query(SYMBOL_ROWS_QUERY);
71
+ if (!rows.success) {
72
+ throw new Error(
73
+ `symbol-granularity symbol projection failed: ${rows.error ?? "unknown error"}`,
74
+ );
75
+ }
76
+ const rels = await prolog.query(SYMBOL_RELATIONSHIPS_QUERY);
77
+ if (!rels.success) {
78
+ throw new Error(
79
+ `symbol-granularity relationship projection failed: ${rels.error ?? "unknown error"}`,
80
+ );
81
+ }
82
+
83
+ const relationships = new Map<string, ExtractionResult["relationships"]>();
84
+ for (const [rawFrom, rawTo, type] of parseTriples(
85
+ rels.bindings.Rels ?? "[]",
86
+ )) {
87
+ const from = normalizeEntityId(rawFrom);
88
+ const current = relationships.get(from) ?? [];
89
+ current.push({ from, to: normalizeEntityId(rawTo), type });
90
+ relationships.set(from, current);
91
+ }
92
+
93
+ const results: ExtractionResult[] = [];
94
+ for (const row of parseListOfLists(rows.bindings.Rows ?? "[]")) {
95
+ const entity = parseEntityFromList(row);
96
+ const id = stringField(entity, "id");
97
+ const sourceFile = stringField(entity, "sourceFile");
98
+ if (id === undefined || sourceFile === undefined) continue;
99
+ const granularityReason = stringField(entity, "granularity_reason");
100
+ results.push({
101
+ entity: {
102
+ id,
103
+ type: "symbol",
104
+ title: stringField(entity, "title") ?? "",
105
+ status: stringField(entity, "status") ?? "",
106
+ created_at: "",
107
+ updated_at: "",
108
+ source: stringField(entity, "source") ?? "",
109
+ ...(granularityReason !== undefined
110
+ ? { granularity_reason: granularityReason }
111
+ : {}),
112
+ },
113
+ relationships: relationships.get(id) ?? [],
114
+ sourceFile: normalizeSourceFile(workspaceRoot, sourceFile),
115
+ });
116
+ }
117
+ return results;
118
+ }
119
+
120
+ /**
121
+ * The symbols the staged gate would judge: they carry a traceability
122
+ * relationship and no allowed granularity_reason. Other symbols are exempt,
123
+ * so their source files need no analysis.
124
+ */
125
+ // implements REQ-cli-check
126
+ function granularityCandidates(
127
+ results: readonly ExtractionResult[],
128
+ ): ExtractionResult[] {
129
+ return results.filter(
130
+ (result) =>
131
+ result.relationships.some((relationship) =>
132
+ isTraceabilityRelationshipType(relationship.type),
133
+ ) && !isAllowedGranularityReason(result.entity.granularity_reason),
134
+ );
135
+ }
136
+
137
+ function readRegularFile(absolutePath: string): string | null {
138
+ try {
139
+ if (!statSync(absolutePath).isFile()) return null;
140
+ return readFileSync(absolutePath, "utf8");
141
+ } catch {
142
+ return null;
143
+ }
144
+ }
145
+
146
+ // implements REQ-cli-check
147
+ async function analyzeFiles(
148
+ files: readonly string[],
149
+ results: readonly ExtractionResult[],
150
+ workspaceRoot: string,
151
+ ): Promise<Map<string, readonly ExtractedSymbol[]>> {
152
+ const manifestLookup = createImpactManifestLookup(results);
153
+ const service = createMaintenanceSourceAnalysisService(workspaceRoot);
154
+ const analyses = new Map<string, readonly ExtractedSymbol[]>();
155
+ for (const file of files) {
156
+ const content = readRegularFile(path.resolve(workspaceRoot, file));
157
+ if (content === null) continue;
158
+ try {
159
+ const analysis = await service.analyzeTextV2(file, content);
160
+ // Only a complete parser-backed analysis decides; the staged gate
161
+ // reports an incomplete one itself when the file is touched.
162
+ if (analysis.status !== "ok") continue;
163
+ const symbols = await extractSymbolsFromStagedFileAsync(
164
+ {
165
+ path: file,
166
+ status: "M",
167
+ content,
168
+ hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
169
+ },
170
+ manifestLookup,
171
+ { analyzeText: async () => analysis },
172
+ );
173
+ analyses.set(file, symbols);
174
+ } catch {
175
+ // An analysis failure cannot decide anything for this file.
176
+ }
177
+ }
178
+ return analyses;
179
+ }
180
+
181
+ // implements REQ-cli-check
182
+ function granularityViolations(
183
+ candidates: readonly ExtractionResult[],
184
+ sourceSymbolsByFile: ReadonlyMap<string, readonly ExtractedSymbol[]>,
185
+ workspaceRoot: string,
186
+ ): Violation[] {
187
+ return createSymbolGranularityDiagnostics({
188
+ manifestResults: candidates.filter(
189
+ (result) =>
190
+ result.sourceFile !== undefined &&
191
+ sourceSymbolsByFile.has(result.sourceFile),
192
+ ),
193
+ symbolsByFile: new Map(),
194
+ sourceSymbolsByFile,
195
+ workspaceRoot,
196
+ }).map((diagnostic) => ({
197
+ rule: SYMBOL_GRANULARITY_RULE,
198
+ entityId: diagnostic.entityId ?? "",
199
+ description: diagnostic.message,
200
+ suggestion: diagnostic.suggestion,
201
+ ...(diagnostic.source !== undefined ? { source: diagnostic.source } : {}),
202
+ evidence: {
203
+ diagnosticId: diagnostic.id,
204
+ ...(diagnostic.evidence ?? {}),
205
+ },
206
+ }));
207
+ }
208
+
209
+ /**
210
+ * `symbol-granularity`: the staged gate's granularity predicate, evaluated
211
+ * for every symbol against its whole working-tree file, every declaration a
212
+ * candidate as if the file were fully staged. Only files of symbols the gate
213
+ * would judge are analyzed; a file the source analyzers cannot fully analyze
214
+ * is skipped.
215
+ */
216
+ // implements REQ-cli-check, REQ-cli-staged-impact-enforcement
217
+ export async function collectSymbolGranularityViolations(
218
+ prolog: Pick<PrologPort, "query">,
219
+ workspaceRoot: string,
220
+ rules: ReadonlySet<string>,
221
+ ): Promise<Violation[]> {
222
+ if (!rules.has(SYMBOL_GRANULARITY_RULE)) return [];
223
+ const results = await loadSymbolResults(prolog, workspaceRoot);
224
+ const candidates = granularityCandidates(results);
225
+ const files = [
226
+ ...new Set(candidates.map((result) => result.sourceFile ?? "")),
227
+ ]
228
+ .filter((file) => file.length > 0)
229
+ .sort();
230
+ if (files.length === 0) return [];
231
+ const analyses = await analyzeFiles(files, results, workspaceRoot);
232
+ return granularityViolations(candidates, analyses, workspaceRoot);
233
+ }
@@ -2,7 +2,7 @@
2
2
  id: kibi-usage
3
3
  name: Kibi Usage
4
4
  description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
5
- version: 2.16.0
5
+ version: 2.16.1
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -286,8 +286,13 @@ authored. Each one is the order the write path accepts.
286
286
  existing entity, whose stored ledger Kibi keeps.
287
287
  2. **Changing the text of a grounded requirement.** New prose means new
288
288
  claim keys, so a bare rewrite is refused with `modeled proposition
289
- claim_keys must match logical grounding target claim_keys exactly`.
290
- Prefer supersession for a change of meaning: analyze the new prose,
289
+ claim_keys must match logical grounding target claim_keys exactly`; the
290
+ error names the modeled keys no fact declares and the facts whose keys
291
+ the ledger dropped. Analyze the new prose with the requirement's `id`
292
+ first: the receipt warns `Claim-key drift against the stored ledger`
293
+ and names the grounded clauses the new wording drops (the title worded
294
+ differently from the stored `semantic_text` is the usual cause), before
295
+ any write. Prefer supersession for a change of meaning: analyze the new prose,
291
296
  write its facts, write the new requirement (`-v2`) with `supersedes` to
292
297
  the old one, then set the old one to `status: closed`. Its scenario
293
298
  follows the same rule as in recipe 1: create the new scenario (with
@@ -117,6 +117,43 @@ export function getBehavioralSymbolNames(
117
117
  ].sort();
118
118
  }
119
119
 
120
+ /**
121
+ * The candidates that are narrower than a manifest symbol: members of it
122
+ * (`Title.member`), or, when the source declares no symbol named like it,
123
+ * every other declaration in the file.
124
+ */
125
+ // implements REQ-symbol-behavioral-anchors, REQ-cli-schema-migration
126
+ export function narrowerSymbols<T extends { name: string }>(
127
+ manifestSymbolName: string,
128
+ candidates: readonly T[],
129
+ sourceSymbols: readonly { name: string }[],
130
+ ): T[] {
131
+ const declared = sourceSymbols.some(
132
+ (symbol) => symbol.name === manifestSymbolName,
133
+ );
134
+ return candidates.filter(
135
+ (candidate) =>
136
+ candidate.name !== manifestSymbolName &&
137
+ (candidate.name.startsWith(`${manifestSymbolName}.`) || !declared),
138
+ );
139
+ }
140
+
141
+ /**
142
+ * The behavioral symbols that make a traceability link on
143
+ * `manifestSymbolName` coarse: the staged granularity gate blocks such a
144
+ * link unless it carries a granularity_reason, and `kibi migrate` marks
145
+ * exactly these links legacy-link. Empty when the link is narrow enough.
146
+ */
147
+ // implements REQ-symbol-behavioral-anchors, REQ-cli-schema-migration
148
+ export function coarseLinkBehavioralNames(
149
+ manifestSymbolName: string,
150
+ sourceSymbols: readonly GranularSymbolCandidate[],
151
+ ): string[] {
152
+ return getBehavioralSymbolNames(
153
+ narrowerSymbols(manifestSymbolName, sourceSymbols, sourceSymbols),
154
+ );
155
+ }
156
+
120
157
  export function getNonBehavioralSymbolNames(
121
158
  candidates: GranularSymbolCandidate[],
122
159
  ): string[] {