MCPcopy Create free account
hub / github.com/diillson/chatcli / AddFactWithMeta

Method AddFactWithMeta

cli/workspace/memory/facts.go:128–194  ·  view source on GitHub ↗

AddFactWithMeta is AddFactWithSource with explicit confidence and provenance. It deduplicates by content hash (reinforcing on an exact repeat) and, before inserting, reconciles against same-category facts: a near-duplicate rephrasing reinforces the existing fact, and a same-subject update of equal-o

(content, category string, tags []string, sourceProject string, confidence float64, provenance string)

Source from the content-addressed store, hash-verified

126// reinforces the existing fact, and a same-subject update of equal-or-higher
127// confidence supersedes the stale one instead of piling up a contradiction.
128func (fi *FactIndex) AddFactWithMeta(content, category string, tags []string, sourceProject string, confidence float64, provenance string) bool {
129 content = strings.TrimSpace(content)
130 if content == "" {
131 return false
132 }
133 if confidence <= 0 {
134 confidence = defaultConfidence
135 }
136
137 id := fi.hashContent(content)
138
139 fi.mu.Lock()
140 defer fi.mu.Unlock()
141
142 // Exact duplicate (same content hash) — reinforce.
143 if existing, ok := fi.facts[id]; ok {
144 fi.reinforceLocked(existing, sourceProject, confidence, provenance)
145 fi.persistLocked()
146 return false
147 }
148
149 // Reconcile against near-duplicates / stale same-subject facts.
150 switch outcome, target := fi.reconcileLocked(content, category, confidence); outcome {
151 case reconcileReinforce:
152 fi.reinforceLocked(target, sourceProject, confidence, provenance)
153 fi.persistLocked()
154 return false
155 case reconcileSupersede:
156 fi.logger.Debug("memory: superseding stale fact",
157 zap.String("old_id", target.ID),
158 zap.String("old", target.Content),
159 zap.String("new", content),
160 )
161 delete(fi.facts, target.ID)
162 // Tombstone the superseded fact or the shared-file merge re-adopts it
163 // from disk and the update never sticks.
164 fi.recordTombstonesLocked(target.ID)
165 if provenance == "" {
166 provenance = ProvenanceExtraction
167 }
168 provenance += " (supersedes " + target.ID + ")"
169 }
170
171 fact := &Fact{
172 ID: id,
173 Content: content,
174 Category: category,
175 Tags: tags,
176 CreatedAt: time.Now(),
177 LastAccessed: time.Now(),
178 AccessCount: 1,
179 Score: 1.0,
180 SourceProject: sourceProject,
181 Confidence: confidence,
182 Provenance: provenance,
183 }
184
185 fi.facts[id] = fact

Calls 9

hashContentMethod · 0.95
reinforceLockedMethod · 0.95
persistLockedMethod · 0.95
reconcileLockedMethod · 0.95
pruneLowestLockedMethod · 0.95
LockMethod · 0.80
UnlockMethod · 0.80
StringMethod · 0.45