@remnic/core 9.3.742 → 9.3.744
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/access-boundary.d.ts +6 -6
- package/dist/access-boundary.js +10 -10
- package/dist/access-cli.js +29 -29
- package/dist/access-http.d.ts +6 -6
- package/dist/access-http.js +15 -15
- package/dist/access-mcp.d.ts +6 -6
- package/dist/access-mcp.js +14 -14
- package/dist/access-operations-batch.js +12 -12
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +13 -13
- package/dist/{access-service-K8n12dXu.d.ts → access-service-OT3Gk79W.d.ts} +3 -3
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +9 -9
- package/dist/access-surface-catalog.d.ts +6 -6
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +2 -2
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +10 -5
- package/dist/capabilities.js +1 -1
- package/dist/{catalog-_Bap6vfD.d.ts → catalog-CX0CjOaf.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-X5PMDVY4.js → chunk-3EA5LIFJ.js} +4 -4
- package/dist/{chunk-YNHRWFAP.js → chunk-4DLFJJOQ.js} +2 -2
- package/dist/{chunk-WIMKOTNY.js → chunk-5QANTTY2.js} +2 -2
- package/dist/{chunk-AM7YKD7V.js → chunk-5UNSGRCR.js} +5 -5
- package/dist/{chunk-Y6PNYJVO.js → chunk-A2KKLCOS.js} +2 -2
- package/dist/{chunk-O4IWVWSW.js → chunk-AVBT5WEW.js} +3 -3
- package/dist/{chunk-QUNH5UZH.js → chunk-BYLC4DKI.js} +2 -2
- package/dist/{chunk-UOVDO6TC.js → chunk-CHELXDTO.js} +3 -3
- package/dist/{chunk-TQQN64J2.js → chunk-DBSMLRTO.js} +2 -2
- package/dist/{chunk-EZZUNKMJ.js → chunk-DYK27X7V.js} +3 -3
- package/dist/{chunk-K2N6WIZM.js → chunk-E7RGJQWP.js} +2 -2
- package/dist/{chunk-M4WI23X3.js → chunk-EEKDRAWX.js} +2 -2
- package/dist/{chunk-GFJ5ABKS.js → chunk-G5FP7VSQ.js} +11 -11
- package/dist/{chunk-BE6NEQLF.js → chunk-HAZVVOYT.js} +3 -3
- package/dist/{chunk-OT5K26NG.js → chunk-HM6UJPPO.js} +2 -2
- package/dist/{chunk-PI4JHLDD.js → chunk-IP5SANO2.js} +2 -2
- package/dist/{chunk-WHEF76BQ.js → chunk-JRZV3767.js} +2 -2
- package/dist/{chunk-OS5RKJOH.js → chunk-JZ7P26GF.js} +2 -2
- package/dist/{chunk-Y62QPRKV.js → chunk-K5LLP4CY.js} +2 -2
- package/dist/{chunk-C3Z5YJSM.js → chunk-LOPZ2DWR.js} +2 -2
- package/dist/{chunk-BJPL5WAL.js → chunk-MXDG6SRH.js} +3 -3
- package/dist/{chunk-UYYSOMS2.js → chunk-NBP3YHHS.js} +4 -4
- package/dist/{chunk-USHVHI6J.js → chunk-NNL4LJAD.js} +3 -3
- package/dist/{chunk-GPX5E36D.js → chunk-OSMBC3JU.js} +2 -2
- package/dist/{chunk-OUSOMUFV.js → chunk-PE6XR4GG.js} +2 -2
- package/dist/{chunk-CMPXLMC3.js → chunk-PI23H7FV.js} +3 -3
- package/dist/{chunk-WGDE2TJP.js → chunk-QOGXUNWL.js} +4 -4
- package/dist/{chunk-ELL5VYXC.js → chunk-RNWWAS5V.js} +3 -3
- package/dist/{chunk-7HUGLMSW.js → chunk-SODQQCAZ.js} +1013 -821
- package/dist/chunk-SODQQCAZ.js.map +1 -0
- package/dist/{chunk-JMMSVRF4.js → chunk-TQPSOTC7.js} +7 -7
- package/dist/{chunk-AX4TRSRE.js → chunk-U5WVRMCA.js} +2 -2
- package/dist/{chunk-7ADHJ6SU.js → chunk-VE54E6RP.js} +4 -4
- package/dist/{chunk-G7Q4D2G3.js → chunk-VSF7AAGE.js} +1 -3
- package/dist/chunk-VSF7AAGE.js.map +1 -0
- package/dist/{chunk-OVYBENIJ.js → chunk-W3M34XT4.js} +3 -3
- package/dist/{chunk-NHJYUIII.js → chunk-WPLRJ4XM.js} +7 -7
- package/dist/{chunk-UEIF7RWQ.js → chunk-XEADGIAA.js} +6 -6
- package/dist/{cli-BEOLy1xo.d.ts → cli-BQiTZ7Zs.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +21 -21
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +2 -2
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-UERKJESC.js → contradiction-scan-3FJYWS3G.js} +3 -3
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +2 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +5 -4
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +4 -4
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-GQ3UQNIL.js → first-start-migration-4I3VDSYS.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +36 -36
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +6 -6
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +2 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -6
- package/dist/{orchestrator-Dr-1v5EL.d.ts → orchestrator-BPQGHpJz.d.ts} +263 -31
- package/dist/orchestrator.d.ts +5 -4
- package/dist/orchestrator.js +24 -24
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-DsIEiCka.d.ts → semantic-consolidation-ByzGwC9c.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-CSKL7BDG.js → tier-stats-5XF4UBRQ.js} +2 -2
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CglNn2V-.d.ts → types-5Jik3r4G.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/package.json +2 -2
- package/src/capabilities.test.ts +0 -2
- package/src/capabilities.ts +7 -6
- package/src/orchestration/contradiction-linking-coordinator.ts +336 -0
- package/src/orchestration/graph-recall-coordinator.ts +471 -0
- package/src/orchestration/recall-section-coordinator.ts +349 -0
- package/src/orchestrator.ts +97 -741
- package/dist/chunk-7HUGLMSW.js.map +0 -1
- package/dist/chunk-G7Q4D2G3.js.map +0 -1
- /package/dist/{chunk-X5PMDVY4.js.map → chunk-3EA5LIFJ.js.map} +0 -0
- /package/dist/{chunk-YNHRWFAP.js.map → chunk-4DLFJJOQ.js.map} +0 -0
- /package/dist/{chunk-WIMKOTNY.js.map → chunk-5QANTTY2.js.map} +0 -0
- /package/dist/{chunk-AM7YKD7V.js.map → chunk-5UNSGRCR.js.map} +0 -0
- /package/dist/{chunk-Y6PNYJVO.js.map → chunk-A2KKLCOS.js.map} +0 -0
- /package/dist/{chunk-O4IWVWSW.js.map → chunk-AVBT5WEW.js.map} +0 -0
- /package/dist/{chunk-QUNH5UZH.js.map → chunk-BYLC4DKI.js.map} +0 -0
- /package/dist/{chunk-UOVDO6TC.js.map → chunk-CHELXDTO.js.map} +0 -0
- /package/dist/{chunk-TQQN64J2.js.map → chunk-DBSMLRTO.js.map} +0 -0
- /package/dist/{chunk-EZZUNKMJ.js.map → chunk-DYK27X7V.js.map} +0 -0
- /package/dist/{chunk-K2N6WIZM.js.map → chunk-E7RGJQWP.js.map} +0 -0
- /package/dist/{chunk-M4WI23X3.js.map → chunk-EEKDRAWX.js.map} +0 -0
- /package/dist/{chunk-GFJ5ABKS.js.map → chunk-G5FP7VSQ.js.map} +0 -0
- /package/dist/{chunk-BE6NEQLF.js.map → chunk-HAZVVOYT.js.map} +0 -0
- /package/dist/{chunk-OT5K26NG.js.map → chunk-HM6UJPPO.js.map} +0 -0
- /package/dist/{chunk-PI4JHLDD.js.map → chunk-IP5SANO2.js.map} +0 -0
- /package/dist/{chunk-WHEF76BQ.js.map → chunk-JRZV3767.js.map} +0 -0
- /package/dist/{chunk-OS5RKJOH.js.map → chunk-JZ7P26GF.js.map} +0 -0
- /package/dist/{chunk-Y62QPRKV.js.map → chunk-K5LLP4CY.js.map} +0 -0
- /package/dist/{chunk-C3Z5YJSM.js.map → chunk-LOPZ2DWR.js.map} +0 -0
- /package/dist/{chunk-BJPL5WAL.js.map → chunk-MXDG6SRH.js.map} +0 -0
- /package/dist/{chunk-UYYSOMS2.js.map → chunk-NBP3YHHS.js.map} +0 -0
- /package/dist/{chunk-USHVHI6J.js.map → chunk-NNL4LJAD.js.map} +0 -0
- /package/dist/{chunk-GPX5E36D.js.map → chunk-OSMBC3JU.js.map} +0 -0
- /package/dist/{chunk-OUSOMUFV.js.map → chunk-PE6XR4GG.js.map} +0 -0
- /package/dist/{chunk-CMPXLMC3.js.map → chunk-PI23H7FV.js.map} +0 -0
- /package/dist/{chunk-WGDE2TJP.js.map → chunk-QOGXUNWL.js.map} +0 -0
- /package/dist/{chunk-ELL5VYXC.js.map → chunk-RNWWAS5V.js.map} +0 -0
- /package/dist/{chunk-JMMSVRF4.js.map → chunk-TQPSOTC7.js.map} +0 -0
- /package/dist/{chunk-AX4TRSRE.js.map → chunk-U5WVRMCA.js.map} +0 -0
- /package/dist/{chunk-7ADHJ6SU.js.map → chunk-VE54E6RP.js.map} +0 -0
- /package/dist/{chunk-OVYBENIJ.js.map → chunk-W3M34XT4.js.map} +0 -0
- /package/dist/{chunk-NHJYUIII.js.map → chunk-WPLRJ4XM.js.map} +0 -0
- /package/dist/{chunk-UEIF7RWQ.js.map → chunk-XEADGIAA.js.map} +0 -0
- /package/dist/{contradiction-scan-UERKJESC.js.map → contradiction-scan-3FJYWS3G.js.map} +0 -0
- /package/dist/{first-start-migration-GQ3UQNIL.js.map → first-start-migration-4I3VDSYS.js.map} +0 -0
- /package/dist/{tier-stats-CSKL7BDG.js.map → tier-stats-5XF4UBRQ.js.map} +0 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contradiction-linking coordinator — extracted from the orchestrator (issue #1526).
|
|
3
|
+
*
|
|
4
|
+
* Owns the write-path semantic-analysis subsystem: contradiction detection
|
|
5
|
+
* (QMD similarity search + LLM verification), deferred contradiction
|
|
6
|
+
* auto-resolve (#1645 — retires superseded memories only after the new write's
|
|
7
|
+
* tombstone status is known), and memory link suggestion. Behavior-preserving
|
|
8
|
+
* move from orchestrator.ts — no logic changes; the orchestrator constructs one
|
|
9
|
+
* instance and keeps thin delegating methods so existing call sites (writeMemory
|
|
10
|
+
* fact-write branches) continue to work.
|
|
11
|
+
*
|
|
12
|
+
* Config, storage, search, namespace resolution, and the extraction engine are
|
|
13
|
+
* accessed through getter callbacks (not captured at construction) so that
|
|
14
|
+
* post-construction reassignment of the orchestrator's live fields is honored.
|
|
15
|
+
* This mirrors the RecallRerankCoordinator / ConversationIndexCoordinator
|
|
16
|
+
* accessor pattern.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type {
|
|
20
|
+
MemoryLink,
|
|
21
|
+
PluginConfig,
|
|
22
|
+
QmdSearchResult,
|
|
23
|
+
} from "../types.js";
|
|
24
|
+
// StorageManager type comes from the package barrel (type-only) so this
|
|
25
|
+
// module does not add a direct storage.ts import (ratchet #1533).
|
|
26
|
+
import type { StorageManager } from "../index.js";
|
|
27
|
+
import type { ExtractionEngine } from "../extraction.js";
|
|
28
|
+
import { log } from "../logger.js";
|
|
29
|
+
import { resolveIndexingCapabilities } from "../capabilities.js";
|
|
30
|
+
import { deindexMemory } from "../temporal-index.js";
|
|
31
|
+
|
|
32
|
+
/** Result type of {@link ContradictionLinkingCoordinator.checkForContradiction}. */
|
|
33
|
+
export interface ContradictionResult {
|
|
34
|
+
supersededId: string;
|
|
35
|
+
confidence: number;
|
|
36
|
+
reason: string;
|
|
37
|
+
supersededPath: string;
|
|
38
|
+
supersededCreated: string;
|
|
39
|
+
supersededTags: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Subset of {@link ContradictionResult} used by
|
|
44
|
+
* {@link ContradictionLinkingCoordinator.applyDeferredContradictionResolve}.
|
|
45
|
+
* The deferred resolve runs AFTER writeMemory and only needs the supersede
|
|
46
|
+
* target fields (not confidence, which the caller already consumed).
|
|
47
|
+
*/
|
|
48
|
+
export interface ContradictionResolveTarget {
|
|
49
|
+
supersededId: string;
|
|
50
|
+
reason: string;
|
|
51
|
+
supersededPath: string;
|
|
52
|
+
supersededCreated: string;
|
|
53
|
+
supersededTags: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Coordinator for the contradiction-detection + memory-linking subsystem.
|
|
58
|
+
*
|
|
59
|
+
* The three methods mirror the orchestrator's former private methods
|
|
60
|
+
* `checkForContradiction`, `applyDeferredContradictionResolve`, and
|
|
61
|
+
* `suggestLinksForMemory` byte-for-byte in logic.
|
|
62
|
+
*/
|
|
63
|
+
export class ContradictionLinkingCoordinator {
|
|
64
|
+
private readonly getConfig: () => PluginConfig;
|
|
65
|
+
private readonly isSearchAvailable: () => boolean;
|
|
66
|
+
private readonly searchAcrossNamespaces: (options: {
|
|
67
|
+
query: string;
|
|
68
|
+
namespaces?: string[];
|
|
69
|
+
maxResults?: number;
|
|
70
|
+
mode?: "search" | "hybrid" | "bm25" | "vector";
|
|
71
|
+
}) => Promise<QmdSearchResult[]>;
|
|
72
|
+
private readonly extractMemoryIdsFromResults: (
|
|
73
|
+
results: QmdSearchResult[],
|
|
74
|
+
) => string[];
|
|
75
|
+
private readonly namespaceFromPath: (p: string) => string;
|
|
76
|
+
private readonly storageForNamespace: (
|
|
77
|
+
namespace: string,
|
|
78
|
+
) => Promise<StorageManager>;
|
|
79
|
+
private readonly getExtraction: () => ExtractionEngine;
|
|
80
|
+
|
|
81
|
+
constructor(options: {
|
|
82
|
+
getConfig: () => PluginConfig;
|
|
83
|
+
isSearchAvailable: () => boolean;
|
|
84
|
+
searchAcrossNamespaces: (options: {
|
|
85
|
+
query: string;
|
|
86
|
+
namespaces?: string[];
|
|
87
|
+
maxResults?: number;
|
|
88
|
+
mode?: "search" | "hybrid" | "bm25" | "vector";
|
|
89
|
+
}) => Promise<QmdSearchResult[]>;
|
|
90
|
+
extractMemoryIdsFromResults: (results: QmdSearchResult[]) => string[];
|
|
91
|
+
namespaceFromPath: (p: string) => string;
|
|
92
|
+
storageForNamespace: (namespace: string) => Promise<StorageManager>;
|
|
93
|
+
getExtraction: () => ExtractionEngine;
|
|
94
|
+
}) {
|
|
95
|
+
this.getConfig = options.getConfig;
|
|
96
|
+
this.isSearchAvailable = options.isSearchAvailable;
|
|
97
|
+
this.searchAcrossNamespaces = options.searchAcrossNamespaces;
|
|
98
|
+
this.extractMemoryIdsFromResults = options.extractMemoryIdsFromResults;
|
|
99
|
+
this.namespaceFromPath = options.namespaceFromPath;
|
|
100
|
+
this.storageForNamespace = options.storageForNamespace;
|
|
101
|
+
this.getExtraction = options.getExtraction;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Check if a new memory contradicts an existing one.
|
|
106
|
+
* Uses QMD to find similar memories, then LLM to verify contradiction.
|
|
107
|
+
*/
|
|
108
|
+
async checkForContradiction(
|
|
109
|
+
content: string,
|
|
110
|
+
category: string,
|
|
111
|
+
namespaceScope: string,
|
|
112
|
+
): Promise<ContradictionResult | null> {
|
|
113
|
+
if (!this.isSearchAvailable()) return null;
|
|
114
|
+
|
|
115
|
+
const config = this.getConfig();
|
|
116
|
+
|
|
117
|
+
// Search for similar memories
|
|
118
|
+
const results = await this.searchAcrossNamespaces({
|
|
119
|
+
query: content,
|
|
120
|
+
namespaces: [namespaceScope],
|
|
121
|
+
maxResults: 5,
|
|
122
|
+
mode: "search",
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
for (const result of results) {
|
|
126
|
+
// Check similarity threshold
|
|
127
|
+
if (result.score < config.contradictionSimilarityThreshold) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Get the existing memory
|
|
132
|
+
const memoryId = this.extractMemoryIdsFromResults([result])[0];
|
|
133
|
+
if (!memoryId) continue;
|
|
134
|
+
|
|
135
|
+
const resultNamespace = this.namespaceFromPath(result.path);
|
|
136
|
+
if (resultNamespace !== namespaceScope) continue;
|
|
137
|
+
const resultStorage = await this.storageForNamespace(resultNamespace);
|
|
138
|
+
const existingMemory = await resultStorage.getMemoryById(memoryId);
|
|
139
|
+
if (!existingMemory) continue;
|
|
140
|
+
|
|
141
|
+
// Skip memories already resolved or explicitly forgotten. Other
|
|
142
|
+
// non-active statuses remain valid contradiction candidates.
|
|
143
|
+
if (
|
|
144
|
+
existingMemory.frontmatter.status === "superseded" ||
|
|
145
|
+
existingMemory.frontmatter.status === "forgotten"
|
|
146
|
+
) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Verify contradiction with LLM
|
|
151
|
+
const extraction = this.getExtraction();
|
|
152
|
+
const verification = await extraction.verifyContradiction(
|
|
153
|
+
{ content, category },
|
|
154
|
+
{
|
|
155
|
+
id: existingMemory.frontmatter.id,
|
|
156
|
+
content: existingMemory.content,
|
|
157
|
+
category: existingMemory.frontmatter.category,
|
|
158
|
+
created: existingMemory.frontmatter.created,
|
|
159
|
+
},
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
if (!verification) continue;
|
|
163
|
+
|
|
164
|
+
// Check if it's a real contradiction with high confidence
|
|
165
|
+
if (
|
|
166
|
+
verification.isContradiction &&
|
|
167
|
+
verification.confidence >= config.contradictionMinConfidence
|
|
168
|
+
) {
|
|
169
|
+
// When the LLM says the existing memory is newer (whichIsNewer ===
|
|
170
|
+
// "first") the incoming fact is the stale one in both resolve modes —
|
|
171
|
+
// log and continue so the caller never marks contradictionDetected and
|
|
172
|
+
// the semantic-skip gate can discard the outdated write normally.
|
|
173
|
+
if (verification.whichIsNewer === "first") {
|
|
174
|
+
log.info(
|
|
175
|
+
`detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory — existing is newer, incoming fact is stale`,
|
|
176
|
+
);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// The new fact is newer than the existing one. When auto-resolve is
|
|
181
|
+
// enabled, the caller retires the old memory AFTER the new write lands
|
|
182
|
+
// and its tombstone status is known (#1645: defer auto-resolve until
|
|
183
|
+
// tombstone status is known — a tombstone-blocked new write must not
|
|
184
|
+
// retire the only active copy, leaving neither memory active). When
|
|
185
|
+
// disabled, the old memory stays active for manual review. The
|
|
186
|
+
// contradiction info is returned in both cases so the caller can apply
|
|
187
|
+
// the deferred retire post-write.
|
|
188
|
+
|
|
189
|
+
// Return the contradiction info regardless of auto-resolve setting.
|
|
190
|
+
// The caller uses this to set `contradictionDetected=true` which
|
|
191
|
+
// prevents the semantic-skip guard from silently dropping a
|
|
192
|
+
// legitimately contradictory update (the regression this fixes).
|
|
193
|
+
log.info(
|
|
194
|
+
`detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory${config.contradictionAutoResolve ? " (auto-resolved)" : " (queued for manual review)"}`,
|
|
195
|
+
);
|
|
196
|
+
return {
|
|
197
|
+
supersededId: existingMemory.frontmatter.id,
|
|
198
|
+
confidence: verification.confidence,
|
|
199
|
+
reason: verification.reasoning,
|
|
200
|
+
supersededPath: existingMemory.path,
|
|
201
|
+
supersededCreated: existingMemory.frontmatter.created,
|
|
202
|
+
supersededTags: existingMemory.frontmatter.tags ?? [],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* #1645: Complete the deferred contradiction auto-resolve after writeMemory
|
|
212
|
+
* returns and the new write's tombstone status is known. Retires the old
|
|
213
|
+
* memory + deindexes it ONLY when the new write is genuinely active (not
|
|
214
|
+
* tombstone-blocked / pending_review). A blocked write must not retire the
|
|
215
|
+
* only active copy — deferring here closes the "contradictionAutoResolve
|
|
216
|
+
* supersedes before tombstone status is known" defect class.
|
|
217
|
+
*/
|
|
218
|
+
async applyDeferredContradictionResolve(
|
|
219
|
+
contradiction: ContradictionResolveTarget | null | undefined,
|
|
220
|
+
storage: StorageManager,
|
|
221
|
+
newMemoryId: string,
|
|
222
|
+
postWriteGuard: boolean,
|
|
223
|
+
): Promise<void> {
|
|
224
|
+
const config = this.getConfig();
|
|
225
|
+
// #1645 yG2: clear the pre-write `supersedes` link from a blocked row so
|
|
226
|
+
// it doesn't claim to supersede a still-active memory (best-effort).
|
|
227
|
+
if (postWriteGuard && contradiction && config.contradictionAutoResolve) {
|
|
228
|
+
try {
|
|
229
|
+
const blockedRow = await storage.getMemoryById(newMemoryId);
|
|
230
|
+
if (blockedRow?.frontmatter?.supersedes) {
|
|
231
|
+
await storage.writeMemoryFrontmatter(blockedRow, { supersedes: undefined });
|
|
232
|
+
}
|
|
233
|
+
} catch (err) {
|
|
234
|
+
log.warn(
|
|
235
|
+
`contradiction auto-resolve supersedes clear failed for blocked ${newMemoryId}: ${err}`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (
|
|
240
|
+
!contradiction ||
|
|
241
|
+
!config.contradictionAutoResolve ||
|
|
242
|
+
postWriteGuard
|
|
243
|
+
) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await storage.supersedeMemory(
|
|
248
|
+
contradiction.supersededId,
|
|
249
|
+
newMemoryId,
|
|
250
|
+
contradiction.reason,
|
|
251
|
+
);
|
|
252
|
+
if (
|
|
253
|
+
resolveIndexingCapabilities(config).queryAwareIndexing &&
|
|
254
|
+
contradiction.supersededPath
|
|
255
|
+
) {
|
|
256
|
+
deindexMemory(
|
|
257
|
+
config.memoryDir,
|
|
258
|
+
contradiction.supersededPath,
|
|
259
|
+
contradiction.supersededCreated,
|
|
260
|
+
contradiction.supersededTags,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
} catch (err) {
|
|
264
|
+
log.warn(
|
|
265
|
+
`contradiction auto-resolve supersede failed for ${contradiction.supersededId}: ${err}`,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ---------------------------------------------------------------------------
|
|
271
|
+
// Memory Linking (Phase 3A)
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Suggest links for a new memory based on similar existing memories.
|
|
276
|
+
*/
|
|
277
|
+
async suggestLinksForMemory(
|
|
278
|
+
content: string,
|
|
279
|
+
category: string,
|
|
280
|
+
namespaceScope: string,
|
|
281
|
+
): Promise<MemoryLink[]> {
|
|
282
|
+
if (!this.isSearchAvailable()) return [];
|
|
283
|
+
|
|
284
|
+
// Search for related memories
|
|
285
|
+
const results = await this.searchAcrossNamespaces({
|
|
286
|
+
query: content,
|
|
287
|
+
namespaces: [namespaceScope],
|
|
288
|
+
maxResults: 5,
|
|
289
|
+
mode: "search",
|
|
290
|
+
});
|
|
291
|
+
if (results.length === 0) return [];
|
|
292
|
+
|
|
293
|
+
// Get full memory details for candidates
|
|
294
|
+
const candidates: Array<{ id: string; content: string; category: string }> =
|
|
295
|
+
[];
|
|
296
|
+
for (const result of results) {
|
|
297
|
+
const memoryId = this.extractMemoryIdsFromResults([result])[0];
|
|
298
|
+
if (!memoryId) continue;
|
|
299
|
+
|
|
300
|
+
const resultNamespace = this.namespaceFromPath(result.path);
|
|
301
|
+
if (resultNamespace !== namespaceScope) continue;
|
|
302
|
+
const resultStorage = await this.storageForNamespace(resultNamespace);
|
|
303
|
+
const memory = await resultStorage.getMemoryById(memoryId);
|
|
304
|
+
if (
|
|
305
|
+
memory &&
|
|
306
|
+
memory.frontmatter.status !== "superseded" &&
|
|
307
|
+
memory.frontmatter.status !== "forgotten"
|
|
308
|
+
) {
|
|
309
|
+
candidates.push({
|
|
310
|
+
id: memory.frontmatter.id,
|
|
311
|
+
content: memory.content,
|
|
312
|
+
category: memory.frontmatter.category,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (candidates.length === 0) return [];
|
|
318
|
+
|
|
319
|
+
// Ask LLM for link suggestions
|
|
320
|
+
const extraction = this.getExtraction();
|
|
321
|
+
const suggestions = await extraction.suggestLinks(
|
|
322
|
+
{ content, category },
|
|
323
|
+
candidates,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
if (!suggestions || suggestions.links.length === 0) return [];
|
|
327
|
+
|
|
328
|
+
// Convert to MemoryLink format
|
|
329
|
+
return suggestions.links.map((link) => ({
|
|
330
|
+
targetId: link.targetId,
|
|
331
|
+
linkType: link.linkType,
|
|
332
|
+
strength: link.strength,
|
|
333
|
+
reason: link.reason || undefined,
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
}
|