kibi-cli 0.17.0 → 0.18.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 (181) hide show
  1. package/dist/cli-json-command.d.ts.map +1 -1
  2. package/dist/cli-json-command.js +87 -11
  3. package/dist/cli-register-maintenance.d.ts.map +1 -1
  4. package/dist/cli-register-maintenance.js +8 -0
  5. package/dist/cli-register-reporting.d.ts.map +1 -1
  6. package/dist/cli-register-reporting.js +5 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +2 -1
  9. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  10. package/dist/commands/aggregated-checks.js +1 -0
  11. package/dist/commands/coverage.d.ts +5 -0
  12. package/dist/commands/coverage.d.ts.map +1 -1
  13. package/dist/commands/coverage.js +5 -0
  14. package/dist/commands/discovery-table.d.ts.map +1 -1
  15. package/dist/commands/discovery-table.js +96 -5
  16. package/dist/commands/sync/cache.d.ts +2 -0
  17. package/dist/commands/sync/cache.d.ts.map +1 -1
  18. package/dist/commands/sync/cache.js +8 -0
  19. package/dist/commands/sync/persistence.d.ts.map +1 -1
  20. package/dist/commands/sync/persistence.js +58 -1
  21. package/dist/commands/sync.d.ts.map +1 -1
  22. package/dist/commands/sync.js +72 -15
  23. package/dist/commands/usage-metrics.d.ts +66 -2
  24. package/dist/commands/usage-metrics.d.ts.map +1 -1
  25. package/dist/commands/usage-metrics.js +34 -24
  26. package/dist/commands/usage-remediation.d.ts +9 -0
  27. package/dist/commands/usage-remediation.d.ts.map +1 -0
  28. package/dist/commands/usage-remediation.js +52 -0
  29. package/dist/extractors/markdown.d.ts +8 -0
  30. package/dist/extractors/markdown.d.ts.map +1 -1
  31. package/dist/extractors/markdown.js +69 -2
  32. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
  33. package/dist/operations/modeling/logic-modeling.js +14 -5
  34. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  35. package/dist/operations/modeling/model-requirement.js +27 -2
  36. package/dist/operations/modeling/predicate-applyplan.d.ts +1 -1
  37. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  38. package/dist/operations/modeling/predicate-applyplan.js +18 -6
  39. package/dist/operations/modeling/predicate-inference.d.ts.map +1 -1
  40. package/dist/operations/modeling/predicate-inference.js +5 -17
  41. package/dist/operations/modeling/predicate-loader.js +1 -1
  42. package/dist/operations/modeling/predicate-types.d.ts +9 -1
  43. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  44. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  45. package/dist/operations/modeling/suggest-predicates.js +35 -11
  46. package/dist/operations/mutation/audit.js +1 -1
  47. package/dist/operations/mutation/contradictions.d.ts +1 -1
  48. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  49. package/dist/operations/mutation/contradictions.js +23 -18
  50. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  51. package/dist/operations/mutation/serialization.js +6 -3
  52. package/dist/operations/mutation/upsert.d.ts +3 -1
  53. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  54. package/dist/operations/mutation/upsert.js +51 -12
  55. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  56. package/dist/operations/mutation/validate-upsert.js +18 -2
  57. package/dist/operations/mutation/validation.d.ts.map +1 -1
  58. package/dist/operations/mutation/validation.js +8 -0
  59. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  60. package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
  61. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  62. package/dist/operations/semantic-advisor/analyze-prose.js +76 -61
  63. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  64. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  65. package/dist/operations/semantic-advisor/clauses.js +7 -7
  66. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +18 -0
  67. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -0
  68. package/dist/operations/semantic-advisor/ingestion-boundary.js +167 -0
  69. package/dist/operations/semantic-advisor/shared.d.ts +8 -0
  70. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  71. package/dist/operations/semantic-advisor/shared.js +37 -3
  72. package/dist/operations/semantic-advisor/types.d.ts +5 -0
  73. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  74. package/dist/prolog/codec.d.ts.map +1 -1
  75. package/dist/prolog/codec.js +9 -2
  76. package/dist/prolog.d.ts +6 -0
  77. package/dist/prolog.d.ts.map +1 -1
  78. package/dist/prolog.js +240 -61
  79. package/dist/public/diagnostic-usage.d.ts +17 -0
  80. package/dist/public/diagnostic-usage.d.ts.map +1 -0
  81. package/dist/public/diagnostic-usage.js +152 -0
  82. package/dist/public/distribution-parity.d.ts +90 -0
  83. package/dist/public/distribution-parity.d.ts.map +1 -0
  84. package/dist/public/distribution-parity.js +367 -0
  85. package/dist/public/impact/full-kb-quality.d.ts +2 -0
  86. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  87. package/dist/public/impact/full-kb-quality.js +53 -1
  88. package/dist/public/impact-diagnostics.d.ts +2 -0
  89. package/dist/public/impact-diagnostics.d.ts.map +1 -1
  90. package/dist/public/impact-diagnostics.js +1 -0
  91. package/dist/public/operations/catalog.d.ts +151 -6
  92. package/dist/public/operations/catalog.d.ts.map +1 -1
  93. package/dist/public/operations/check-executor.d.ts.map +1 -1
  94. package/dist/public/operations/check-executor.js +4 -0
  95. package/dist/public/operations/discovery-executors.d.ts +6 -0
  96. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  97. package/dist/public/operations/discovery-executors.js +18 -2
  98. package/dist/public/operations/index.d.ts +4 -0
  99. package/dist/public/operations/index.d.ts.map +1 -1
  100. package/dist/public/operations/index.js +4 -0
  101. package/dist/public/operations/legacy-migration-plan.d.ts +113 -0
  102. package/dist/public/operations/legacy-migration-plan.d.ts.map +1 -0
  103. package/dist/public/operations/legacy-migration-plan.js +409 -0
  104. package/dist/public/operations/node-ports.d.ts.map +1 -1
  105. package/dist/public/operations/node-ports.js +90 -0
  106. package/dist/public/operations/repair-plan.d.ts +184 -0
  107. package/dist/public/operations/repair-plan.d.ts.map +1 -0
  108. package/dist/public/operations/repair-plan.js +397 -0
  109. package/dist/public/operations/runtime-types.d.ts +7 -0
  110. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  111. package/dist/public/operations/specs/check.d.ts +2 -2
  112. package/dist/public/operations/specs/check.js +2 -2
  113. package/dist/public/operations/specs/discovery.d.ts +1 -1
  114. package/dist/public/operations/specs/discovery.js +1 -1
  115. package/dist/public/operations/specs/modeling.d.ts +19 -1
  116. package/dist/public/operations/specs/modeling.d.ts.map +1 -1
  117. package/dist/public/operations/specs/modeling.js +16 -1
  118. package/dist/public/operations/specs/mutation-schemas.d.ts +96 -1
  119. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  120. package/dist/public/operations/specs/mutation-schemas.js +40 -1
  121. package/dist/public/operations/specs/reporting.d.ts +42 -1
  122. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  123. package/dist/public/operations/specs/reporting.js +70 -6
  124. package/dist/public/operations/specs/semantic.js +1 -1
  125. package/dist/public/operations/specs/upsert.d.ts +96 -1
  126. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  127. package/dist/public/operations/workspace-snapshot.d.ts +10 -0
  128. package/dist/public/operations/workspace-snapshot.d.ts.map +1 -0
  129. package/dist/public/operations/workspace-snapshot.js +20 -0
  130. package/dist/public/schemas/entity.d.ts.map +1 -1
  131. package/dist/public/schemas/entity.js +43 -1
  132. package/dist/public/skills/kibi-traceability/SKILL.md +7 -1
  133. package/dist/public/skills/kibi-usage/SKILL.md +10 -4
  134. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
  135. package/dist/public/skills/kibi-usage/resources/logic-ir.md +1 -1
  136. package/dist/public/skills/kibi-usage/resources/workflows.md +19 -2
  137. package/dist/public/telemetry-acceptance.d.ts +89 -0
  138. package/dist/public/telemetry-acceptance.d.ts.map +1 -0
  139. package/dist/public/telemetry-acceptance.js +597 -0
  140. package/dist/public/telemetry-remediation.d.ts +33 -0
  141. package/dist/public/telemetry-remediation.d.ts.map +1 -0
  142. package/dist/public/telemetry-remediation.js +257 -0
  143. package/dist/public/verification-receipt.d.ts +75 -0
  144. package/dist/public/verification-receipt.d.ts.map +1 -0
  145. package/dist/public/verification-receipt.js +129 -0
  146. package/dist/schemas/entity.schema.json +96 -2
  147. package/dist/traceability/temp-kb.d.ts.map +1 -1
  148. package/dist/traceability/temp-kb.js +36 -3
  149. package/dist/types/entities.d.ts +1 -0
  150. package/dist/types/entities.d.ts.map +1 -1
  151. package/dist/utils/rule-registry.d.ts +2 -0
  152. package/dist/utils/rule-registry.d.ts.map +1 -1
  153. package/package.json +30 -2
  154. package/src/public/diagnostic-usage.ts +206 -0
  155. package/src/public/distribution-parity.ts +580 -0
  156. package/src/public/impact/full-kb-quality.ts +74 -1
  157. package/src/public/impact-diagnostics.ts +16 -0
  158. package/src/public/operations/check-executor.ts +4 -0
  159. package/src/public/operations/discovery-executors.ts +24 -2
  160. package/src/public/operations/index.ts +4 -0
  161. package/src/public/operations/legacy-migration-plan.ts +688 -0
  162. package/src/public/operations/node-ports.ts +109 -0
  163. package/src/public/operations/repair-plan.ts +562 -0
  164. package/src/public/operations/runtime-types.ts +8 -0
  165. package/src/public/operations/specs/check.ts +2 -2
  166. package/src/public/operations/specs/discovery.ts +1 -1
  167. package/src/public/operations/specs/modeling.ts +19 -1
  168. package/src/public/operations/specs/mutation-schemas.ts +47 -1
  169. package/src/public/operations/specs/reporting.ts +91 -6
  170. package/src/public/operations/specs/semantic.ts +1 -1
  171. package/src/public/operations/workspace-snapshot.ts +28 -0
  172. package/src/public/schemas/entity.ts +44 -1
  173. package/src/public/skills/kibi-traceability/SKILL.md +7 -1
  174. package/src/public/skills/kibi-usage/SKILL.md +10 -4
  175. package/src/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
  176. package/src/public/skills/kibi-usage/resources/logic-ir.md +1 -1
  177. package/src/public/skills/kibi-usage/resources/workflows.md +19 -2
  178. package/src/public/telemetry-acceptance.ts +859 -0
  179. package/src/public/telemetry-remediation.ts +462 -0
  180. package/src/public/verification-receipt.ts +170 -0
  181. package/src/schemas/entity.schema.json +96 -2
@@ -21,6 +21,8 @@ import * as path from "node:path";
21
21
  import { branchErrorToDiagnostic, createDocsNotIndexedDiagnostic, createInvalidAuthoringDiagnostic, createKbMissingDiagnostic, formatSyncSummary, } from "../diagnostics.js";
22
22
  import { isCliDebugEnabled } from "../env.js";
23
23
  import { extractFromRelationshipShards, flattenRelationships, validateRelationships, } from "../extractors/relationships.js";
24
+ import { analyzeSemanticAdvisorInput } from "../operations/semantic-advisor/analyze-prose.js";
25
+ import { validateSemanticInventoryBoundary } from "../operations/semantic-advisor/ingestion-boundary.js";
24
26
  import { PrologProcess } from "../prolog.js";
25
27
  import { resolveActiveBranch, } from "../utils/branch-resolver.js";
26
28
  import { loadSyncConfig } from "../utils/config.js";
@@ -90,6 +92,13 @@ export async function syncCommand(options = {}, runtime = {}) {
90
92
  const nowMs = Date.now();
91
93
  const nextHashes = {};
92
94
  const nextSeenAt = {};
95
+ const nextSemanticHashes = {
96
+ ...syncCache.semanticHashes,
97
+ };
98
+ const nextSemanticContracts = {
99
+ ...syncCache.semanticContracts,
100
+ };
101
+ const initialSemanticBaseline = Object.keys(syncCache.hashes).length === 0;
93
102
  const shardResults = extractFromRelationshipShards(relationshipsDir);
94
103
  const allRelationships = flattenRelationships(shardResults);
95
104
  const changedMarkdownFiles = [];
@@ -120,9 +129,56 @@ export async function syncCommand(options = {}, runtime = {}) {
120
129
  console.warn(`Warning: Failed to hash ${file}: ${message}`);
121
130
  }
122
131
  }
132
+ // Coordinate refresh must precede extraction so the manifest overlay that
133
+ // is persisted into RDF observes the newly generated coordinates. Force
134
+ // each refreshed manifest through extraction even when its authored YAML
135
+ // hash is unchanged; the generated coordinate artifact is an input too.
136
+ if (!validateOnly && options.refreshSymbolCoordinates) {
137
+ for (const file of manifestFiles) {
138
+ try {
139
+ await refreshManifestCoordinates(file, process.cwd(), {
140
+ refreshSymbolCoordinates: options.refreshSymbolCoordinates,
141
+ });
142
+ if (!changedManifestFiles.includes(file)) {
143
+ changedManifestFiles.push(file);
144
+ }
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ console.warn(`Warning: Failed to refresh symbol coordinates in ${file}: ${message}`);
149
+ }
150
+ }
151
+ }
123
152
  const performedFullReindex = changedMarkdownFiles.length === markdownFiles.length &&
124
153
  changedManifestFiles.length === manifestFiles.length;
125
154
  const { results, failedCacheKeys, errors } = await processExtractions(changedMarkdownFiles, changedManifestFiles, validateOnly);
155
+ for (const result of results) {
156
+ if (result.entity.type !== "req")
157
+ continue;
158
+ const key = toCacheKey(result.entity.source);
159
+ const payload = {
160
+ type: result.entity.type,
161
+ id: result.entity.id,
162
+ properties: result.entity,
163
+ relationships: result.relationships,
164
+ };
165
+ const semantic = analyzeSemanticAdvisorInput({ payload });
166
+ const boundary = validateSemanticInventoryBoundary(payload, result.relationships, semantic.receipt);
167
+ const previousSemanticHash = syncCache.semanticHashes[key];
168
+ const advertisedContract = result.entity.semantic_inventory_version !== undefined ||
169
+ result.entity.semantic_source_hash !== undefined ||
170
+ result.entity.semantic_inventory !== undefined;
171
+ const enforceBoundary = (!initialSemanticBaseline && syncCache.hashes[key] === undefined) ||
172
+ syncCache.semanticContracts[key] === true ||
173
+ (previousSemanticHash !== undefined &&
174
+ previousSemanticHash !== boundary.sourceHash) ||
175
+ advertisedContract;
176
+ if (enforceBoundary && boundary.errors.length > 0) {
177
+ throw new SyncError(`${key}: proposition-complete ingestion failed: ${boundary.errors.join("; ")}. Run kb_semantic_advisor with the complete requirement prose and preserve its inventory contract.`);
178
+ }
179
+ nextSemanticHashes[key] = boundary.sourceHash;
180
+ nextSemanticContracts[key] = advertisedContract;
181
+ }
126
182
  // Collect INVALID_AUTHORING diagnostics
127
183
  for (const err of errors) {
128
184
  const error = new Error(err.message);
@@ -139,21 +195,6 @@ export async function syncCommand(options = {}, runtime = {}) {
139
195
  diagnostics.push(createInvalidAuthoringDiagnostic(err.file, embeddedTypes));
140
196
  }
141
197
  }
142
- if (!validateOnly) {
143
- if (options.refreshSymbolCoordinates) {
144
- for (const file of manifestFiles) {
145
- try {
146
- await refreshManifestCoordinates(file, process.cwd(), {
147
- refreshSymbolCoordinates: options.refreshSymbolCoordinates,
148
- });
149
- }
150
- catch (error) {
151
- const message = error instanceof Error ? error.message : String(error);
152
- console.warn(`Warning: Failed to refresh symbol coordinates in ${file}: ${message}`);
153
- }
154
- }
155
- }
156
- }
157
198
  if (validateOnly && errors.length > 0 && results.length === 0) {
158
199
  for (const err of errors) {
159
200
  console.error(`${err.file}: ${err.message}`);
@@ -174,17 +215,25 @@ export async function syncCommand(options = {}, runtime = {}) {
174
215
  if (results.length === 0 && allRelationships.length === 0 && !rebuild) {
175
216
  const evictedHashes = {};
176
217
  const evictedSeenAt = {};
218
+ const evictedSemanticHashes = {};
219
+ const evictedSemanticContracts = {};
177
220
  for (const [key, hash] of Object.entries(nextHashes)) {
178
221
  if (failedCacheKeys.has(key)) {
179
222
  continue;
180
223
  }
181
224
  evictedHashes[key] = hash;
182
225
  evictedSeenAt[key] = nextSeenAt[key] ?? nowIso;
226
+ if (nextSemanticHashes[key] !== undefined) {
227
+ evictedSemanticHashes[key] = nextSemanticHashes[key];
228
+ evictedSemanticContracts[key] = nextSemanticContracts[key] === true;
229
+ }
183
230
  }
184
231
  writeSyncCache(cachePath, {
185
232
  version: SYNC_CACHE_VERSION,
186
233
  hashes: evictedHashes,
187
234
  seenAt: evictedSeenAt,
235
+ semanticHashes: evictedSemanticHashes,
236
+ semanticContracts: evictedSemanticContracts,
188
237
  });
189
238
  console.log("✓ Imported 0 entities, 0 relationships (no changes)");
190
239
  return withOptionalCommit({
@@ -288,18 +337,26 @@ export async function syncCommand(options = {}, runtime = {}) {
288
337
  cleanupStaging(stagingPath);
289
338
  const evictedHashes = {};
290
339
  const evictedSeenAt = {};
340
+ const evictedSemanticHashes = {};
341
+ const evictedSemanticContracts = {};
291
342
  for (const [key, hash] of Object.entries(nextHashes)) {
292
343
  if (failedCacheKeys.has(key)) {
293
344
  continue;
294
345
  }
295
346
  evictedHashes[key] = hash;
296
347
  evictedSeenAt[key] = nextSeenAt[key] ?? nowIso;
348
+ if (nextSemanticHashes[key] !== undefined) {
349
+ evictedSemanticHashes[key] = nextSemanticHashes[key];
350
+ evictedSemanticContracts[key] = nextSemanticContracts[key] === true;
351
+ }
297
352
  }
298
353
  const liveCachePath = path.join(livePath, "sync-cache.json");
299
354
  writeSyncCache(liveCachePath, {
300
355
  version: SYNC_CACHE_VERSION,
301
356
  hashes: evictedHashes,
302
357
  seenAt: evictedSeenAt,
358
+ semanticHashes: evictedSemanticHashes,
359
+ semanticContracts: evictedSemanticContracts,
303
360
  });
304
361
  published = true;
305
362
  if (performedFullReindex &&
@@ -1,8 +1,72 @@
1
1
  import type { CommandResult } from "../cli.js";
2
- interface UsageMetricsOptions {
2
+ import { type TelemetryAcceptanceReport, type TelemetryUsageEvent } from "../public/telemetry-acceptance.js";
3
+ export interface UsageMetricsOptions {
3
4
  format?: "json" | "table";
4
5
  limit?: string;
6
+ requireAcceptance?: boolean;
7
+ }
8
+ export interface UsageLogRow extends TelemetryUsageEvent {
9
+ branch?: string;
10
+ active_branch?: string;
11
+ sourceFile?: string;
12
+ args?: {
13
+ sourceFile?: string;
14
+ [key: string]: unknown;
15
+ };
16
+ business_args?: Readonly<{
17
+ sourceFile?: string;
18
+ [key: string]: unknown;
19
+ }>;
20
+ result_summary?: string;
21
+ violation_count?: number;
22
+ error?: string;
23
+ error_message?: string;
24
+ error_category?: string;
25
+ error_stage?: string;
26
+ }
27
+ export interface UsageMetricsReport {
28
+ rowCount: number;
29
+ dateRange: {
30
+ first: string | null;
31
+ last: string | null;
32
+ };
33
+ toolCounts: Record<string, number>;
34
+ branchCounts: Record<string, number>;
35
+ outcomeCounts: {
36
+ success: number;
37
+ error: number;
38
+ };
39
+ telemetry: {
40
+ completeCount: number;
41
+ missingCount: number;
42
+ completenessRate: number;
43
+ };
44
+ zeroResults: {
45
+ count: number;
46
+ rate: number;
47
+ byTool: Record<string, number>;
48
+ topSourceFiles: Array<{
49
+ sourceFile: string;
50
+ count: number;
51
+ }>;
52
+ };
53
+ kbCheck: {
54
+ violationTrend: Array<{
55
+ timestamp: string;
56
+ violationCount: number;
57
+ }>;
58
+ };
59
+ upsertErrors: {
60
+ categories: Record<string, number>;
61
+ };
62
+ errors: {
63
+ categories: Record<string, number>;
64
+ stages: Record<string, number>;
65
+ byTool: Record<string, number>;
66
+ };
67
+ acceptance: TelemetryAcceptanceReport;
5
68
  }
6
69
  export declare function usageMetricsCommand(options: UsageMetricsOptions): Promise<CommandResult | undefined>;
7
- export {};
70
+ export declare function parseUsageLog(contents: string): UsageLogRow[];
71
+ export declare function buildUsageMetricsReport(rows: UsageLogRow[], limit: number, now?: Date): UsageMetricsReport;
8
72
  //# sourceMappingURL=usage-metrics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage-metrics.d.ts","sourceRoot":"","sources":["../../src/commands/usage-metrics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAuBpC"}
1
+ {"version":3,"file":"usage-metrics.d.ts","sourceRoot":"","sources":["../../src/commands/usage-metrics.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import Table from "cli-table3";
4
+ import { analyzeTelemetryAcceptance, parseTelemetryUsageLog, } from "../public/telemetry-acceptance.js";
4
5
  // implements REQ-003
5
6
  export async function usageMetricsCommand(options) {
6
7
  const limit = Number.parseInt(options.limit || "10", 10);
@@ -15,36 +16,23 @@ export async function usageMetricsCommand(options) {
15
16
  }
16
17
  const rows = parseUsageLog(readFileSync(usageLogPath, "utf8"));
17
18
  const report = buildUsageMetricsReport(rows, limit);
19
+ const gateResult = options.requireAcceptance === true && report.acceptance.status !== "passed"
20
+ ? { exitCode: 1 }
21
+ : undefined;
18
22
  if (options.format === "json") {
19
23
  console.log(JSON.stringify(report, null, 2));
20
- return;
24
+ return gateResult;
21
25
  }
22
26
  console.log(renderUsageMetricsReport(report));
23
- return;
24
- }
25
- function parseUsageLog(contents) {
26
- const rows = [];
27
- for (const [index, line] of contents.split(/\r?\n/).entries()) {
28
- const trimmed = line.trim();
29
- if (!trimmed) {
30
- continue;
31
- }
32
- let parsed;
33
- try {
34
- parsed = JSON.parse(trimmed);
35
- }
36
- catch (error) {
37
- const message = error instanceof Error ? error.message : String(error);
38
- throw new Error(`Failed to parse .kb/usage.log line ${index + 1}: ${message}`);
39
- }
40
- if (!parsed || typeof parsed !== "object") {
41
- throw new Error(`Failed to parse .kb/usage.log line ${index + 1}: expected object`);
42
- }
43
- rows.push(parsed);
27
+ if (gateResult) {
28
+ console.error(`Telemetry acceptance gate: ${report.acceptance.status}. Review the acceptance metrics and quality diagnostics before completion.`);
44
29
  }
45
- return rows;
30
+ return gateResult;
31
+ }
32
+ export function parseUsageLog(contents) {
33
+ return parseTelemetryUsageLog(contents);
46
34
  }
47
- function buildUsageMetricsReport(rows, limit) {
35
+ export function buildUsageMetricsReport(rows, limit, now = new Date()) {
48
36
  const timestamps = rows
49
37
  .map((row) => row.timestamp)
50
38
  .filter((value) => typeof value === "string")
@@ -140,6 +128,7 @@ function buildUsageMetricsReport(rows, limit) {
140
128
  stages: mapToSortedObject(errorStages),
141
129
  byTool: mapToSortedObject(errorsByTool),
142
130
  },
131
+ acceptance: analyzeTelemetryAcceptance(rows, now),
143
132
  };
144
133
  }
145
134
  function hasCompleteTelemetry(row) {
@@ -271,6 +260,7 @@ function mapToSortedObject(counts) {
271
260
  function renderUsageMetricsReport(report) {
272
261
  const sections = [
273
262
  renderSummaryTable(report),
263
+ renderAcceptanceTable(report.acceptance),
274
264
  renderCountsTable("Tool Counts", "Tool", report.toolCounts),
275
265
  renderCountsTable("Branch Counts", "Branch", report.branchCounts),
276
266
  renderCountsTable("Outcome Counts", "Outcome", report.outcomeCounts),
@@ -284,6 +274,26 @@ function renderUsageMetricsReport(report) {
284
274
  ].filter(Boolean);
285
275
  return sections.join("\n\n");
286
276
  }
277
+ function renderAcceptanceTable(report) {
278
+ const table = new Table({
279
+ head: ["Metric", "Status", "Observed", "Rate"],
280
+ colWidths: [36, 24, 18, 14],
281
+ wordWrap: true,
282
+ });
283
+ for (const metric of report.metrics) {
284
+ table.push([
285
+ metric.id,
286
+ metric.status,
287
+ `${metric.numerator}/${metric.denominator}`,
288
+ metric.rate === undefined ? "-" : formatRate(metric.rate),
289
+ ]);
290
+ }
291
+ return [
292
+ `Telemetry Acceptance (${report.version})`,
293
+ `Status: ${report.status}; evidence fresh: ${report.scope.fresh ? "yes" : "no"}`,
294
+ table.toString(),
295
+ ].join("\n");
296
+ }
287
297
  function renderSummaryTable(report) {
288
298
  const table = new Table({
289
299
  head: ["Field", "Value"],
@@ -0,0 +1,9 @@
1
+ import type { CommandResult } from "../cli.js";
2
+ import { type TelemetryRemediationReport } from "../public/telemetry-remediation.js";
3
+ export interface UsageRemediationOptions {
4
+ readonly format?: "json" | "table";
5
+ readonly limit?: string;
6
+ }
7
+ export declare function renderUsageRemediationReport(report: TelemetryRemediationReport, limit: number): string;
8
+ export declare function usageRemediationCommand(options: UsageRemediationOptions): Promise<CommandResult | undefined>;
9
+ //# sourceMappingURL=usage-remediation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-remediation.d.ts","sourceRoot":"","sources":["../../src/commands/usage-remediation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EACL,KAAK,0BAA0B,EAEhC,MAAM,oCAAoC,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,0BAA0B,EAClC,KAAK,EAAE,MAAM,GACZ,MAAM,CA0BR;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CA0BpC"}
@@ -0,0 +1,52 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import Table from "cli-table3";
4
+ import { parseTelemetryUsageLog } from "../public/telemetry-acceptance.js";
5
+ import { buildTelemetryRemediationReport, } from "../public/telemetry-remediation.js";
6
+ export function renderUsageRemediationReport(report, limit) {
7
+ const table = new Table({
8
+ head: ["Rank", "Metric", "Line", "Target", "Reason", "Repair"],
9
+ colWidths: [7, 28, 8, 26, 42, 48],
10
+ wordWrap: true,
11
+ });
12
+ for (const item of report.items.slice(0, limit)) {
13
+ table.push([
14
+ item.rank,
15
+ item.metric,
16
+ item.event?.logLine ?? "report",
17
+ item.target,
18
+ item.reason,
19
+ item.action,
20
+ ]);
21
+ }
22
+ const suffix = report.items.length > limit
23
+ ? `\nShowing ${limit}/${report.items.length} remediation items.`
24
+ : "";
25
+ return ([
26
+ `Telemetry remediation: ${report.status} (${report.summary.eventItems} event, ${report.summary.reportItems} report-level)`,
27
+ table.toString(),
28
+ ].join("\n") + suffix);
29
+ }
30
+ export async function usageRemediationCommand(options) {
31
+ const limit = Number.parseInt(options.limit ?? "50", 10);
32
+ if (!Number.isFinite(limit) || limit < 1) {
33
+ console.error("Error: --limit must be a positive integer");
34
+ return { exitCode: 1 };
35
+ }
36
+ if (options.format !== undefined &&
37
+ !["json", "table"].includes(options.format)) {
38
+ console.error("Error: --format must be json or table");
39
+ return { exitCode: 1 };
40
+ }
41
+ const usageLogPath = path.join(process.cwd(), ".kb", "usage.log");
42
+ if (!existsSync(usageLogPath)) {
43
+ console.error(`Error: usage log not found at ${usageLogPath}`);
44
+ return { exitCode: 1 };
45
+ }
46
+ const events = parseTelemetryUsageLog(readFileSync(usageLogPath, "utf8"));
47
+ const report = buildTelemetryRemediationReport(events);
48
+ console.log(options.format === "json"
49
+ ? JSON.stringify(report, null, 2)
50
+ : renderUsageRemediationReport(report, limit));
51
+ return undefined;
52
+ }
@@ -1,3 +1,4 @@
1
+ import { type VerificationReceipt } from "../public/verification-receipt.js";
1
2
  export interface ExtractedEntity {
2
3
  id: string;
3
4
  type: string;
@@ -11,7 +12,12 @@ export interface ExtractedEntity {
11
12
  priority?: string;
12
13
  severity?: string;
13
14
  text_ref?: string;
15
+ semantic_text?: string;
14
16
  logic_claims?: string[];
17
+ semantic_clauses?: string[];
18
+ semantic_inventory_version?: "kibi.semantic-inventory.v1";
19
+ semantic_source_field?: "semantic_text" | "text_ref" | "title";
20
+ semantic_source_hash?: string;
15
21
  granularity_reason?: string;
16
22
  symbol_kind?: string;
17
23
  symbol_role?: string;
@@ -21,6 +27,7 @@ export interface ExtractedEntity {
21
27
  sourceEndColumn?: number;
22
28
  verification_scope?: "unit" | "integration" | "end_to_end";
23
29
  verification_perspective?: "internal" | "consumer";
30
+ verification_receipts?: readonly VerificationReceipt[];
24
31
  fact_kind?: "subject" | "property_value" | "observation" | "meta" | "predicate_schema" | "predicate" | "rule_schema" | "rule";
25
32
  subject_key?: string;
26
33
  property_key?: string;
@@ -79,6 +86,7 @@ export declare class FrontmatterError extends Error {
79
86
  });
80
87
  toString(): string;
81
88
  }
89
+ export declare function requirementSemanticText(body: string): string;
82
90
  export declare function detectEmbeddedEntities(data: Record<string, unknown>, entityType: string): string[];
83
91
  export declare function extractFromMarkdownString(content: string, filePath: string): ExtractionResult;
84
92
  export declare function extractFromMarkdown(filePath: string): ExtractionResult;
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ import { readFileSync } from "node:fs";
20
20
  import Ajv from "ajv";
21
21
  import { load as yamlLoad } from "js-yaml";
22
22
  import { semanticClaimKey } from "../operations/semantic-advisor/clauses.js";
23
+ import { verificationReceiptHistoryErrors, } from "../public/verification-receipt.js";
23
24
  import entitySchema from "../schemas/entity.schema.json" with { type: "json" };
24
25
  // Typed fact field constants for extraction
25
26
  const FACT_STRING_FIELDS = [
@@ -70,6 +71,7 @@ const FACT_ONLY_FIELDS = [
70
71
  const TEST_ENUM_FIELDS = [
71
72
  "verification_scope",
72
73
  "verification_perspective",
74
+ "verification_receipts",
73
75
  ];
74
76
  const ajv = new Ajv({ strict: false, allErrors: true });
75
77
  const validateExtractedEntity = ajv.compile(entitySchema);
@@ -230,6 +232,16 @@ function parseFrontmatter(content) {
230
232
  content: parts.slice(2).join("---"),
231
233
  };
232
234
  }
235
+ // implements REQ-kibi-legacy-migration-preview-v2
236
+ export function requirementSemanticText(body) {
237
+ return body
238
+ .replace(/\r\n?/g, "\n")
239
+ .split("\n")
240
+ .filter((line) => !/^\s{0,3}#{1,6}(?:\s+|$)/.test(line))
241
+ .map((line) => line.replace(/^\s*(?:(?:[-*+]|\d+[.)])\s+|>\s*)/, ""))
242
+ .join("\n")
243
+ .trim();
244
+ }
233
245
  function hasLikelyUnquotedColonInTitle(content) {
234
246
  if (!content.trim().startsWith("---")) {
235
247
  return false;
@@ -294,7 +306,7 @@ data, entityType) {
294
306
  // implements REQ-007, REQ-004
295
307
  function extractFromMarkdownContent(content, filePath) {
296
308
  try {
297
- const { data } = parseFrontmatter(content);
309
+ const { data, content: body } = parseFrontmatter(content);
298
310
  if (content.trim().startsWith("---")) {
299
311
  const parts = content.split("---");
300
312
  if (parts.length < 3) {
@@ -370,11 +382,32 @@ function extractFromMarkdownContent(content, filePath) {
370
382
  entity.priority = data.priority;
371
383
  if (data.severity !== undefined)
372
384
  entity.severity = data.severity;
373
- if (data.text_ref !== undefined)
385
+ if (data.text_ref !== undefined) {
374
386
  entity.text_ref = data.text_ref;
387
+ }
388
+ if (type === "req" && data.semantic_text !== undefined) {
389
+ entity.semantic_text = data.semantic_text;
390
+ }
391
+ else if (type === "req") {
392
+ const semanticText = requirementSemanticText(body);
393
+ if (semanticText)
394
+ entity.semantic_text = semanticText;
395
+ }
375
396
  if (type === "req" && Array.isArray(data.logic_claims)) {
376
397
  entity.logic_claims = data.logic_claims.filter((value) => typeof value === "string");
377
398
  }
399
+ if (type === "req" && Array.isArray(data.semantic_clauses)) {
400
+ entity.semantic_clauses = data.semantic_clauses.filter((value) => typeof value === "string");
401
+ }
402
+ if (type === "req" && data.semantic_inventory_version !== undefined) {
403
+ entity.semantic_inventory_version = data.semantic_inventory_version;
404
+ }
405
+ if (type === "req" && data.semantic_source_field !== undefined) {
406
+ entity.semantic_source_field = data.semantic_source_field;
407
+ }
408
+ if (type === "req" && data.semantic_source_hash !== undefined) {
409
+ entity.semantic_source_hash = data.semantic_source_hash;
410
+ }
378
411
  if (type !== "fact") {
379
412
  const invalidFactField = FACT_ONLY_FIELDS.find((field) => data[field] !== undefined);
380
413
  if (invalidFactField) {
@@ -412,6 +445,40 @@ function extractFromMarkdownContent(content, filePath) {
412
445
  }
413
446
  entity.verification_perspective = data.verification_perspective;
414
447
  }
448
+ if (data.verification_receipts !== undefined) {
449
+ if (!Array.isArray(data.verification_receipts)) {
450
+ throw new FrontmatterError("Invalid verification_receipts; expected an array", filePath, {
451
+ classification: "Invalid Test Verification Receipts",
452
+ hint: "Use append-only kibi.verification-receipt.v1 objects.",
453
+ });
454
+ }
455
+ const normalizedReceipts = data.verification_receipts.map((value) => {
456
+ if (typeof value !== "object" ||
457
+ value === null ||
458
+ Array.isArray(value)) {
459
+ return value;
460
+ }
461
+ return {
462
+ ...value,
463
+ ...(normalizeDateLike(value.started_at) !== undefined
464
+ ? { started_at: normalizeDateLike(value.started_at) }
465
+ : {}),
466
+ ...(normalizeDateLike(value.finished_at) !== undefined
467
+ ? { finished_at: normalizeDateLike(value.finished_at) }
468
+ : {}),
469
+ };
470
+ });
471
+ entity.verification_receipts = normalizedReceipts;
472
+ const errors = verificationReceiptHistoryErrors(entity.id, entity.verification_scope, normalizedReceipts.filter((value) => typeof value === "object" &&
473
+ value !== null &&
474
+ !Array.isArray(value)));
475
+ if (errors.length > 0) {
476
+ throw new FrontmatterError(errors.join("; "), filePath, {
477
+ classification: "Invalid Test Verification Receipts",
478
+ hint: "Bind every receipt to this test and its typed verification_scope, with unique IDs and ordered ISO-8601 timestamps.",
479
+ });
480
+ }
481
+ }
415
482
  }
416
483
  // Add typed fact fields only for fact entities
417
484
  //
@@ -1 +1 @@
1
- {"version":3,"file":"logic-modeling.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/logic-modeling.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAUD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,GACzB,oBAAoB,CAwGtB"}
1
+ {"version":3,"file":"logic-modeling.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/logic-modeling.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,mBAAmB,CAAC;AAO3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAUD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,GACzB,oBAAoB,CAsHtB"}
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { logicSemanticKey, utf8Span, validateLogicIr, } from "../../logic/ir.js";
3
- import { semanticClaimKey } from "../semantic-advisor/clauses.js";
3
+ import { normalizeSemanticClause, semanticClaimKey, } from "../semantic-advisor/clauses.js";
4
+ import { semanticSourceHash } from "../semantic-advisor/shared.js";
4
5
  function shortId(value) {
5
6
  return createHash("sha256")
6
7
  .update(value)
@@ -20,12 +21,14 @@ export function buildLogicApplyPlan(input) {
20
21
  !validation.renderedProlog) {
21
22
  throw new Error(`Logic IR validation failed: ${validation.errors.join("; ")}`);
22
23
  }
23
- const claimText = input.claimText?.trim() || input.text.trim();
24
+ const sourceText = input.claimText?.trim() || input.text.trim();
25
+ const claimText = normalizeSemanticClause(sourceText);
24
26
  const claimKey = input.claimKey || semanticClaimKey(claimText);
25
27
  const semanticKey = logicSemanticKey(validation.normalized);
26
28
  const schemaId = validation.normalized.ruleSchemaId ?? "FACT-RULE-SCHEMA-LOGIC-V1";
27
29
  const ruleId = logicRuleFactId(semanticKey);
28
- const span = utf8Span(input.text, 0, input.text.length);
30
+ const claimStart = input.text.indexOf(claimText);
31
+ const span = utf8Span(input.text, claimStart >= 0 ? claimStart : 0, claimStart >= 0 ? claimStart + claimText.length : claimText.length);
29
32
  const logicClaims = Array.from(new Set([...(input.existingLogicClaims ?? []), claimKey]));
30
33
  const schemaPlan = input.logic.ruleSchemaId
31
34
  ? []
@@ -85,13 +88,19 @@ export function buildLogicApplyPlan(input) {
85
88
  title: claimText.split(/[.!?]/, 1)[0] || "Typed logical requirement",
86
89
  status: "open",
87
90
  source: input.source,
88
- text_ref: claimText,
91
+ semantic_text: input.text.trim(),
89
92
  logic_claims: logicClaims,
93
+ semantic_clauses: [claimText],
94
+ semantic_inventory_version: "kibi.semantic-inventory.v1",
95
+ semantic_source_field: "semantic_text",
96
+ semantic_source_hash: semanticSourceHash(input.text.trim()),
90
97
  semantic_inventory: [
91
98
  {
92
99
  claim_key: claimKey,
93
100
  claim_text: claimText,
94
- role: "normative",
101
+ role: /\b(?:must|shall|should|required|requires?)\b/i.test(claimText)
102
+ ? "normative"
103
+ : "descriptive",
95
104
  status: "modeled",
96
105
  span,
97
106
  semantic_key: semanticKey,
@@ -1 +1 @@
1
- {"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAIjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAMhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAEF,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,sBAAsB,CAAC,CA4IjC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAEjC"}
1
+ {"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAQjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAMhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAEF,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,sBAAsB,CAAC,CAsKjC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAEjC"}