bilmem 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +439 -0
- package/dist/canonical-CglQQ0xc.d.ts +262 -0
- package/dist/cli/index.js +7601 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/index.d.ts +311 -0
- package/dist/core/index.js +1975 -0
- package/dist/core/index.js.map +1 -0
- package/dist/filesystem-B3qAej0l.d.ts +69 -0
- package/dist/index.d.ts +163 -0
- package/dist/index.js +7765 -0
- package/dist/index.js.map +1 -0
- package/dist/install/index.d.ts +373 -0
- package/dist/install/index.js +6632 -0
- package/dist/install/index.js.map +1 -0
- package/dist/jev/index.d.ts +32 -0
- package/dist/jev/index.js +269 -0
- package/dist/jev/index.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +5479 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/rules/index.d.ts +59 -0
- package/dist/rules/index.js +388 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/scanner/index.d.ts +169 -0
- package/dist/scanner/index.js +3829 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/search/index.d.ts +44 -0
- package/dist/search/index.js +301 -0
- package/dist/search/index.js.map +1 -0
- package/dist/stats/index.d.ts +60 -0
- package/dist/stats/index.js +1373 -0
- package/dist/stats/index.js.map +1 -0
- package/dist/storage/index.d.ts +82 -0
- package/dist/storage/index.js +1748 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-Nxq5Gzay.d.ts +390 -0
- package/package.json +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/storage/canonical.ts","../../src/rules/loader.ts","../../src/stats/events.ts","../../src/stats/aggregator.ts","../../src/stats/filter.ts","../../src/stats/format.ts","../../src/stats/index.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n Knowledge,\n Evidence,\n Observation,\n UnknownRecord,\n OutcomeRecord,\n EvidenceRelation,\n BilmemConfig,\n BilmemMetrics,\n RuleSet,\n RuleDefinition,\n RevisionSnapshot,\n KnowledgeDiff,\n InvestigationReceipt\n} from '../core/types.js';\nimport type { KnowledgeStoreProvider } from '../search/retriever.js';\nimport {\n loadRuleSetFile,\n stringifyRuleSetYaml,\n findRuleFiles\n} from '../rules/loader.js';\nimport type { MetricEvent } from '../stats/types.js';\nimport { readMetricEvents, resetMetricEvents } from '../stats/events.js';\n\nexport function sanitizeFileName(id: string): string {\n return encodeURIComponent(id).replace(/%/g, '_');\n}\n\nexport function desanitizeFileName(name: string): string {\n try {\n return decodeURIComponent(name.replace(/_/g, '%'));\n } catch {\n return name;\n }\n}\n\nexport class Storage implements KnowledgeStoreProvider {\n private baseDir: string;\n private knowledgeDir: string;\n private evidenceDir: string;\n private observationDir: string;\n private unknownDir: string;\n private rulesDir: string;\n private configFile: string;\n private relationsFile: string;\n private outcomesFile: string;\n private metricsFile: string;\n private revisionsFile: string;\n private knowledgeJsonlFile: string;\n private evidenceJsonlFile: string;\n private observationJsonlFile: string;\n private unknownsJsonlFile: string;\n private receiptsDir: string;\n private receiptsJsonlFile: string;\n private eventsFile: string;\n\n constructor(rootDir: string = process.cwd()) {\n this.baseDir = path.resolve(rootDir, '.bilmem');\n this.knowledgeDir = path.join(this.baseDir, 'knowledge');\n this.evidenceDir = path.join(this.baseDir, 'evidence');\n this.observationDir = path.join(this.baseDir, 'observations');\n this.unknownDir = path.join(this.baseDir, 'unknowns');\n this.rulesDir = path.join(this.baseDir, 'rules');\n this.receiptsDir = path.join(this.baseDir, 'receipts');\n this.configFile = path.join(this.baseDir, 'config.json');\n this.relationsFile = path.join(this.baseDir, 'relations.json');\n this.outcomesFile = path.join(this.baseDir, 'outcomes.jsonl');\n this.metricsFile = path.join(this.baseDir, 'metrics.json');\n this.revisionsFile = path.join(this.baseDir, 'revisions.jsonl');\n this.knowledgeJsonlFile = path.join(this.baseDir, 'knowledge.jsonl');\n this.evidenceJsonlFile = path.join(this.baseDir, 'evidence.jsonl');\n this.observationJsonlFile = path.join(this.baseDir, 'observations.jsonl');\n this.unknownsJsonlFile = path.join(this.baseDir, 'unknowns.jsonl');\n this.receiptsJsonlFile = path.join(this.baseDir, 'receipts.jsonl');\n this.eventsFile = path.join(this.baseDir, 'events.jsonl');\n }\n\n getBaseDir(): string {\n return this.baseDir;\n }\n\n async isInitialized(): Promise<boolean> {\n try {\n await fs.access(this.configFile);\n return true;\n } catch {\n return false;\n }\n }\n\n async init(options: { projectName?: string; defaultScope?: string } = {}): Promise<BilmemConfig> {\n await fs.mkdir(this.knowledgeDir, { recursive: true });\n await fs.mkdir(this.evidenceDir, { recursive: true });\n await fs.mkdir(this.observationDir, { recursive: true });\n await fs.mkdir(this.unknownDir, { recursive: true });\n await fs.mkdir(this.rulesDir, { recursive: true });\n await fs.mkdir(this.receiptsDir, { recursive: true });\n\n let config: BilmemConfig;\n if (await this.isInitialized()) {\n config = await this.getConfig();\n } else {\n config = {\n schemaVersion: 1,\n projectName: options.projectName ?? path.basename(path.dirname(this.baseDir)) ?? 'project',\n defaultScope: options.defaultScope ?? 'project',\n dataDir: this.baseDir\n };\n await this.saveConfig(config);\n }\n\n // Initialize relations & metrics if missing\n try {\n await fs.access(this.relationsFile);\n } catch {\n await fs.writeFile(this.relationsFile, JSON.stringify([], null, 2), 'utf-8');\n }\n\n try {\n await fs.access(this.metricsFile);\n } catch {\n const defaultMetrics: BilmemMetrics = {\n knowledgeHits: 0,\n knowledgeMisses: 0,\n knowledgeReused: 0,\n unknownsResolved: 0,\n repeatedInvestigationsPrevented: 0,\n candidateKnowledgeMerged: 0,\n staleKnowledgeDetected: 0,\n contradictionsDetected: 0,\n knowledgePromoted: 0,\n knowledgeSuperseded: 0\n };\n await fs.writeFile(this.metricsFile, JSON.stringify(defaultMetrics, null, 2), 'utf-8');\n }\n\n return config;\n }\n\n // --- Config ---\n\n async getConfig(): Promise<BilmemConfig> {\n const raw = await fs.readFile(this.configFile, 'utf-8');\n return JSON.parse(raw) as BilmemConfig;\n }\n\n async saveConfig(config: BilmemConfig): Promise<void> {\n await fs.writeFile(this.configFile, JSON.stringify(config, null, 2), 'utf-8');\n }\n\n async updateConfig(updates: Partial<BilmemConfig>): Promise<BilmemConfig> {\n const current = await this.getConfig();\n const updated = { ...current, ...updates };\n await this.saveConfig(updated);\n return updated;\n }\n\n // --- Knowledge ---\n\n async saveKnowledge(knowledge: Knowledge): Promise<void> {\n await fs.mkdir(this.knowledgeDir, { recursive: true });\n const filename = `${sanitizeFileName(knowledge.id)}.json`;\n const filePath = path.join(this.knowledgeDir, filename);\n await fs.writeFile(filePath, JSON.stringify(knowledge, null, 2), 'utf-8');\n await fs.appendFile(this.knowledgeJsonlFile, JSON.stringify(knowledge) + '\\n', 'utf-8');\n }\n\n async getKnowledge(id: string): Promise<Knowledge | undefined> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.knowledgeDir, filename);\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(raw) as Knowledge;\n } catch {\n return undefined;\n }\n }\n\n async getAllKnowledge(): Promise<Knowledge[]> {\n try {\n const files = await fs.readdir(this.knowledgeDir);\n const items: Knowledge[] = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const raw = await fs.readFile(path.join(this.knowledgeDir, file), 'utf-8');\n try {\n items.push(JSON.parse(raw));\n } catch {\n // Ignore corrupt file\n }\n }\n return items;\n } catch {\n return [];\n }\n }\n\n async deleteKnowledge(id: string): Promise<boolean> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.knowledgeDir, filename);\n try {\n await fs.unlink(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n // --- Evidence ---\n\n async saveEvidence(evidence: Evidence): Promise<void> {\n await fs.mkdir(this.evidenceDir, { recursive: true });\n const filename = `${sanitizeFileName(evidence.id)}.json`;\n const filePath = path.join(this.evidenceDir, filename);\n await fs.writeFile(filePath, JSON.stringify(evidence, null, 2), 'utf-8');\n await fs.appendFile(this.evidenceJsonlFile, JSON.stringify(evidence) + '\\n', 'utf-8');\n }\n\n async getEvidence(id: string): Promise<Evidence | undefined> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.evidenceDir, filename);\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(raw) as Evidence;\n } catch {\n return undefined;\n }\n }\n\n async getAllEvidence(): Promise<Evidence[]> {\n try {\n const files = await fs.readdir(this.evidenceDir);\n const items: Evidence[] = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const raw = await fs.readFile(path.join(this.evidenceDir, file), 'utf-8');\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n return items;\n } catch {\n return [];\n }\n }\n\n // --- Observations ---\n\n async saveObservation(obs: Observation): Promise<void> {\n await fs.mkdir(this.observationDir, { recursive: true });\n const filename = `${sanitizeFileName(obs.id)}.json`;\n const filePath = path.join(this.observationDir, filename);\n await fs.writeFile(filePath, JSON.stringify(obs, null, 2), 'utf-8');\n await fs.appendFile(this.observationJsonlFile, JSON.stringify(obs) + '\\n', 'utf-8');\n }\n\n async getObservation(id: string): Promise<Observation | undefined> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.observationDir, filename);\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(raw) as Observation;\n } catch {\n return undefined;\n }\n }\n\n async getAllObservations(): Promise<Observation[]> {\n try {\n const files = await fs.readdir(this.observationDir);\n const items: Observation[] = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const raw = await fs.readFile(path.join(this.observationDir, file), 'utf-8');\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n return items;\n } catch {\n return [];\n }\n }\n\n async deleteObservation(id: string): Promise<boolean> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.observationDir, filename);\n try {\n await fs.unlink(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n // --- Unknowns ---\n\n async saveUnknown(record: UnknownRecord): Promise<void> {\n await fs.mkdir(this.unknownDir, { recursive: true });\n const filename = `${sanitizeFileName(record.id)}.json`;\n const filePath = path.join(this.unknownDir, filename);\n await fs.writeFile(filePath, JSON.stringify(record, null, 2), 'utf-8');\n await fs.appendFile(this.unknownsJsonlFile, JSON.stringify(record) + '\\n', 'utf-8');\n }\n\n async getUnknown(id: string): Promise<UnknownRecord | undefined> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.unknownDir, filename);\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(raw) as UnknownRecord;\n } catch {\n return undefined;\n }\n }\n\n async getAllUnknowns(): Promise<UnknownRecord[]> {\n try {\n const files = await fs.readdir(this.unknownDir);\n const items: UnknownRecord[] = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const raw = await fs.readFile(path.join(this.unknownDir, file), 'utf-8');\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n return items;\n } catch {\n return [];\n }\n }\n\n async deleteUnknown(id: string): Promise<boolean> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.unknownDir, filename);\n try {\n await fs.unlink(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n // --- Outcomes (Append-oriented log) ---\n\n async appendOutcome(outcome: OutcomeRecord): Promise<void> {\n const line = JSON.stringify(outcome) + '\\n';\n await fs.appendFile(this.outcomesFile, line, 'utf-8');\n if (outcome.knowledgeId) {\n await this.appendMetricEvent({\n type: 'outcome',\n knowledgeId: outcome.knowledgeId,\n result: outcome.result,\n timestamp: Date.now()\n });\n if (outcome.result === 'success') {\n await this.appendMetricEvent({\n type: 'question_resolved',\n questionId: outcome.knowledgeId,\n timestamp: Date.now()\n });\n }\n }\n }\n\n async getAllOutcomes(): Promise<OutcomeRecord[]> {\n try {\n const raw = await fs.readFile(this.outcomesFile, 'utf-8');\n const lines = raw.split('\\n').filter((l) => l.trim().length > 0);\n return lines.map((l) => JSON.parse(l));\n } catch {\n return [];\n }\n }\n\n // --- Metric Events (Append-only local log) ---\n\n async appendMetricEvent(event: MetricEvent): Promise<void> {\n try {\n await fs.mkdir(this.baseDir, { recursive: true });\n await fs.appendFile(this.eventsFile, JSON.stringify(event) + '\\n', 'utf-8');\n } catch {\n // non-fatal\n }\n }\n\n async getMetricEvents(filter?: { sinceTimestamp?: number; knowledgeId?: string }): Promise<MetricEvent[]> {\n return readMetricEvents(path.dirname(this.baseDir), filter);\n }\n\n async resetMetricEvents(): Promise<void> {\n return resetMetricEvents(path.dirname(this.baseDir));\n }\n\n // --- Investigation Receipts ---\n\n async saveReceipt(receipt: InvestigationReceipt): Promise<void> {\n await fs.mkdir(this.receiptsDir, { recursive: true });\n const filename = `${sanitizeFileName(receipt.id)}.json`;\n const filePath = path.join(this.receiptsDir, filename);\n await fs.writeFile(filePath, JSON.stringify(receipt, null, 2), 'utf-8');\n await fs.appendFile(this.receiptsJsonlFile, JSON.stringify(receipt) + '\\n', 'utf-8');\n }\n\n async getReceipt(id: string): Promise<InvestigationReceipt | undefined> {\n const filename = `${sanitizeFileName(id)}.json`;\n const filePath = path.join(this.receiptsDir, filename);\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(raw) as InvestigationReceipt;\n } catch {\n return undefined;\n }\n }\n\n async getAllReceipts(): Promise<InvestigationReceipt[]> {\n try {\n const files = await fs.readdir(this.receiptsDir);\n const items: InvestigationReceipt[] = [];\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const raw = await fs.readFile(path.join(this.receiptsDir, file), 'utf-8');\n try {\n items.push(JSON.parse(raw));\n } catch {}\n }\n return items;\n } catch {\n return [];\n }\n }\n\n // --- Relations ---\n\n async getRelations(): Promise<EvidenceRelation[]> {\n try {\n const raw = await fs.readFile(this.relationsFile, 'utf-8');\n return JSON.parse(raw) as EvidenceRelation[];\n } catch {\n return [];\n }\n }\n\n async saveRelations(relations: EvidenceRelation[]): Promise<void> {\n await fs.writeFile(this.relationsFile, JSON.stringify(relations, null, 2), 'utf-8');\n }\n\n // --- Metrics ---\n\n async getMetrics(): Promise<BilmemMetrics> {\n try {\n const raw = await fs.readFile(this.metricsFile, 'utf-8');\n return JSON.parse(raw) as BilmemMetrics;\n } catch {\n return {\n knowledgeHits: 0,\n knowledgeMisses: 0,\n knowledgeReused: 0,\n unknownsResolved: 0,\n repeatedInvestigationsPrevented: 0,\n candidateKnowledgeMerged: 0,\n staleKnowledgeDetected: 0,\n contradictionsDetected: 0,\n knowledgePromoted: 0,\n knowledgeSuperseded: 0\n };\n }\n }\n\n async saveMetrics(metrics: BilmemMetrics): Promise<void> {\n await fs.writeFile(this.metricsFile, JSON.stringify(metrics, null, 2), 'utf-8');\n }\n\n // --- Rules ---\n\n getRulesDir(): string {\n return this.rulesDir;\n }\n\n async loadRuleSets(): Promise<RuleSet[]> {\n const files = await findRuleFiles(path.dirname(this.baseDir), this.rulesDir);\n const sets: RuleSet[] = [];\n for (const f of files) {\n try {\n sets.push(await loadRuleSetFile(f));\n } catch {}\n }\n return sets;\n }\n\n async saveRuleSet(ruleSet: RuleSet, fileName: string = 'default.yml'): Promise<string> {\n await fs.mkdir(this.rulesDir, { recursive: true });\n const cleanName = fileName.endsWith('.yml') || fileName.endsWith('.yaml') ? fileName : `${fileName}.yml`;\n const targetPath = path.join(this.rulesDir, cleanName);\n const yaml = stringifyRuleSetYaml(ruleSet);\n await fs.writeFile(targetPath, yaml, 'utf-8');\n return targetPath;\n }\n\n async addRule(rule: RuleDefinition, fileName: string = 'default.yml'): Promise<string> {\n await fs.mkdir(this.rulesDir, { recursive: true });\n const cleanName = fileName.endsWith('.yml') || fileName.endsWith('.yaml') ? fileName : `${fileName}.yml`;\n const targetPath = path.join(this.rulesDir, cleanName);\n\n let existingSet: RuleSet;\n try {\n existingSet = await loadRuleSetFile(targetPath);\n } catch {\n existingSet = {\n name: path.basename(cleanName, path.extname(cleanName)),\n rules: []\n };\n }\n\n const existingIdx = existingSet.rules.findIndex((r) => r.id === rule.id);\n if (existingIdx >= 0) {\n existingSet.rules[existingIdx] = rule;\n } else {\n existingSet.rules.push(rule);\n }\n\n const yaml = stringifyRuleSetYaml(existingSet);\n await fs.writeFile(targetPath, yaml, 'utf-8');\n return targetPath;\n }\n\n // --- Revisions & Incremental Learning Diff ---\n\n async appendRevision(snapshot: RevisionSnapshot): Promise<void> {\n const line = JSON.stringify(snapshot) + '\\n';\n await fs.appendFile(this.revisionsFile, line, 'utf-8');\n }\n\n async getRevisions(): Promise<RevisionSnapshot[]> {\n try {\n const raw = await fs.readFile(this.revisionsFile, 'utf-8');\n const lines = raw.split('\\n').filter((l) => l.trim().length > 0);\n return lines.map((l) => JSON.parse(l));\n } catch {\n return [];\n }\n }\n\n async getLatestRevision(): Promise<RevisionSnapshot | undefined> {\n const revs = await this.getRevisions();\n return revs.length > 0 ? revs[revs.length - 1] : undefined;\n }\n\n async getDiff(sinceRef?: string): Promise<KnowledgeDiff> {\n const revisions = await this.getRevisions();\n let baselineSnapshot: RevisionSnapshot | undefined;\n let targetSnapshot: RevisionSnapshot | undefined;\n\n if (sinceRef && sinceRef.includes('..')) {\n const [startRef, endRef] = sinceRef.split('..').map((s) => s.trim().toLowerCase());\n baselineSnapshot = revisions.find(\n (r) =>\n r.id.toLowerCase() === startRef ||\n r.commit?.toLowerCase() === startRef ||\n r.commit?.toLowerCase().startsWith(startRef) ||\n r.id.toLowerCase().startsWith(startRef)\n );\n targetSnapshot = revisions.find(\n (r) =>\n r.id.toLowerCase() === endRef ||\n r.commit?.toLowerCase() === endRef ||\n r.commit?.toLowerCase().startsWith(endRef) ||\n r.id.toLowerCase().startsWith(endRef)\n );\n } else if (sinceRef) {\n const cleanRef = sinceRef.trim().toLowerCase();\n baselineSnapshot = revisions.find(\n (r) =>\n r.id.toLowerCase() === cleanRef ||\n r.commit?.toLowerCase() === cleanRef ||\n r.commit?.toLowerCase().startsWith(cleanRef) ||\n r.id.toLowerCase().startsWith(cleanRef)\n );\n } else {\n // If no ref provided, compare against the snapshot before the latest (if available)\n if (revisions.length >= 2) {\n baselineSnapshot = revisions[revisions.length - 2];\n } else if (revisions.length === 1) {\n baselineSnapshot = revisions[0];\n }\n }\n\n const baselineTimestamp = baselineSnapshot?.timestamp ?? '1970-01-01T00:00:00.000Z';\n const baselineTime = new Date(baselineTimestamp).getTime();\n const targetTime = targetSnapshot ? new Date(targetSnapshot.timestamp).getTime() : Date.now();\n\n const inWindow = (time: number) => time >= baselineTime && time <= targetTime;\n\n const allObservations = await this.getAllObservations();\n const allKnowledge = await this.getAllKnowledge();\n const allUnknowns = await this.getAllUnknowns();\n\n let observationsAdded = 0;\n for (const obs of allObservations) {\n const obsTime = new Date(obs.recordedAt || obs.provenance?.timestamp || 0).getTime();\n if (inWindow(obsTime)) {\n observationsAdded++;\n }\n }\n\n let candidatesAdded = 0;\n let strengthenedCount = 0;\n let revisedCount = 0;\n let contradictionCount = 0;\n let invalidatedCount = 0;\n let needsRevalidationCount = 0;\n\n const strengthened: string[] = [];\n const revised: string[] = [];\n const contradictions: string[] = [];\n const invalidated: string[] = [];\n const needsRevalidation: string[] = [];\n\n for (const k of allKnowledge) {\n const createdTime = new Date(k.createdAt).getTime();\n const updatedTime = new Date(k.updatedAt).getTime();\n\n if ((k.status === 'invalid' || k.status === 'invalidated') && inWindow(updatedTime)) {\n invalidatedCount++;\n invalidated.push(k.id);\n continue;\n }\n\n if (k.status === 'contradicted' && inWindow(updatedTime)) {\n contradictionCount++;\n contradictions.push(k.id);\n continue;\n }\n\n if ((k.status === 'needs_revalidation' || k.status === 'stale') && inWindow(updatedTime)) {\n needsRevalidationCount++;\n needsRevalidation.push(k.id);\n continue;\n }\n\n if (inWindow(createdTime)) {\n // Newly added knowledge candidate in this window\n candidatesAdded++;\n } else if (inWindow(updatedTime)) {\n // Pre-existing knowledge revised or strengthened\n if (k.metrics.support_count > 1 || k.confidence >= 0.85 || k.metrics.successful_outcomes > 0) {\n strengthenedCount++;\n strengthened.push(k.id);\n } else {\n revisedCount++;\n revised.push(k.id);\n }\n }\n }\n\n let unknownsCount = 0;\n const unknownsList: string[] = [];\n for (const u of allUnknowns) {\n const uTime = new Date(u.createdAt || u.updatedAt || 0).getTime();\n if (inWindow(uTime)) {\n unknownsCount++;\n unknownsList.push(u.id);\n }\n }\n\n const refLabel = sinceRef ?? (baselineSnapshot ? (baselineSnapshot.commit?.slice(0, 7) || baselineSnapshot.id.slice(0, 7)) : undefined);\n\n return {\n sinceRef: refLabel,\n observationsAdded,\n candidatesAdded,\n strengthenedCount,\n revisedCount,\n contradictionCount,\n unknownsCount,\n needsRevalidationCount,\n invalidatedCount,\n details: {\n strengthened,\n revised,\n contradictions,\n unknowns: unknownsList,\n needsRevalidation,\n invalidated\n }\n };\n }\n}\n\nexport function formatKnowledgeDiff(diff: KnowledgeDiff): string {\n const header = diff.sinceRef ? `Since ${diff.sinceRef}:` : 'Recent knowledge changes:';\n const lines = [\n header,\n '',\n `+ ${diff.observationsAdded} observations`,\n `+ ${diff.candidatesAdded} candidates`,\n `↑ ${diff.strengthenedCount} knowledge strengthened`,\n `~ ${diff.revisedCount} knowledge revised`,\n `! ${diff.contradictionCount} contradiction${diff.contradictionCount === 1 ? '' : 's'}`,\n `? ${diff.unknownsCount ?? 0} unknowns`,\n `× ${diff.needsRevalidationCount ?? 0} knowledge needs revalidation`,\n `- ${diff.invalidatedCount} invalidated`\n ];\n return lines.join('\\n');\n}\n\nexport { Storage as CanonicalStorage };\n\n","import YAML from 'yaml';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { RuleDefinition, RuleSet, KnowledgeType } from '../core/types.js';\n\nexport interface RuleValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validates whether an object conforms to the RuleDefinition specification.\n */\nexport function validateRuleDefinition(rule: unknown, index: number = 0): string[] {\n const errors: string[] = [];\n if (!rule || typeof rule !== 'object') {\n errors.push(`Rule at index ${index} must be an object.`);\n return errors;\n }\n\n const r = rule as Partial<RuleDefinition>;\n if (!r.id || typeof r.id !== 'string' || !r.id.trim()) {\n errors.push(`Rule at index ${index} requires a non-empty string 'id'.`);\n }\n\n if (!r.statement || typeof r.statement !== 'string' || !r.statement.trim()) {\n errors.push(`Rule '${r.id || index}' requires a non-empty string 'statement'.`);\n }\n\n if (r.type) {\n const validTypes: KnowledgeType[] = [\n 'rule',\n 'convention',\n 'decision',\n 'lesson',\n 'architecture',\n 'fact'\n ];\n if (!validTypes.includes(r.type)) {\n errors.push(`Rule '${r.id || index}' has invalid type '${r.type}'. Allowed: ${validTypes.join(', ')}.`);\n }\n }\n\n if (r.confidence !== undefined) {\n if (typeof r.confidence !== 'number' || r.confidence < 0 || r.confidence > 1) {\n errors.push(`Rule '${r.id || index}' confidence must be a number between 0.0 and 1.0.`);\n }\n }\n\n if (r.positive !== undefined && !Array.isArray(r.positive)) {\n errors.push(`Rule '${r.id || index}' positive cues must be an array of strings.`);\n }\n\n if (r.negative !== undefined && !Array.isArray(r.negative)) {\n errors.push(`Rule '${r.id || index}' negative cues must be an array of strings.`);\n }\n\n return errors;\n}\n\n/**\n * Validates a RuleSet structure.\n */\nexport function validateRuleSet(data: unknown): RuleValidationResult {\n const errors: string[] = [];\n if (!data || typeof data !== 'object') {\n return { valid: false, errors: ['RuleSet content must be an object or an array of rules.'] };\n }\n\n let rules: unknown[] = [];\n if (Array.isArray(data)) {\n rules = data;\n } else if ('rules' in data && Array.isArray((data as any).rules)) {\n rules = (data as any).rules;\n } else if ('id' in data && 'statement' in data) {\n rules = [data];\n } else {\n return { valid: false, errors: ['RuleSet must contain a \"rules\" array or be a list of rule definitions.'] };\n }\n\n if (rules.length === 0) {\n errors.push('RuleSet contains no rules.');\n }\n\n rules.forEach((rule, idx) => {\n errors.push(...validateRuleDefinition(rule, idx));\n });\n\n return {\n valid: errors.length === 0,\n errors\n };\n}\n\n/**\n * Parses a YAML string into a normalized RuleSet.\n */\nexport function parseRuleSetYaml(content: string, sourcePath: string = 'inline.yml'): RuleSet {\n let parsed: unknown;\n try {\n parsed = YAML.parse(content);\n } catch (err: any) {\n throw new Error(`YAML syntax error in ${sourcePath}: ${err.message}`);\n }\n\n const validation = validateRuleSet(parsed);\n if (!validation.valid) {\n throw new Error(`Invalid RuleSet in ${sourcePath}:\\n- ${validation.errors.join('\\n- ')}`);\n }\n\n if (Array.isArray(parsed)) {\n return {\n name: path.basename(sourcePath, path.extname(sourcePath)),\n rules: parsed as RuleDefinition[]\n };\n }\n\n if ('id' in (parsed as any) && 'statement' in (parsed as any) && !('rules' in (parsed as any))) {\n return {\n name: (parsed as any).id,\n rules: [parsed as RuleDefinition]\n };\n }\n\n const set = parsed as RuleSet;\n return {\n name: set.name ?? path.basename(sourcePath, path.extname(sourcePath)),\n version: set.version ?? 1,\n scope: set.scope ?? 'project',\n description: set.description,\n rules: set.rules\n };\n}\n\n/**\n * Formats a RuleSet into clean, Git-friendly YAML.\n */\nexport function stringifyRuleSetYaml(ruleSet: RuleSet): string {\n const payload: Record<string, unknown> = {};\n if (ruleSet.name) payload.name = ruleSet.name;\n if (ruleSet.version !== undefined) payload.version = ruleSet.version;\n if (ruleSet.scope) payload.scope = ruleSet.scope;\n if (ruleSet.description) payload.description = ruleSet.description;\n\n payload.rules = ruleSet.rules.map((r) => {\n const ruleObj: Record<string, unknown> = {\n id: r.id\n };\n if (r.name) ruleObj.name = r.name;\n ruleObj.statement = r.statement;\n if (r.type && r.type !== 'rule') ruleObj.type = r.type;\n if (r.confidence !== undefined && r.confidence !== 0.95) ruleObj.confidence = r.confidence;\n if (r.scope && r.scope !== 'project') ruleObj.scope = r.scope;\n if (r.positive && r.positive.length > 0) ruleObj.positive = r.positive;\n if (r.negative && r.negative.length > 0) ruleObj.negative = r.negative;\n if (r.tags && r.tags.length > 0) ruleObj.tags = r.tags;\n if (r.when && Object.keys(r.when).length > 0) ruleObj.when = r.when;\n if (r.details && Object.keys(r.details).length > 0) ruleObj.details = r.details;\n return ruleObj;\n });\n\n return YAML.stringify(payload, { indent: 2, lineWidth: 100 });\n}\n\n/**\n * Reads and parses a single YAML rule file.\n */\nexport async function loadRuleSetFile(filePath: string): Promise<RuleSet> {\n const content = await fs.readFile(filePath, 'utf-8');\n return parseRuleSetYaml(content, filePath);\n}\n\n/**\n * Finds all rule YAML files in standard bilmem locations.\n */\nexport async function findRuleFiles(rootDir: string, storageRulesDir?: string): Promise<string[]> {\n const candidates: string[] = [];\n\n // 1. Storage rules directory: .bilmem/rules/*.yml, *.yaml\n const rulesDir = storageRulesDir || path.resolve(rootDir, '.bilmem', 'rules');\n try {\n const entries = await fs.readdir(rulesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && (entry.name.endsWith('.yml') || entry.name.endsWith('.yaml'))) {\n candidates.push(path.join(rulesDir, entry.name));\n }\n }\n } catch {\n // Directory might not exist yet\n }\n\n // 2. Storage root: .bilmem/rules.yml, .bilmem/rules.yaml\n for (const name of ['rules.yml', 'rules.yaml']) {\n const p = path.resolve(rootDir, '.bilmem', name);\n try {\n const st = await fs.stat(p);\n if (st.isFile()) candidates.push(p);\n } catch {}\n }\n\n // 3. Project root: rules.yml, rules.yaml, bilmem.rules.yml, bilmem.rules.yaml\n for (const name of ['bilmem.rules.yml', 'bilmem.rules.yaml', 'rules.yml', 'rules.yaml']) {\n const p = path.resolve(rootDir, name);\n try {\n const st = await fs.stat(p);\n if (st.isFile()) candidates.push(p);\n } catch {}\n }\n\n // Deduplicate canonical paths\n return Array.from(new Set(candidates));\n}\n\n/**\n * Loads and combines all rule sets discovered in project and storage.\n */\nexport async function loadAllProjectRuleSets(\n rootDir: string,\n storageRulesDir?: string\n): Promise<{ ruleSets: RuleSet[]; sourceFiles: string[] }> {\n const files = await findRuleFiles(rootDir, storageRulesDir);\n const ruleSets: RuleSet[] = [];\n const loadedFiles: string[] = [];\n\n for (const file of files) {\n try {\n const set = await loadRuleSetFile(file);\n ruleSets.push(set);\n loadedFiles.push(file);\n } catch (err: any) {\n // Log or keep error context without failing the entire scan\n console.warn(`[bilmem] Warning: Failed to load rule set from ${file}: ${err.message}`);\n }\n }\n\n return { ruleSets, sourceFiles: loadedFiles };\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { MetricEvent } from './types.js';\n\nexport function getEventsFilePath(rootDir: string): string {\n return path.join(rootDir, '.bilmem', 'events.jsonl');\n}\n\n/**\n * Appends a metric event to .bilmem/events.jsonl.\n * Fire-and-forget safe: will not crash caller if filesystem error occurs.\n */\nexport async function appendMetricEvent(\n rootDir: string,\n event: MetricEvent\n): Promise<void> {\n const filePath = getEventsFilePath(rootDir);\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(filePath, line, 'utf-8');\n } catch {\n // Non-fatal logging failure: core operations must never fail due to metric tracking\n }\n}\n\n/**\n * Reads all metric events from .bilmem/events.jsonl with resilience against\n * corrupted tails, empty lines, and malformed entries.\n */\nexport async function readMetricEvents(\n rootDir: string,\n filter?: { sinceTimestamp?: number; knowledgeId?: string }\n): Promise<MetricEvent[]> {\n const filePath = getEventsFilePath(rootDir);\n let raw: string;\n try {\n raw = await fs.readFile(filePath, 'utf-8');\n } catch (err: any) {\n if (err.code === 'ENOENT') {\n return [];\n }\n return [];\n }\n\n const lines = raw.split('\\n');\n const events: MetricEvent[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const parsed = JSON.parse(trimmed) as MetricEvent;\n if (!parsed || typeof parsed !== 'object' || typeof parsed.type !== 'string') {\n continue;\n }\n if (typeof parsed.timestamp !== 'number') {\n continue;\n }\n\n if (filter?.sinceTimestamp !== undefined && parsed.timestamp < filter.sinceTimestamp) {\n continue;\n }\n\n if (filter?.knowledgeId !== undefined) {\n const kid = (parsed as { knowledgeId?: string }).knowledgeId;\n if (kid !== filter.knowledgeId) {\n continue;\n }\n }\n\n events.push(parsed);\n } catch {\n // Gracefully ignore corrupted line / partial write\n continue;\n }\n }\n\n return events;\n}\n\n/**\n * Safely resets only the metric events log.\n * Preserves all knowledge, evidence, unknowns, rules, and receipts.\n */\nexport async function resetMetricEvents(rootDir: string): Promise<void> {\n const filePath = getEventsFilePath(rootDir);\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, '', 'utf-8');\n } catch (err: any) {\n if (err.code !== 'ENOENT') throw err;\n }\n}\n","import type { Storage } from '../storage/canonical.js';\nimport type { Knowledge, KnowledgeStatus } from '../core/types.js';\nimport type {\n MetricEvent,\n StatsReport,\n KnowledgeStatsReport,\n KnowledgeHealthCategory,\n EffectivenessRatio\n} from './types.js';\n\nfunction formatPercentage(ratio?: number): string {\n if (ratio === undefined || isNaN(ratio)) {\n return '—';\n }\n return `${(ratio * 100).toFixed(1)}%`;\n}\n\nfunction formatRelativeTime(dateStr?: string | number): string | undefined {\n if (!dateStr) return undefined;\n const ts = typeof dateStr === 'number' ? dateStr : Date.parse(dateStr);\n if (isNaN(ts)) return undefined;\n\n const diffMs = Date.now() - ts;\n const diffSec = Math.floor(diffMs / 1000);\n if (diffSec < 60) return `${diffSec}s ago`;\n const diffMin = Math.floor(diffSec / 60);\n if (diffMin < 60) return `${diffMin}m ago`;\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24) return `${diffHr}h ago`;\n const diffDays = Math.floor(diffHr / 24);\n return `${diffDays}d ago`;\n}\n\nexport function classifyKnowledgeHealth(\n knowledge: Knowledge,\n knowledgeEvents: MetricEvent[],\n independentSourcesCount: number\n): { category: KnowledgeHealthCategory; reason: string } {\n // 1. Needs Revalidation\n if (knowledge.status === 'needs_revalidation' || knowledge.status === 'stale') {\n return {\n category: 'NEEDS_REVALIDATION',\n reason: 'Underlying source or dependency changed since last validation'\n };\n }\n\n // 2. Frequently Misleading\n const outcomes = knowledgeEvents.filter((e) => e.type === 'outcome') as Array<\n MetricEvent & { type: 'outcome' }\n >;\n const misleadingCount = outcomes.filter(\n (o) => o.result === 'failure' || o.result === 'reverted' || (o as any).result === 'misleading'\n ).length + (knowledge.outcomesSummary?.misleading ?? 0);\n const successCount = outcomes.filter((o) => o.result === 'success').length +\n (knowledge.metrics.successful_outcomes ?? 0);\n\n if (misleadingCount > 0 && misleadingCount >= successCount) {\n return {\n category: 'FREQUENTLY_MISLEADING',\n reason: `${misleadingCount} negative or misleading outcome(s) recorded`\n };\n }\n\n // 3. Frequently Rejected by JEV\n const jevEvents = knowledgeEvents.filter((e) => e.type === 'jev_result') as Array<\n MetricEvent & { type: 'jev_result' }\n >;\n const rejectCount = jevEvents.filter((j) => j.result === 'REJECT').length;\n if (jevEvents.length >= 3 && rejectCount / jevEvents.length >= 0.7) {\n return {\n category: 'FREQUENTLY_REJECTED',\n reason: `Rejected in ${rejectCount} of ${jevEvents.length} JEV evaluations`\n };\n }\n\n // 4. Low Evidence\n if (independentSourcesCount < 2 && knowledge.confidence < 0.75) {\n return {\n category: 'LOW_EVIDENCE',\n reason: `Only ${independentSourcesCount} independent source(s) and confidence < 0.75`\n };\n }\n\n // 5. Unused\n const reuseCount =\n knowledge.metrics.reuse_count +\n knowledgeEvents.filter((e) => e.type === 'knowledge_reused').length;\n const createdAtMs = Date.parse(knowledge.createdAt);\n const ageHours = !isNaN(createdAtMs) ? (Date.now() - createdAtMs) / (1000 * 3600) : 0;\n if (reuseCount === 0 && ageHours > 1) {\n return {\n category: 'UNUSED',\n reason: 'No reuse recorded since creation'\n };\n }\n\n // 6. Healthy\n return {\n category: 'HEALTHY',\n reason: 'Active with verified evidence and clean outcome history'\n };\n}\n\nexport async function computeStats(\n storage: Storage,\n events: MetricEvent[],\n options?: { since?: string; sinceTimestamp?: number }\n): Promise<StatsReport> {\n // 1. Current State Metrics (read directly from current Bilmem state, never drift)\n const allKnowledge = await storage.getAllKnowledge();\n const allUnknowns = await storage.getAllUnknowns();\n\n let active = 0;\n let candidates = 0;\n let conflicted = 0;\n let needsRevalidation = 0;\n let stale = 0;\n\n for (const k of allKnowledge) {\n if (k.status === 'active') active++;\n else if (k.status === 'candidate' || k.stage === 'candidate') candidates++;\n else if (k.status === 'contradicted') conflicted++;\n else if (k.status === 'needs_revalidation') needsRevalidation++;\n else if (k.status === 'stale') stale++;\n }\n\n // 2. Activity Metrics (aggregated from events)\n const learning = {\n observations: 0,\n new: 0,\n merged: 0,\n strengthened: 0,\n specialized: 0,\n superseded: 0,\n contradictions: 0,\n ignoredDuplicates: 0\n };\n\n const resolution = {\n resolveCalls: 0,\n known: 0,\n partiallyKnown: 0,\n unknown: 0,\n conflicted: 0,\n stale: 0\n };\n\n const investigation = {\n repeatedChecksAvoided: 0,\n knowledgeReused: 0,\n questionsSuggested: 0,\n questionsResolved: 0,\n broadSearchesAvoided: 0,\n sourceReadsAvoided: 0,\n investigationsReused: 0\n };\n\n const jev = {\n candidates: 0,\n match: 0,\n possible: 0,\n rejected: 0,\n hardNegativeRejects: 0,\n reasons: {\n hardNegative: 0,\n scopeMismatch: 0,\n insufficientContext: 0,\n staleKnowledge: 0\n }\n };\n\n const actions: Record<string, number> = {};\n\n for (const e of events) {\n switch (e.type) {\n case 'knowledge_created':\n learning.new++;\n break;\n case 'knowledge_merged':\n learning.merged++;\n break;\n case 'knowledge_strengthened':\n learning.strengthened++;\n break;\n case 'knowledge_specialized':\n learning.specialized++;\n break;\n case 'knowledge_superseded':\n learning.superseded++;\n break;\n case 'contradiction_detected':\n learning.contradictions++;\n break;\n case 'duplicate_ignored':\n learning.ignoredDuplicates++;\n break;\n\n case 'resolve':\n resolution.resolveCalls++;\n if (e.state === 'KNOWN') resolution.known++;\n else if (e.state === 'PARTIALLY_KNOWN') resolution.partiallyKnown++;\n else if (e.state === 'UNKNOWN') resolution.unknown++;\n else if (e.state === 'CONFLICTED') resolution.conflicted++;\n else if (e.state === 'STALE') resolution.stale++;\n\n if (e.action) {\n actions[e.action] = (actions[e.action] ?? 0) + 1;\n }\n break;\n\n case 'knowledge_reused':\n investigation.knowledgeReused++;\n break;\n case 'question_suggested':\n investigation.questionsSuggested++;\n break;\n case 'question_resolved':\n investigation.questionsResolved++;\n break;\n case 'broad_search_avoided':\n investigation.broadSearchesAvoided++;\n break;\n case 'source_read_avoided':\n investigation.sourceReadsAvoided++;\n investigation.repeatedChecksAvoided++;\n break;\n case 'investigation_reused':\n investigation.investigationsReused++;\n investigation.repeatedChecksAvoided++;\n break;\n\n case 'jev_result':\n jev.candidates++;\n if (e.result === 'MATCH') jev.match++;\n else if (e.result === 'POSSIBLE') jev.possible++;\n else if (e.result === 'REJECT') {\n jev.rejected++;\n const reason = String(e.reason || '').toUpperCase();\n if (reason.includes('HARD_NEGATIVE') || reason.includes('FORBIDS')) {\n jev.hardNegativeRejects++;\n jev.reasons.hardNegative++;\n } else if (reason.includes('SCOPE')) {\n jev.reasons.scopeMismatch++;\n } else if (reason.includes('STALE')) {\n jev.reasons.staleKnowledge++;\n } else {\n jev.reasons.insufficientContext++;\n }\n }\n break;\n\n case 'jev_hard_negative':\n // Counted if not already accounted for\n break;\n }\n }\n\n // Count total observations from storage\n try {\n const allObs = await storage.getAllObservations();\n learning.observations = allObs.length;\n } catch {\n learning.observations = 0;\n }\n\n // 3. Effectiveness Ratios\n // Knowledge reuse rate: resolve operations that reused existing applicable knowledge / all resolve operations\n const reuseRatio =\n resolution.resolveCalls > 0\n ? Math.min(1.0, (resolution.known + Math.min(resolution.partiallyKnown, investigation.knowledgeReused)) / resolution.resolveCalls)\n : undefined;\n\n const knowledgeReuseRate: EffectivenessRatio = {\n value: reuseRatio,\n formatted: reuseRatio !== undefined ? formatPercentage(reuseRatio) : '— (Not enough observations)',\n formula: 'resolve operations that reused existing applicable knowledge / all resolve operations'\n };\n\n // Resolve success rate: (KNOWN + successfully resolved PARTIALLY_KNOWN) / all completed resolve attempts\n const resolveSuccessRatio =\n resolution.resolveCalls > 0\n ? Math.min(1.0, (resolution.known + investigation.questionsResolved) / resolution.resolveCalls)\n : undefined;\n\n const resolveSuccessRate: EffectivenessRatio = {\n value: resolveSuccessRatio,\n formatted: resolveSuccessRatio !== undefined ? formatPercentage(resolveSuccessRatio) : '— (Not enough observations)',\n formula: '(KNOWN + successfully resolved PARTIALLY_KNOWN) / all completed resolve attempts'\n };\n\n // Question resolution rate: questions resolved / questions suggested\n const questionRatio =\n investigation.questionsSuggested > 0\n ? Math.min(1.0, investigation.questionsResolved / investigation.questionsSuggested)\n : undefined;\n\n const questionResolutionRate: EffectivenessRatio = {\n value: questionRatio,\n formatted: questionRatio !== undefined ? formatPercentage(questionRatio) : '— (Not enough observations)',\n formula: 'questions resolved / questions suggested'\n };\n\n // JEV rejection rate: JEV rejected candidates / all JEV candidates evaluated\n const jevRatio =\n jev.candidates > 0\n ? jev.rejected / jev.candidates\n : undefined;\n\n const jevRejectionRate: EffectivenessRatio = {\n value: jevRatio,\n formatted: jevRatio !== undefined ? formatPercentage(jevRatio) : '— (Not enough observations)',\n formula: 'JEV rejected candidates / all JEV candidates evaluated'\n };\n\n // 4. Knowledge Health Distribution\n const health = {\n healthy: 0,\n needsRevalidation: 0,\n lowEvidence: 0,\n frequentlyRejected: 0,\n frequentlyMisleading: 0,\n unused: 0\n };\n\n const eventsByKnowledge = new Map<string, MetricEvent[]>();\n for (const e of events) {\n const kid = (e as { knowledgeId?: string }).knowledgeId;\n if (kid) {\n const list = eventsByKnowledge.get(kid) || [];\n list.push(e);\n eventsByKnowledge.set(kid, list);\n }\n }\n\n for (const k of allKnowledge) {\n const kEvents = eventsByKnowledge.get(k.id) || [];\n const uniqueSources = new Set(k.evidence.map((ev) => ev.replace(/^(code|file|test|doc):/, '')));\n const { category } = classifyKnowledgeHealth(k, kEvents, uniqueSources.size);\n\n switch (category) {\n case 'HEALTHY':\n health.healthy++;\n break;\n case 'NEEDS_REVALIDATION':\n health.needsRevalidation++;\n break;\n case 'LOW_EVIDENCE':\n health.lowEvidence++;\n break;\n case 'FREQUENTLY_REJECTED':\n health.frequentlyRejected++;\n break;\n case 'FREQUENTLY_MISLEADING':\n health.frequentlyMisleading++;\n break;\n case 'UNUSED':\n health.unused++;\n break;\n }\n }\n\n return {\n since: options?.since,\n sinceTimestamp: options?.sinceTimestamp,\n knowledge: {\n active,\n candidates,\n unknown: allUnknowns.length,\n conflicted,\n needsRevalidation,\n stale,\n total: allKnowledge.length\n },\n learning,\n resolution,\n investigation,\n jev,\n actions,\n effectiveness: {\n knowledgeReuseRate,\n resolveSuccessRate,\n questionResolutionRate,\n jevRejectionRate\n },\n health\n };\n}\n\nexport async function computeKnowledgeStats(\n storage: Storage,\n knowledgeId: string,\n events: MetricEvent[]\n): Promise<KnowledgeStatsReport | undefined> {\n const knowledge = await storage.getKnowledge(knowledgeId);\n if (!knowledge) {\n return undefined;\n }\n\n const kEvents = events.filter((e) => (e as { knowledgeId?: string }).knowledgeId === knowledgeId);\n\n // Usage & Outcomes\n const outcomes = kEvents.filter((e) => e.type === 'outcome') as Array<\n MetricEvent & { type: 'outcome' }\n >;\n const successfulOutcomes =\n knowledge.metrics.successful_outcomes +\n outcomes.filter((o) => o.result === 'success').length;\n const neutralOutcomes =\n (knowledge.outcomesSummary?.neutral ?? 0) +\n outcomes.filter((o) => o.result === 'neutral').length;\n const misleadingOutcomes =\n (knowledge.outcomesSummary?.misleading ?? 0) +\n outcomes.filter((o) => (o as any).result === 'misleading').length;\n const failedOutcomes =\n knowledge.metrics.failed_outcomes +\n outcomes.filter((o) => o.result === 'failure' || o.result === 'reverted').length;\n\n const used =\n knowledge.metrics.reuse_count +\n kEvents.filter((e) => e.type === 'knowledge_reused').length;\n\n // JEV stats\n const jevEvents = kEvents.filter((e) => e.type === 'jev_result') as Array<\n MetricEvent & { type: 'jev_result' }\n >;\n const jevMatch = jevEvents.filter((j) => j.result === 'MATCH').length;\n const jevPossible = jevEvents.filter((j) => j.result === 'POSSIBLE').length;\n const jevRejected = jevEvents.filter((j) => j.result === 'REJECT').length;\n const jevHardNegativeRejects = jevEvents.filter(\n (j) => String(j.reason || '').toUpperCase().includes('HARD_NEGATIVE')\n ).length + kEvents.filter((e) => e.type === 'jev_hard_negative').length;\n\n // Evidence\n const uniqueSources = new Set(knowledge.evidence.map((ev) => ev.replace(/^(code|file|test|doc):/, '')));\n\n // Lifecycle\n const revisions = knowledge.temporal?.revision || knowledge.history?.length || 1;\n const strengthened =\n knowledge.metrics.support_count +\n kEvents.filter((e) => e.type === 'knowledge_strengthened').length;\n const contradictions =\n knowledge.metrics.contradiction_count +\n kEvents.filter((e) => e.type === 'contradiction_detected').length;\n\n const lastUsedStr = formatRelativeTime(knowledge.metrics.last_used);\n const lastValidatedStr = formatRelativeTime(knowledge.updatedAt);\n\n const { category: healthCategory, reason: healthReason } = classifyKnowledgeHealth(\n knowledge,\n kEvents,\n uniqueSources.size\n );\n\n return {\n id: knowledge.id,\n status: knowledge.status,\n stage: knowledge.stage,\n statement: knowledge.statement,\n usage: {\n used,\n successfulOutcomes,\n neutralOutcomes,\n misleadingOutcomes,\n failedOutcomes\n },\n jev: {\n match: jevMatch,\n possible: jevPossible,\n rejected: jevRejected,\n hardNegativeRejects: jevHardNegativeRejects\n },\n evidence: {\n sources: knowledge.evidence.length,\n independentSources: uniqueSources.size,\n sourcesList: knowledge.evidence\n },\n lifecycle: {\n revisions,\n strengthened,\n contradictions,\n lastUsed: lastUsedStr,\n lastValidated: lastValidatedStr,\n health: healthCategory,\n healthReason\n }\n };\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Resolves a --since argument into a numeric unix timestamp in milliseconds.\n * Supports relative duration (e.g. 24h, 7d, 30d) or Git revision (e.g. HEAD~20, commit SHA).\n */\nexport async function resolveSinceTimestamp(\n since: string,\n projectDir: string = process.cwd()\n): Promise<number> {\n const trimmed = since.trim();\n\n // 1. Duration format: e.g. 24h, 7d, 30d, 2w\n const durationMatch = trimmed.match(/^(\\d+)\\s*([smhdw])$/i);\n if (durationMatch) {\n const value = parseInt(durationMatch[1], 10);\n const unit = durationMatch[2].toLowerCase();\n let ms = 0;\n switch (unit) {\n case 's':\n ms = value * 1000;\n break;\n case 'm':\n ms = value * 60 * 1000;\n break;\n case 'h':\n ms = value * 3600 * 1000;\n break;\n case 'd':\n ms = value * 86400 * 1000;\n break;\n case 'w':\n ms = value * 7 * 86400 * 1000;\n break;\n }\n return Date.now() - ms;\n }\n\n // 2. ISO timestamp format: e.g. 2026-09-01T00:00:00Z\n const parsedDate = Date.parse(trimmed);\n if (!isNaN(parsedDate) && trimmed.includes('-')) {\n return parsedDate;\n }\n\n // 3. Git revision format: e.g. HEAD~20, 81ac23, main\n try {\n const { stdout } = await execFileAsync(\n 'git',\n ['log', '-1', '--format=%ct', trimmed],\n { cwd: projectDir }\n );\n const epochSec = parseInt(stdout.trim(), 10);\n if (!isNaN(epochSec) && epochSec > 0) {\n return epochSec * 1000;\n }\n throw new Error(`Invalid git output: ${stdout}`);\n } catch {\n throw new Error(`Unable to resolve Git revision: ${trimmed}`);\n }\n}\n","import type { StatsReport, KnowledgeStatsReport } from './types.js';\n\nfunction padRow(label: string, value: string | number, width: number = 26): string {\n return ` ${label.padEnd(width)} ${String(value).padStart(5)}`;\n}\n\nexport function formatStatsReport(report: StatsReport): string {\n const lines: string[] = [];\n\n if (report.since) {\n lines.push(`Time range: since ${report.since}\\n`);\n }\n\n // 1. Knowledge\n lines.push('Knowledge');\n lines.push(padRow('Active', report.knowledge.active));\n lines.push(padRow('Candidates', report.knowledge.candidates));\n lines.push(padRow('Unknown', report.knowledge.unknown));\n lines.push(padRow('Conflicted', report.knowledge.conflicted));\n lines.push(padRow('Needs revalidation', report.knowledge.needsRevalidation));\n lines.push('');\n\n // 2. Learning\n lines.push('Learning');\n lines.push(padRow('Observations', report.learning.observations));\n lines.push(padRow('New', report.learning.new));\n lines.push(padRow('Merged', report.learning.merged));\n lines.push(padRow('Strengthened', report.learning.strengthened));\n lines.push(padRow('Specialized', report.learning.specialized));\n lines.push(padRow('Superseded', report.learning.superseded));\n lines.push(padRow('Contradictions', report.learning.contradictions));\n lines.push(padRow('Ignored duplicates', report.learning.ignoredDuplicates));\n lines.push('');\n\n // 3. Resolution\n lines.push('Resolution');\n lines.push(padRow('Resolve calls', report.resolution.resolveCalls));\n lines.push(padRow('Known', report.resolution.known));\n lines.push(padRow('Partially known', report.resolution.partiallyKnown));\n lines.push(padRow('Unknown', report.resolution.unknown));\n lines.push(padRow('Conflicted', report.resolution.conflicted));\n lines.push('');\n\n // 4. Investigation\n lines.push('Investigation');\n lines.push(padRow('Repeated checks avoided', report.investigation.repeatedChecksAvoided));\n lines.push(padRow('Knowledge reused', report.investigation.knowledgeReused));\n lines.push(padRow('Questions suggested', report.investigation.questionsSuggested));\n lines.push(padRow('Questions resolved', report.investigation.questionsResolved));\n lines.push(padRow('Broad searches avoided', report.investigation.broadSearchesAvoided));\n lines.push('');\n\n // 5. JEV\n lines.push('JEV');\n lines.push(padRow('Candidates', report.jev.candidates));\n lines.push(padRow('Match', report.jev.match));\n lines.push(padRow('Possible', report.jev.possible));\n lines.push(padRow('Rejected', report.jev.rejected));\n lines.push(padRow('Hard negative rejects', report.jev.hardNegativeRejects));\n lines.push('');\n\n // 6. Resolution Actions\n const actionKeys = Object.keys(report.actions);\n if (actionKeys.length > 0) {\n const actionLabels: Record<string, string> = {\n USE_KNOWLEDGE: 'Use existing knowledge',\n INSPECT_FILE: 'Inspect single source',\n INSPECT_TEST: 'Inspect test',\n INSPECT_SYMBOL: 'Inspect symbol',\n CHECK_GIT: 'Check Git',\n CHECK_DOCUMENTATION: 'Check documentation',\n SEARCH_REPOSITORY: 'Search repository',\n ASK_USER: 'Ask user',\n STOP: 'Stop unresolved'\n };\n\n lines.push('Resolution Actions');\n for (const key of actionKeys) {\n const label = actionLabels[key] || key;\n lines.push(padRow(label, report.actions[key]));\n }\n lines.push('');\n }\n\n // 7. Effectiveness\n lines.push('Effectiveness');\n lines.push(padRow('Knowledge reuse rate', report.effectiveness.knowledgeReuseRate.formatted));\n lines.push(padRow('Resolve success rate', report.effectiveness.resolveSuccessRate.formatted));\n lines.push(padRow('Question resolution rate', report.effectiveness.questionResolutionRate.formatted));\n lines.push(padRow('JEV rejection rate', report.effectiveness.jevRejectionRate.formatted));\n lines.push('');\n\n // 8. Health\n lines.push('Knowledge Health');\n lines.push(padRow('Healthy', report.health.healthy));\n lines.push(padRow('Needs revalidation', report.health.needsRevalidation));\n lines.push(padRow('Low evidence', report.health.lowEvidence));\n lines.push(padRow('Frequently rejected', report.health.frequentlyRejected));\n lines.push(padRow('Frequently misleading', report.health.frequentlyMisleading));\n lines.push(padRow('Unused', report.health.unused));\n\n return lines.join('\\n');\n}\n\nexport function formatKnowledgeStatsReport(report: KnowledgeStatsReport): string {\n const lines: string[] = [];\n\n lines.push(report.id);\n lines.push(`\"${report.statement}\"\\n`);\n\n lines.push('Status');\n lines.push(` ${report.status.toUpperCase()}${report.stage ? ` (${report.stage})` : ''}\\n`);\n\n lines.push('Usage');\n lines.push(padRow('Used', report.usage.used));\n lines.push(padRow('Successful outcomes', report.usage.successfulOutcomes));\n lines.push(padRow('Neutral', report.usage.neutralOutcomes));\n lines.push(padRow('Misleading', report.usage.misleadingOutcomes));\n lines.push('');\n\n lines.push('JEV');\n lines.push(padRow('Match', report.jev.match));\n lines.push(padRow('Possible', report.jev.possible));\n lines.push(padRow('Rejected', report.jev.rejected));\n lines.push(padRow('Hard negative rejects', report.jev.hardNegativeRejects));\n lines.push('');\n\n lines.push('Evidence');\n lines.push(padRow('Sources', report.evidence.sources));\n lines.push(padRow('Independent sources', report.evidence.independentSources));\n lines.push('');\n\n lines.push('Lifecycle');\n lines.push(padRow('Revisions', report.lifecycle.revisions));\n lines.push(padRow('Strengthened', report.lifecycle.strengthened));\n lines.push(padRow('Contradictions', report.lifecycle.contradictions));\n if (report.lifecycle.lastUsed) {\n lines.push(padRow('Last used', report.lifecycle.lastUsed));\n }\n if (report.lifecycle.lastValidated) {\n lines.push(padRow('Last validated', report.lifecycle.lastValidated));\n }\n lines.push(padRow('Health', `${report.lifecycle.health} (${report.lifecycle.healthReason})`));\n\n return lines.join('\\n');\n}\n","import { Storage } from '../storage/canonical.js';\nimport type { StatsReport, KnowledgeStatsReport } from './types.js';\nimport { readMetricEvents, resetMetricEvents } from './events.js';\nimport { computeStats, computeKnowledgeStats } from './aggregator.js';\nimport { resolveSinceTimestamp } from './filter.js';\n\nexport * from './types.js';\nexport * from './events.js';\nexport * from './aggregator.js';\nexport * from './filter.js';\nexport * from './format.js';\n\nexport interface RunStatsOptions {\n rootDir?: string;\n since?: string;\n knowledgeId?: string;\n reset?: boolean;\n}\n\n/**\n * High-level stats runner for CLI and programmatic API.\n */\nexport async function runStats(\n options: RunStatsOptions = {}\n): Promise<{\n report?: StatsReport;\n knowledgeReport?: KnowledgeStatsReport;\n reset?: boolean;\n}> {\n const rootDir = options.rootDir || process.cwd();\n const storage = new Storage(rootDir);\n\n // If reset requested:\n if (options.reset) {\n await resetMetricEvents(rootDir);\n return { reset: true };\n }\n\n let sinceTimestamp: number | undefined;\n if (options.since) {\n sinceTimestamp = await resolveSinceTimestamp(options.since, rootDir);\n }\n\n const events = await readMetricEvents(rootDir, {\n sinceTimestamp,\n knowledgeId: options.knowledgeId\n });\n\n if (options.knowledgeId) {\n const knowledgeReport = await computeKnowledgeStats(storage, options.knowledgeId, events);\n return { knowledgeReport };\n }\n\n const report = await computeStats(storage, events, {\n since: options.since,\n sinceTimestamp\n });\n\n return { report };\n}\n"],"mappings":"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","names":["fs","path","fs","path"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { S as Storage } from '../canonical-CglQQ0xc.js';
|
|
2
|
+
export { d as desanitizeFileName, f as formatKnowledgeDiff, s as sanitizeFileName } from '../canonical-CglQQ0xc.js';
|
|
3
|
+
import { r as ReconciliationResult, K as Knowledge, B as BilmemConfig, U as UnknownRecord, c as Evidence, o as Observation, d as EvidenceRelation, b as BilmemMetrics } from '../types-Nxq5Gzay.js';
|
|
4
|
+
import '../search/index.js';
|
|
5
|
+
|
|
6
|
+
interface BatchOp {
|
|
7
|
+
type: 'put' | 'delete' | 'append';
|
|
8
|
+
collection: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
data?: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface StorageDriver {
|
|
13
|
+
get<T = unknown>(collection: string, id: string): Promise<T | undefined>;
|
|
14
|
+
put<T = unknown>(collection: string, id: string, data: T): Promise<void>;
|
|
15
|
+
delete(collection: string, id: string): Promise<boolean>;
|
|
16
|
+
scan<T = unknown>(collection: string): Promise<T[]>;
|
|
17
|
+
append<T = unknown>(collection: string, data: T): Promise<string>;
|
|
18
|
+
batch(operations: BatchOp[]): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface PortableDump {
|
|
22
|
+
schemaVersion: number;
|
|
23
|
+
exportedAt: string;
|
|
24
|
+
config: BilmemConfig;
|
|
25
|
+
knowledge: Knowledge[];
|
|
26
|
+
unknowns: UnknownRecord[];
|
|
27
|
+
evidence: Evidence[];
|
|
28
|
+
observations?: Observation[];
|
|
29
|
+
relations: EvidenceRelation[];
|
|
30
|
+
metrics: BilmemMetrics;
|
|
31
|
+
}
|
|
32
|
+
interface ImportReport {
|
|
33
|
+
totalParsed: number;
|
|
34
|
+
results: ReconciliationResult[];
|
|
35
|
+
created: Knowledge[];
|
|
36
|
+
updated: Knowledge[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Exports active or scoped knowledge to human-readable, Git-friendly YAML.
|
|
40
|
+
*/
|
|
41
|
+
declare function exportKnowledgeToYaml(items: Knowledge[], options?: {
|
|
42
|
+
scope?: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/**
|
|
45
|
+
* Smart import operation:
|
|
46
|
+
* Validates, normalizes, retrieves related knowledge, and reconciles
|
|
47
|
+
* with merge / update / contradict / new actions.
|
|
48
|
+
*/
|
|
49
|
+
declare function importKnowledgeFromYaml(yamlContent: string, storage: Storage): Promise<ImportReport>;
|
|
50
|
+
/**
|
|
51
|
+
* Produces a portable, complete snapshot sufficient for deterministic restoration.
|
|
52
|
+
*/
|
|
53
|
+
declare function dumpToYaml(storage: Storage): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Deterministic restoration from a dump file.
|
|
56
|
+
* Does NOT reinterpret or relearn the backup; restores exact canonical state.
|
|
57
|
+
*/
|
|
58
|
+
declare function restoreFromYaml(yamlContent: string, storage: Storage): Promise<{
|
|
59
|
+
restoredKnowledgeCount: number;
|
|
60
|
+
restoredUnknownsCount: number;
|
|
61
|
+
}>;
|
|
62
|
+
|
|
63
|
+
interface CompactionReport {
|
|
64
|
+
dryRun: boolean;
|
|
65
|
+
mergedDuplicatesCount: number;
|
|
66
|
+
markedStaleCount: number;
|
|
67
|
+
markedContradictedCount: number;
|
|
68
|
+
prunedObservationsCount: number;
|
|
69
|
+
details: string[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Conservative compaction mechanism:
|
|
73
|
+
* - merges duplicates & consolidates highly similar knowledge only after polarity check
|
|
74
|
+
* - marks stale knowledge based on age / zero reuse
|
|
75
|
+
* - detects heavily contradicted knowledge
|
|
76
|
+
* - cleans orphaned, unreferenced low-value observations while strictly preserving provenance.
|
|
77
|
+
*/
|
|
78
|
+
declare function compact(storage: Storage, options?: {
|
|
79
|
+
dryRun?: boolean;
|
|
80
|
+
}): Promise<CompactionReport>;
|
|
81
|
+
|
|
82
|
+
export { type BatchOp, Storage as CanonicalStorage, type CompactionReport, type ImportReport, type PortableDump, Storage, type StorageDriver, compact, dumpToYaml, exportKnowledgeToYaml, importKnowledgeFromYaml, restoreFromYaml };
|