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.
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +87 -11
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +8 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +1 -0
- package/dist/commands/coverage.d.ts +5 -0
- package/dist/commands/coverage.d.ts.map +1 -1
- package/dist/commands/coverage.js +5 -0
- package/dist/commands/discovery-table.d.ts.map +1 -1
- package/dist/commands/discovery-table.js +96 -5
- package/dist/commands/sync/cache.d.ts +2 -0
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +8 -0
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +58 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +72 -15
- package/dist/commands/usage-metrics.d.ts +66 -2
- package/dist/commands/usage-metrics.d.ts.map +1 -1
- package/dist/commands/usage-metrics.js +34 -24
- package/dist/commands/usage-remediation.d.ts +9 -0
- package/dist/commands/usage-remediation.d.ts.map +1 -0
- package/dist/commands/usage-remediation.js +52 -0
- package/dist/extractors/markdown.d.ts +8 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +69 -2
- package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
- package/dist/operations/modeling/logic-modeling.js +14 -5
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +27 -2
- package/dist/operations/modeling/predicate-applyplan.d.ts +1 -1
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +18 -6
- package/dist/operations/modeling/predicate-inference.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-inference.js +5 -17
- package/dist/operations/modeling/predicate-loader.js +1 -1
- package/dist/operations/modeling/predicate-types.d.ts +9 -1
- package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +35 -11
- package/dist/operations/mutation/audit.js +1 -1
- package/dist/operations/mutation/contradictions.d.ts +1 -1
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +23 -18
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +6 -3
- package/dist/operations/mutation/upsert.d.ts +3 -1
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +51 -12
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +18 -2
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +8 -0
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +76 -61
- package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
- package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/clauses.js +7 -7
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +18 -0
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/ingestion-boundary.js +167 -0
- package/dist/operations/semantic-advisor/shared.d.ts +8 -0
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +37 -3
- package/dist/operations/semantic-advisor/types.d.ts +5 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +9 -2
- package/dist/prolog.d.ts +6 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +240 -61
- package/dist/public/diagnostic-usage.d.ts +17 -0
- package/dist/public/diagnostic-usage.d.ts.map +1 -0
- package/dist/public/diagnostic-usage.js +152 -0
- package/dist/public/distribution-parity.d.ts +90 -0
- package/dist/public/distribution-parity.d.ts.map +1 -0
- package/dist/public/distribution-parity.js +367 -0
- package/dist/public/impact/full-kb-quality.d.ts +2 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +53 -1
- package/dist/public/impact-diagnostics.d.ts +2 -0
- package/dist/public/impact-diagnostics.d.ts.map +1 -1
- package/dist/public/impact-diagnostics.js +1 -0
- package/dist/public/operations/catalog.d.ts +151 -6
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +4 -0
- package/dist/public/operations/discovery-executors.d.ts +6 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +18 -2
- package/dist/public/operations/index.d.ts +4 -0
- package/dist/public/operations/index.d.ts.map +1 -1
- package/dist/public/operations/index.js +4 -0
- package/dist/public/operations/legacy-migration-plan.d.ts +113 -0
- package/dist/public/operations/legacy-migration-plan.d.ts.map +1 -0
- package/dist/public/operations/legacy-migration-plan.js +409 -0
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +90 -0
- package/dist/public/operations/repair-plan.d.ts +184 -0
- package/dist/public/operations/repair-plan.d.ts.map +1 -0
- package/dist/public/operations/repair-plan.js +397 -0
- package/dist/public/operations/runtime-types.d.ts +7 -0
- package/dist/public/operations/runtime-types.d.ts.map +1 -1
- package/dist/public/operations/specs/check.d.ts +2 -2
- package/dist/public/operations/specs/check.js +2 -2
- package/dist/public/operations/specs/discovery.d.ts +1 -1
- package/dist/public/operations/specs/discovery.js +1 -1
- package/dist/public/operations/specs/modeling.d.ts +19 -1
- package/dist/public/operations/specs/modeling.d.ts.map +1 -1
- package/dist/public/operations/specs/modeling.js +16 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +96 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +40 -1
- package/dist/public/operations/specs/reporting.d.ts +42 -1
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +70 -6
- package/dist/public/operations/specs/semantic.js +1 -1
- package/dist/public/operations/specs/upsert.d.ts +96 -1
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/workspace-snapshot.d.ts +10 -0
- package/dist/public/operations/workspace-snapshot.d.ts.map +1 -0
- package/dist/public/operations/workspace-snapshot.js +20 -0
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +43 -1
- package/dist/public/skills/kibi-traceability/SKILL.md +7 -1
- package/dist/public/skills/kibi-usage/SKILL.md +10 -4
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
- package/dist/public/skills/kibi-usage/resources/logic-ir.md +1 -1
- package/dist/public/skills/kibi-usage/resources/workflows.md +19 -2
- package/dist/public/telemetry-acceptance.d.ts +89 -0
- package/dist/public/telemetry-acceptance.d.ts.map +1 -0
- package/dist/public/telemetry-acceptance.js +597 -0
- package/dist/public/telemetry-remediation.d.ts +33 -0
- package/dist/public/telemetry-remediation.d.ts.map +1 -0
- package/dist/public/telemetry-remediation.js +257 -0
- package/dist/public/verification-receipt.d.ts +75 -0
- package/dist/public/verification-receipt.d.ts.map +1 -0
- package/dist/public/verification-receipt.js +129 -0
- package/dist/schemas/entity.schema.json +96 -2
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +36 -3
- package/dist/types/entities.d.ts +1 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/rule-registry.d.ts +2 -0
- package/dist/utils/rule-registry.d.ts.map +1 -1
- package/package.json +30 -2
- package/src/public/diagnostic-usage.ts +206 -0
- package/src/public/distribution-parity.ts +580 -0
- package/src/public/impact/full-kb-quality.ts +74 -1
- package/src/public/impact-diagnostics.ts +16 -0
- package/src/public/operations/check-executor.ts +4 -0
- package/src/public/operations/discovery-executors.ts +24 -2
- package/src/public/operations/index.ts +4 -0
- package/src/public/operations/legacy-migration-plan.ts +688 -0
- package/src/public/operations/node-ports.ts +109 -0
- package/src/public/operations/repair-plan.ts +562 -0
- package/src/public/operations/runtime-types.ts +8 -0
- package/src/public/operations/specs/check.ts +2 -2
- package/src/public/operations/specs/discovery.ts +1 -1
- package/src/public/operations/specs/modeling.ts +19 -1
- package/src/public/operations/specs/mutation-schemas.ts +47 -1
- package/src/public/operations/specs/reporting.ts +91 -6
- package/src/public/operations/specs/semantic.ts +1 -1
- package/src/public/operations/workspace-snapshot.ts +28 -0
- package/src/public/schemas/entity.ts +44 -1
- package/src/public/skills/kibi-traceability/SKILL.md +7 -1
- package/src/public/skills/kibi-usage/SKILL.md +10 -4
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
- package/src/public/skills/kibi-usage/resources/logic-ir.md +1 -1
- package/src/public/skills/kibi-usage/resources/workflows.md +19 -2
- package/src/public/telemetry-acceptance.ts +859 -0
- package/src/public/telemetry-remediation.ts +462 -0
- package/src/public/verification-receipt.ts +170 -0
- package/src/schemas/entity.schema.json +96 -2
package/dist/commands/sync.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
|
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;AAC/C,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EAGzB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,WAAY,SAAQ,mBAAmB;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,aAAa,CAAC,EAAE,QAAQ,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE;QACT,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,aAAa,EAAE;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,SAAS,EAAE;QACT,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,cAAc,EAAE,KAAK,CAAC;YACpB,UAAU,EAAE,MAAM,CAAC;YACnB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;KACJ,CAAC;IACF,OAAO,EAAE;QACP,cAAc,EAAE,KAAK,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;YAClB,cAAc,EAAE,MAAM,CAAC;SACxB,CAAC,CAAC;KACJ,CAAC;IACF,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC,CAAC;IACF,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,UAAU,EAAE,yBAAyB,CAAC;CACvC;AAGD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAgCpC;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAE7D;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,GAAE,IAAiB,GACrB,kBAAkB,CA4HpB"}
|
|
@@ -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
|
-
|
|
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
|
|
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":"
|
|
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;
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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;
|
|
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"}
|