Reference implementation for the Phoenix Architecture. Work in progress. aicoding.leaflet.pub/
ai coding crazy
at main 65 lines 1.8 kB view raw
1/** 2 * Negative Knowledge Store — persists what was tried and failed. 3 * Preserved across compaction. The system's immune memory. 4 */ 5 6import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'node:fs'; 7import { join } from 'node:path'; 8import type { NegativeKnowledge } from '../models/negative-knowledge.js'; 9 10interface NKIndex { 11 records: NegativeKnowledge[]; 12} 13 14export class NegativeKnowledgeStore { 15 private indexPath: string; 16 17 constructor(phoenixRoot: string) { 18 const dir = join(phoenixRoot, 'provenance'); 19 mkdirSync(dir, { recursive: true }); 20 this.indexPath = join(dir, 'negative-knowledge.json'); 21 } 22 23 private load(): NKIndex { 24 if (!existsSync(this.indexPath)) return { records: [] }; 25 return JSON.parse(readFileSync(this.indexPath, 'utf8')); 26 } 27 28 private save(index: NKIndex): void { 29 writeFileSync(this.indexPath, JSON.stringify(index, null, 2), 'utf8'); 30 } 31 32 add(record: NegativeKnowledge): void { 33 const index = this.load(); 34 const existing = index.records.findIndex(r => r.nk_id === record.nk_id); 35 if (existing >= 0) { 36 index.records[existing] = record; 37 } else { 38 index.records.push(record); 39 } 40 this.save(index); 41 } 42 43 getBySubject(subjectId: string): NegativeKnowledge[] { 44 return this.load().records.filter(r => r.subject_id === subjectId && r.active); 45 } 46 47 getAll(): NegativeKnowledge[] { 48 return this.load().records; 49 } 50 51 getActive(): NegativeKnowledge[] { 52 return this.load().records.filter(r => r.active); 53 } 54 55 markStale(nkId: string): boolean { 56 const index = this.load(); 57 const record = index.records.find(r => r.nk_id === nkId); 58 if (record) { 59 record.active = false; 60 this.save(index); 61 return true; 62 } 63 return false; 64 } 65}