@remnic/core 9.51.1 → 9.52.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/dist/access-admin-ops-surface.d.ts +6 -5
- package/dist/access-admin-ops-surface.js +16 -16
- package/dist/access-authorization-probe.d.ts +6 -5
- package/dist/access-authorization-probe.js +17 -17
- package/dist/access-boundary.d.ts +6 -5
- package/dist/access-boundary.js +16 -16
- package/dist/access-cli.js +39 -39
- package/dist/access-extraction-force-flush.d.ts +6 -5
- package/dist/access-extraction-force-flush.js +16 -16
- package/dist/access-http-lcm-compaction.d.ts +6 -5
- package/dist/access-http-lifecycle-flush.d.ts +6 -5
- package/dist/access-http-offline-stream.d.ts +6 -5
- package/dist/access-http-query.js +16 -16
- package/dist/access-http.d.ts +6 -5
- package/dist/access-http.js +22 -22
- package/dist/access-identity-continuity-surface.d.ts +5 -4
- package/dist/access-identity-continuity-surface.js +16 -16
- package/dist/access-lcm-surface.d.ts +6 -5
- package/dist/access-lcm-surface.js +16 -16
- package/dist/access-mcp.d.ts +6 -5
- package/dist/access-mcp.js +20 -20
- package/dist/access-namespace-preflight.js +16 -16
- package/dist/access-observe-write-surface.d.ts +6 -5
- package/dist/access-observe-write-surface.js +16 -16
- package/dist/access-offline-manifest.d.ts +5 -4
- package/dist/access-operations-batch.js +17 -17
- package/dist/access-operations.d.ts +9 -8
- package/dist/access-operations.js +19 -19
- package/dist/access-recall-concurrency.d.ts +6 -5
- package/dist/access-recall-concurrency.js +16 -16
- package/dist/access-recall-response.d.ts +6 -5
- package/dist/access-recall-response.js +16 -16
- package/dist/access-recall-surface.d.ts +6 -5
- package/dist/access-recall-surface.js +16 -16
- package/dist/access-schema.d.ts +88 -88
- package/dist/{access-service-BY0KJ44c.d.ts → access-service-Cbk3bNbD.d.ts} +3 -3
- package/dist/access-service-helpers.d.ts +6 -5
- package/dist/access-service.d.ts +6 -5
- package/dist/access-service.js +16 -16
- package/dist/access-surface-catalog.d.ts +6 -5
- package/dist/access-wearables-meetings-surface.d.ts +2 -2
- package/dist/bootstrap.d.ts +5 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +7 -7
- package/dist/buffer.d.ts +1 -1
- package/dist/{capsule-merge-XMFBXVDP.js → capsule-merge-HCJJMLPS.js} +4 -4
- package/dist/causal-consolidation.js +8 -8
- package/dist/{chunk-PWN32TAG.js → chunk-2ASAS3CQ.js} +2 -2
- package/dist/{chunk-WQM326GS.js → chunk-2LY6GIIE.js} +2 -2
- package/dist/{chunk-JL43BVDE.js → chunk-2OIQDTDC.js} +2 -2
- package/dist/{chunk-33SV3E43.js → chunk-3OY7KXHM.js} +3 -3
- package/dist/{chunk-AIUBBHSF.js → chunk-5UZ6UCOZ.js} +3 -3
- package/dist/chunk-5WITETWU.js +591 -0
- package/dist/chunk-5WITETWU.js.map +1 -0
- package/dist/{chunk-UT5BV5OG.js → chunk-7HXZJAID.js} +2 -2
- package/dist/{chunk-M7BXDKPR.js → chunk-7M6NYQWB.js} +3 -3
- package/dist/{chunk-TPTECFWR.js → chunk-B6LZ4IBH.js} +3 -3
- package/dist/{chunk-J5LLX6IL.js → chunk-BF6SXNQJ.js} +10 -10
- package/dist/{chunk-4PC4PRJE.js → chunk-BKIFTXHR.js} +2 -2
- package/dist/{chunk-VVG2BOKA.js → chunk-BMEYMKWX.js} +2 -2
- package/dist/{chunk-DCZBSE4F.js → chunk-D5YOZ66N.js} +18 -18
- package/dist/{chunk-BHXYAVUM.js → chunk-DLG5V6ND.js} +2 -2
- package/dist/{chunk-52UKFTUK.js → chunk-F4EU6VUC.js} +2 -2
- package/dist/{chunk-M4A44LUA.js → chunk-GSTIBXBW.js} +2 -2
- package/dist/{chunk-W5XVQFLM.js → chunk-GXFSQ6SD.js} +2 -2
- package/dist/{chunk-XADV5IZ3.js → chunk-HDIUYMSB.js} +5 -5
- package/dist/{chunk-FXTYIA46.js → chunk-J272WKX2.js} +2 -2
- package/dist/{chunk-ENTCVTQR.js → chunk-JJRVPWFY.js} +11 -1
- package/dist/chunk-JJRVPWFY.js.map +1 -0
- package/dist/{chunk-JYL3BVVZ.js → chunk-JSEJH2YQ.js} +2 -2
- package/dist/{chunk-5UDMFE3Q.js → chunk-MLXZD4WM.js} +2 -2
- package/dist/{chunk-PUSLMZBQ.js → chunk-NOEMGE56.js} +2 -2
- package/dist/{chunk-C5QLI33R.js → chunk-QINJITDS.js} +2 -2
- package/dist/{chunk-45BRYON6.js → chunk-QPOHMO6M.js} +2 -2
- package/dist/{chunk-ZQOCRIGA.js → chunk-QYN5PXDZ.js} +3 -3
- package/dist/{chunk-PA45XCUD.js → chunk-RANKJI5T.js} +2 -2
- package/dist/{chunk-ZHY5TMJG.js → chunk-RMHMUUBW.js} +2392 -628
- package/dist/chunk-RMHMUUBW.js.map +1 -0
- package/dist/{chunk-37ZO6LLJ.js → chunk-RYLEDKQ2.js} +2 -2
- package/dist/{chunk-CV6BBVYV.js → chunk-TEMSWHQD.js} +2 -2
- package/dist/{chunk-QGR6OVGT.js → chunk-VFSAWRMZ.js} +2 -2
- package/dist/{chunk-NLK2VZYZ.js → chunk-VXCNQYTC.js} +2 -2
- package/dist/{chunk-AZ2QBGYB.js → chunk-W7Y5JDVB.js} +1 -1
- package/dist/{chunk-VBHPOWBJ.js → chunk-WD5B5AIE.js} +1051 -591
- package/dist/chunk-WD5B5AIE.js.map +1 -0
- package/dist/{chunk-OYESWJ43.js → chunk-WLRD2TXF.js} +15 -10
- package/dist/chunk-WLRD2TXF.js.map +1 -0
- package/dist/{chunk-4F6X3RXW.js → chunk-X57M2Q4I.js} +2 -2
- package/dist/{chunk-6MTSFX7A.js → chunk-X7XEDOSL.js} +8 -8
- package/dist/{chunk-UEVLYVNW.js → chunk-YXKVLYXU.js} +2 -2
- package/dist/{chunk-OQAL6SIR.js → chunk-ZMSZVISA.js} +2 -2
- package/dist/{cli-CnOkH9hA.d.ts → cli-DMAFI0qt.d.ts} +3 -3
- package/dist/cli.d.ts +7 -6
- package/dist/cli.js +33 -33
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +7 -7
- package/dist/connectors/codex-materialize-runner.js +7 -7
- package/dist/connectors/index.js +7 -7
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +1 -1
- package/dist/convergence-refresh.js +9 -9
- package/dist/corpus-watermark.js +9 -9
- package/dist/dependency-propagation-delivery-D63r24pH.d.ts +41 -0
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +7 -7
- package/dist/explicit-capture.d.ts +5 -4
- package/dist/explicit-capture.js +4 -4
- package/dist/external-wiki-access.d.ts +6 -5
- package/dist/external-wiki-access.js +17 -17
- package/dist/external-wiki-mcp-tools.d.ts +6 -5
- package/dist/extraction.js +7 -7
- package/dist/{forget-UJDJHG6R.js → forget-HDS4N6CG.js} +3 -3
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/index.d.ts +687 -686
- package/dist/index.js +39 -39
- package/dist/maintenance/memory-governance.js +7 -7
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
- package/dist/maintenance/rebuild-memory-projection.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-projection.js +8 -8
- package/dist/{maintenance-CKwxpdRx.d.ts → maintenance-kBII2qUI.d.ts} +3 -2
- package/dist/mcp-memory-inspector-app.d.ts +6 -5
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +8 -8
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +7 -7
- package/dist/operator-doctor-corpus.js +10 -10
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +15 -15
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +12 -12
- package/dist/{orchestrator-BshGam-o.d.ts → orchestrator-DHy5LtTy.d.ts} +20 -35
- package/dist/orchestrator.d.ts +5 -4
- package/dist/orchestrator.js +39 -39
- package/dist/page-versioning.js +3 -3
- package/dist/schemas.d.ts +138 -138
- package/dist/semantic-consolidation.js +8 -8
- package/dist/semantic-rule-promotion.js +7 -7
- package/dist/semantic-rule-verifier.js +7 -7
- package/dist/{service-BIgVM7fL.d.ts → service-PT2_z7xm.d.ts} +1 -1
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/source-agent-qualifier.js +7 -7
- package/dist/{storage-CVfGWqCI.d.ts → storage-BmVudhk4.d.ts} +46 -27
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +6 -6
- package/dist/temporal-supersession.d.ts +51 -26
- package/dist/temporal-supersession.js +3 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/types.d.ts +66 -66
- package/dist/verified-recall.js +7 -7
- package/package.json +2 -2
- package/src/lifecycle/tombstones.ts +30 -0
- package/src/orchestration/consolidation-run.ts +324 -106
- package/src/orchestration/contradiction-linking-coordinator.ts +237 -64
- package/src/orchestration/dependency-propagation-delivery.test.ts +2353 -0
- package/src/orchestration/dependency-propagation-delivery.ts +1143 -0
- package/src/orchestration/dependency-propagation-queue-state.ts +220 -0
- package/src/orchestration/dependency-propagation-recovery-replay.ts +237 -0
- package/src/orchestration/dependency-propagation-replay-reconciliation.ts +73 -0
- package/src/orchestration/dependency-propagation-triggers.test.ts +1069 -11
- package/src/orchestration/dependency-propagation.test.ts +82 -31
- package/src/orchestration/dependency-propagation.ts +55 -17
- package/src/orchestration/extraction-persist-deps.ts +2 -2
- package/src/orchestration/extraction-persist.ts +14 -15
- package/src/orchestration/extraction-queue-coordinator.ts +23 -1
- package/src/orchestration/extraction-shutdown.ts +29 -0
- package/src/orchestration/maintenance.ts +13 -7
- package/src/orchestration/turn-ingestion.ts +5 -1
- package/src/orchestrator-background-writes.test.ts +265 -1
- package/src/orchestrator-extraction-queue.test.ts +39 -0
- package/src/orchestrator.ts +59 -58
- package/src/storage/committed-invalidation.ts +34 -0
- package/src/storage/deletion-revision-store.ts +529 -0
- package/src/storage/supersession-audit.ts +41 -0
- package/src/storage/supersession-side-effects.ts +52 -25
- package/src/storage-contract/failure-semantics.test.ts +12 -0
- package/src/storage-contract/round-trip.test.ts +184 -2
- package/src/storage-deletion-revisions.test.ts +213 -1
- package/src/storage-frontmatter-cas.test.ts +141 -0
- package/src/storage-memory-lifecycle-ledger.test.ts +372 -0
- package/src/storage-replay.test.ts +149 -0
- package/src/storage.ts +345 -358
- package/src/temporal-supersession.test.ts +431 -2
- package/src/temporal-supersession.ts +567 -107
- package/src/testing/subjects/dependency-propagation.test.ts +179 -38
- package/dist/chunk-ENTCVTQR.js.map +0 -1
- package/dist/chunk-EWMTOVMY.js +0 -484
- package/dist/chunk-EWMTOVMY.js.map +0 -1
- package/dist/chunk-OYESWJ43.js.map +0 -1
- package/dist/chunk-VBHPOWBJ.js.map +0 -1
- package/dist/chunk-ZHY5TMJG.js.map +0 -1
- /package/dist/{capsule-merge-XMFBXVDP.js.map → capsule-merge-HCJJMLPS.js.map} +0 -0
- /package/dist/{chunk-PWN32TAG.js.map → chunk-2ASAS3CQ.js.map} +0 -0
- /package/dist/{chunk-WQM326GS.js.map → chunk-2LY6GIIE.js.map} +0 -0
- /package/dist/{chunk-JL43BVDE.js.map → chunk-2OIQDTDC.js.map} +0 -0
- /package/dist/{chunk-33SV3E43.js.map → chunk-3OY7KXHM.js.map} +0 -0
- /package/dist/{chunk-AIUBBHSF.js.map → chunk-5UZ6UCOZ.js.map} +0 -0
- /package/dist/{chunk-UT5BV5OG.js.map → chunk-7HXZJAID.js.map} +0 -0
- /package/dist/{chunk-M7BXDKPR.js.map → chunk-7M6NYQWB.js.map} +0 -0
- /package/dist/{chunk-TPTECFWR.js.map → chunk-B6LZ4IBH.js.map} +0 -0
- /package/dist/{chunk-J5LLX6IL.js.map → chunk-BF6SXNQJ.js.map} +0 -0
- /package/dist/{chunk-4PC4PRJE.js.map → chunk-BKIFTXHR.js.map} +0 -0
- /package/dist/{chunk-VVG2BOKA.js.map → chunk-BMEYMKWX.js.map} +0 -0
- /package/dist/{chunk-DCZBSE4F.js.map → chunk-D5YOZ66N.js.map} +0 -0
- /package/dist/{chunk-BHXYAVUM.js.map → chunk-DLG5V6ND.js.map} +0 -0
- /package/dist/{chunk-52UKFTUK.js.map → chunk-F4EU6VUC.js.map} +0 -0
- /package/dist/{chunk-M4A44LUA.js.map → chunk-GSTIBXBW.js.map} +0 -0
- /package/dist/{chunk-W5XVQFLM.js.map → chunk-GXFSQ6SD.js.map} +0 -0
- /package/dist/{chunk-XADV5IZ3.js.map → chunk-HDIUYMSB.js.map} +0 -0
- /package/dist/{chunk-FXTYIA46.js.map → chunk-J272WKX2.js.map} +0 -0
- /package/dist/{chunk-JYL3BVVZ.js.map → chunk-JSEJH2YQ.js.map} +0 -0
- /package/dist/{chunk-5UDMFE3Q.js.map → chunk-MLXZD4WM.js.map} +0 -0
- /package/dist/{chunk-PUSLMZBQ.js.map → chunk-NOEMGE56.js.map} +0 -0
- /package/dist/{chunk-C5QLI33R.js.map → chunk-QINJITDS.js.map} +0 -0
- /package/dist/{chunk-45BRYON6.js.map → chunk-QPOHMO6M.js.map} +0 -0
- /package/dist/{chunk-ZQOCRIGA.js.map → chunk-QYN5PXDZ.js.map} +0 -0
- /package/dist/{chunk-PA45XCUD.js.map → chunk-RANKJI5T.js.map} +0 -0
- /package/dist/{chunk-37ZO6LLJ.js.map → chunk-RYLEDKQ2.js.map} +0 -0
- /package/dist/{chunk-CV6BBVYV.js.map → chunk-TEMSWHQD.js.map} +0 -0
- /package/dist/{chunk-QGR6OVGT.js.map → chunk-VFSAWRMZ.js.map} +0 -0
- /package/dist/{chunk-NLK2VZYZ.js.map → chunk-VXCNQYTC.js.map} +0 -0
- /package/dist/{chunk-AZ2QBGYB.js.map → chunk-W7Y5JDVB.js.map} +0 -0
- /package/dist/{chunk-4F6X3RXW.js.map → chunk-X57M2Q4I.js.map} +0 -0
- /package/dist/{chunk-6MTSFX7A.js.map → chunk-X7XEDOSL.js.map} +0 -0
- /package/dist/{chunk-UEVLYVNW.js.map → chunk-YXKVLYXU.js.map} +0 -0
- /package/dist/{chunk-OQAL6SIR.js.map → chunk-ZMSZVISA.js.map} +0 -0
- /package/dist/{forget-UJDJHG6R.js.map → forget-HDS4N6CG.js.map} +0 -0
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
* identity consolidation, recall section config, fast LLM) arrives as
|
|
21
21
|
* injectable delegates.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
* orchestrator keeps a thin delegating method so existing call sites
|
|
23
|
+
* The orchestrator keeps a thin delegating method so existing call sites
|
|
25
24
|
* (runConsolidationNow, maintenance scheduler) and tests continue to work.
|
|
26
25
|
*/
|
|
27
26
|
|
|
@@ -32,7 +31,12 @@ import { applyCommitmentLedgerLifecycle } from "../commitment-ledger.js";
|
|
|
32
31
|
import { recordDreamsPhaseRun } from "../maintenance/dreams-ledger.js";
|
|
33
32
|
import { deindexMemoriesBatchAsync } from "../temporal-index-batch.js";
|
|
34
33
|
import { isActiveMemoryStatus } from "../memory-lifecycle-ledger-utils.js";
|
|
35
|
-
import {
|
|
34
|
+
import type {
|
|
35
|
+
DependencyPropagationDeliveryPort,
|
|
36
|
+
DependencyPropagationPreparationToken,
|
|
37
|
+
} from "./dependency-propagation-delivery.js";
|
|
38
|
+
import { canonicalize } from "./dependency-propagation-queue-state.js";
|
|
39
|
+
import type { PropagationEvent } from "./dependency-propagation.js";
|
|
36
40
|
import {
|
|
37
41
|
resolveCapabilities,
|
|
38
42
|
resolveConsolidationCapabilities,
|
|
@@ -73,11 +77,13 @@ export interface ConsolidationRunCoordinatorDeps {
|
|
|
73
77
|
getStorageRouter: () => NamespaceStorageRouter;
|
|
74
78
|
getNamespaceCatalog?: () => NamespaceCatalog;
|
|
75
79
|
getExtraction: () => ExtractionEngine;
|
|
80
|
+
storageDirNamespace: (storageDir: string) => string;
|
|
76
81
|
embeddingFallback: EmbeddingFallback;
|
|
77
82
|
tmtBuilder: TmtBuilder;
|
|
78
83
|
consolidationObservers: Set<
|
|
79
84
|
(observation: ConsolidationObservation) => Promise<void> | void
|
|
80
85
|
>;
|
|
86
|
+
getDependencyPropagationDelivery: () => DependencyPropagationDeliveryPort;
|
|
81
87
|
getAccessTrackingBuffer: () => Map<
|
|
82
88
|
string,
|
|
83
89
|
{ count: number; lastAccessed: string }
|
|
@@ -113,6 +119,185 @@ type HarmonicStore = {
|
|
|
113
119
|
abstractionNodeStoreDir?: string;
|
|
114
120
|
};
|
|
115
121
|
|
|
122
|
+
type PendingDependencyPropagation = {
|
|
123
|
+
delivery: DependencyPropagationDeliveryPort;
|
|
124
|
+
event: PropagationEvent;
|
|
125
|
+
preparation: DependencyPropagationPreparationToken | null;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
async function prepareDependencyPropagation(
|
|
129
|
+
getDelivery: () => DependencyPropagationDeliveryPort,
|
|
130
|
+
event: PropagationEvent,
|
|
131
|
+
enabled: boolean,
|
|
132
|
+
): Promise<PendingDependencyPropagation | null> {
|
|
133
|
+
if (!enabled) return null;
|
|
134
|
+
let delivery: DependencyPropagationDeliveryPort;
|
|
135
|
+
try {
|
|
136
|
+
delivery = getDelivery();
|
|
137
|
+
} catch (error) {
|
|
138
|
+
log.warn(`consolidation dependency propagation getter failed: ${error}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
let preparation: DependencyPropagationPreparationToken | null = null;
|
|
142
|
+
try {
|
|
143
|
+
preparation = await delivery.prepare(event);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
log.warn(`consolidation dependency propagation preparation failed: ${error}`);
|
|
146
|
+
}
|
|
147
|
+
return { delivery, event, preparation };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function clonePropagationMemory(memory: MemoryFile): MemoryFile {
|
|
151
|
+
return structuredClone(memory);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function sameMemorySnapshot(a: MemoryFile, b: MemoryFile): boolean {
|
|
155
|
+
return (
|
|
156
|
+
a.content === b.content &&
|
|
157
|
+
JSON.stringify(canonicalize(a.frontmatter)) === JSON.stringify(canonicalize(b.frontmatter))
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function prepareCurrentDependencyPropagation(
|
|
162
|
+
storage: StorageManager,
|
|
163
|
+
getDelivery: () => DependencyPropagationDeliveryPort,
|
|
164
|
+
sourceId: string,
|
|
165
|
+
buildEvent: (source: MemoryFile) => PropagationEvent,
|
|
166
|
+
enabled: boolean,
|
|
167
|
+
): Promise<{ source: MemoryFile; pending: PendingDependencyPropagation | null } | null> {
|
|
168
|
+
const loaded = await storage.getMemoryById(sourceId);
|
|
169
|
+
if (!loaded) return null;
|
|
170
|
+
let source = clonePropagationMemory(loaded);
|
|
171
|
+
let pending = await prepareDependencyPropagation(getDelivery, buildEvent(source), enabled);
|
|
172
|
+
if (!pending) return { source, pending: null };
|
|
173
|
+
let latest: MemoryFile | null;
|
|
174
|
+
try {
|
|
175
|
+
latest = await storage.getMemoryById(sourceId);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
await cancelDependencyPropagation(pending);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
if (!latest) {
|
|
181
|
+
await cancelDependencyPropagation(pending);
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
if (!sameMemorySnapshot(source, latest)) {
|
|
185
|
+
await cancelDependencyPropagation(pending);
|
|
186
|
+
source = clonePropagationMemory(latest);
|
|
187
|
+
pending = await prepareDependencyPropagation(getDelivery, buildEvent(source), enabled);
|
|
188
|
+
}
|
|
189
|
+
return { source, pending };
|
|
190
|
+
}
|
|
191
|
+
async function cancelDependencyPropagation(
|
|
192
|
+
pending: PendingDependencyPropagation,
|
|
193
|
+
): Promise<void> {
|
|
194
|
+
if (!pending.preparation?.ownsPreparedJob) return;
|
|
195
|
+
try {
|
|
196
|
+
await pending.delivery.cancel(pending.preparation);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
log.warn(`consolidation dependency propagation cancellation failed: ${error}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function deferDependencyPropagation(
|
|
203
|
+
pending: PendingDependencyPropagation | null,
|
|
204
|
+
): Promise<void> {
|
|
205
|
+
if (!pending) return;
|
|
206
|
+
let token = pending.preparation;
|
|
207
|
+
if (token === null) {
|
|
208
|
+
try {
|
|
209
|
+
token = await pending.delivery.prepare(pending.event);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
log.warn(`consolidation dependency propagation recovery preparation failed: ${error}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (token === null) return;
|
|
215
|
+
try {
|
|
216
|
+
await pending.delivery.deferPrepared(token);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
log.warn(`consolidation dependency propagation defer failed: ${error}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function afterDependencyPropagationMutation(
|
|
223
|
+
pending: PendingDependencyPropagation,
|
|
224
|
+
): Promise<void> {
|
|
225
|
+
try {
|
|
226
|
+
await pending.delivery.afterMutation(pending.preparation, pending.event);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
log.warn(`consolidation dependency propagation delivery failed: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
type InvalidationCommitState = "committed" | "not-committed" | "unknown";
|
|
232
|
+
|
|
233
|
+
async function classifyInvalidation(
|
|
234
|
+
storage: StorageManager,
|
|
235
|
+
memoryId: string,
|
|
236
|
+
expectedSnapshot: MemoryFile | null,
|
|
237
|
+
options: {
|
|
238
|
+
checkInvalidationProof?: boolean;
|
|
239
|
+
missingMeansCommitted?: boolean;
|
|
240
|
+
matchesCommitted?: (current: MemoryFile) => boolean;
|
|
241
|
+
} = {},
|
|
242
|
+
): Promise<InvalidationCommitState> {
|
|
243
|
+
if (options.checkInvalidationProof !== false && expectedSnapshot) {
|
|
244
|
+
if (!storage.hasCommittedInvalidation) {
|
|
245
|
+
log.warn(`consolidation invalidation proof capability missing for ${memoryId}`);
|
|
246
|
+
} else {
|
|
247
|
+
try {
|
|
248
|
+
if (await storage.hasCommittedInvalidation(expectedSnapshot)) return "committed";
|
|
249
|
+
} catch (error) {
|
|
250
|
+
log.warn(`consolidation invalidation proof read failed for ${memoryId}: ${error}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
const current = await storage.getMemoryById(memoryId);
|
|
256
|
+
if (!current) {
|
|
257
|
+
if (options.missingMeansCommitted === false) return "not-committed";
|
|
258
|
+
if (expectedSnapshot && !storage.hasCommittedInvalidation) return "unknown";
|
|
259
|
+
return "committed";
|
|
260
|
+
}
|
|
261
|
+
if (options.matchesCommitted?.(current)) return "committed";
|
|
262
|
+
if (expectedSnapshot && sameMemorySnapshot(current, expectedSnapshot)) {
|
|
263
|
+
return "not-committed";
|
|
264
|
+
}
|
|
265
|
+
return "unknown";
|
|
266
|
+
} catch (error) {
|
|
267
|
+
log.warn(`consolidation invalidation state read failed for ${memoryId}: ${error}`);
|
|
268
|
+
return "unknown";
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function settleFailedConsolidationPropagation(
|
|
273
|
+
pending: PendingDependencyPropagation | null,
|
|
274
|
+
commitState: InvalidationCommitState,
|
|
275
|
+
memoryId: string,
|
|
276
|
+
): Promise<void> {
|
|
277
|
+
if (!pending) return;
|
|
278
|
+
let token = pending.preparation;
|
|
279
|
+
if (commitState === "not-committed") {
|
|
280
|
+
if (token !== null) await cancelDependencyPropagation({ ...pending, preparation: token });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (token === null && (commitState === "committed" || commitState === "unknown")) {
|
|
284
|
+
try {
|
|
285
|
+
token = await pending.delivery.prepare(pending.event);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
log.warn(
|
|
288
|
+
`consolidation dependency propagation recovery preparation failed for ${memoryId}: ${error}`,
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (token !== null) {
|
|
293
|
+
try {
|
|
294
|
+
await pending.delivery.deferPrepared(token);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
log.warn(`consolidation dependency propagation defer failed for ${memoryId}: ${error}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
116
301
|
type HarmonicCatalogCursor = {
|
|
117
302
|
nextStorageDir?: string;
|
|
118
303
|
};
|
|
@@ -286,66 +471,75 @@ export class ConsolidationRunCoordinator {
|
|
|
286
471
|
const profile = await storage.readProfile();
|
|
287
472
|
const result = await this.deps.getExtraction().consolidate(recent, older, profile);
|
|
288
473
|
|
|
289
|
-
// Build a lookup map from the already-loaded corpus to avoid repeated
|
|
290
|
-
// readAllMemories() scans inside getMemoryById for pre-action deindex reads.
|
|
291
|
-
const memoryLookup = resolveIndexingCapabilities(config).queryAwareIndexing
|
|
292
|
-
? new Map(allMemories.map((m) => [m.frontmatter.id, m]))
|
|
293
|
-
: null;
|
|
294
|
-
|
|
295
474
|
// Collect deindex entries from INVALIDATE/MERGE actions and de-index them in
|
|
296
|
-
// one batch, instead of a full index read-modify-write per memory. The
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
// disk are still de-indexed if a later iteration throws; it runs exactly once
|
|
301
|
-
// (normal completion or throw) and any loop error still propagates after it.
|
|
475
|
+
// one batch, instead of a full index read-modify-write per memory. The flush
|
|
476
|
+
// runs in `finally` so memories already invalidated on disk are still
|
|
477
|
+
// de-indexed if a later iteration throws; it runs exactly once and any loop
|
|
478
|
+
// error still propagates after it.
|
|
302
479
|
const itemsDeindexBatch: Array<{ path: string; createdAt: string; tags: string[] }> = [];
|
|
303
480
|
|
|
304
481
|
try {
|
|
305
482
|
for (const item of result.items) {
|
|
306
483
|
switch (item.action) {
|
|
307
484
|
case "INVALIDATE": {
|
|
308
|
-
|
|
485
|
+
const propagationEnabled =
|
|
486
|
+
config.dependencyPropagation.enabled &&
|
|
487
|
+
config.dependencyPropagation.maxDependents > 0;
|
|
488
|
+
const prepared = await prepareCurrentDependencyPropagation(
|
|
489
|
+
storage,
|
|
490
|
+
this.deps.getDependencyPropagationDelivery,
|
|
491
|
+
item.existingId,
|
|
492
|
+
(propagationOld) => ({
|
|
493
|
+
oldMemory: propagationOld,
|
|
494
|
+
replacementId: null,
|
|
495
|
+
replacementContent: null,
|
|
496
|
+
cause: "consolidation_invalidate",
|
|
497
|
+
namespaceScope: this.deps.storageDirNamespace(storage.dir),
|
|
498
|
+
}),
|
|
499
|
+
propagationEnabled,
|
|
500
|
+
);
|
|
501
|
+
const propagationOld = prepared?.source ?? null;
|
|
502
|
+
const pending = prepared?.pending ?? null;
|
|
503
|
+
const expectedSnapshot = pending ? propagationOld : null;
|
|
309
504
|
const toInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
|
|
310
|
-
?
|
|
505
|
+
? propagationOld
|
|
311
506
|
: null;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
507
|
+
const recordCommitProof = pending?.preparation?.ownsPreparedJob === true;
|
|
508
|
+
let didInvalidate: boolean;
|
|
509
|
+
try {
|
|
510
|
+
didInvalidate = await storage.invalidateMemory(
|
|
511
|
+
item.existingId,
|
|
512
|
+
expectedSnapshot ?? undefined,
|
|
513
|
+
{ recordCommitProof },
|
|
514
|
+
);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
const commitState = await classifyInvalidation(storage, item.existingId, expectedSnapshot);
|
|
517
|
+
await settleFailedConsolidationPropagation(
|
|
518
|
+
pending,
|
|
519
|
+
commitState,
|
|
520
|
+
item.existingId,
|
|
521
|
+
);
|
|
522
|
+
throw error;
|
|
523
|
+
}
|
|
524
|
+
if (!didInvalidate) {
|
|
525
|
+
const commitState = await classifyInvalidation(storage, item.existingId, expectedSnapshot);
|
|
526
|
+
await settleFailedConsolidationPropagation(
|
|
527
|
+
pending,
|
|
528
|
+
commitState,
|
|
529
|
+
item.existingId,
|
|
530
|
+
);
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
invalidated += 1;
|
|
534
|
+
memoryItemMutated = true;
|
|
535
|
+
if (pending) await afterDependencyPropagationMutation(pending);
|
|
536
|
+
await this.deps.embeddingFallback.removeFromIndex(item.existingId);
|
|
537
|
+
if (toInvalidate?.path && toInvalidate.frontmatter?.created) {
|
|
538
|
+
itemsDeindexBatch.push({
|
|
539
|
+
path: toInvalidate.path,
|
|
540
|
+
createdAt: toInvalidate.frontmatter.created,
|
|
541
|
+
tags: toInvalidate.frontmatter.tags ?? [],
|
|
542
|
+
});
|
|
349
543
|
}
|
|
350
544
|
break;
|
|
351
545
|
}
|
|
@@ -366,63 +560,87 @@ export class ConsolidationRunCoordinator {
|
|
|
366
560
|
break;
|
|
367
561
|
case "MERGE":
|
|
368
562
|
if (item.updatedContent && item.mergeWith) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
563
|
+
const updatedContent = item.updatedContent;
|
|
564
|
+
const mergeWith = item.mergeWith;
|
|
565
|
+
const propagationEnabled =
|
|
566
|
+
config.dependencyPropagation.enabled &&
|
|
567
|
+
config.dependencyPropagation.maxDependents > 0;
|
|
568
|
+
const prepared = await prepareCurrentDependencyPropagation(
|
|
569
|
+
storage,
|
|
570
|
+
this.deps.getDependencyPropagationDelivery,
|
|
571
|
+
item.mergeWith,
|
|
572
|
+
(propagationOld) => ({
|
|
573
|
+
oldMemory: propagationOld,
|
|
574
|
+
replacementId: item.existingId,
|
|
575
|
+
replacementContent: updatedContent,
|
|
576
|
+
cause: "consolidation_merge",
|
|
577
|
+
namespaceScope: this.deps.storageDirNamespace(storage.dir),
|
|
578
|
+
}),
|
|
579
|
+
propagationEnabled,
|
|
376
580
|
);
|
|
581
|
+
const propagationOld = prepared?.source ?? null;
|
|
582
|
+
const pending = prepared?.pending ?? null;
|
|
583
|
+
const expectedSnapshot = pending ? propagationOld : null;
|
|
584
|
+
const toMergeInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
|
|
585
|
+
? propagationOld
|
|
586
|
+
: null;
|
|
587
|
+
let didUpdate: boolean;
|
|
588
|
+
try {
|
|
589
|
+
didUpdate = await storage.updateMemory(
|
|
590
|
+
item.existingId,
|
|
591
|
+
updatedContent,
|
|
592
|
+
{
|
|
593
|
+
supersedes: item.mergeWith,
|
|
594
|
+
lineage: [item.existingId, item.mergeWith],
|
|
595
|
+
},
|
|
596
|
+
);
|
|
597
|
+
} catch (error) {
|
|
598
|
+
await deferDependencyPropagation(pending);
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
if (!didUpdate) {
|
|
602
|
+
if (pending) await cancelDependencyPropagation(pending);
|
|
603
|
+
break;
|
|
604
|
+
}
|
|
377
605
|
memoryItemMutated = true;
|
|
378
606
|
await this.deps.indexPersistedMemory(storage, item.existingId);
|
|
379
607
|
// updateMemory() only changes content/updated/supersedes/lineage — path, created, and tags
|
|
380
608
|
// are preserved, so the temporal/tag index entry for the survivor is already correct.
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
if (
|
|
417
|
-
toMergeInvalidate?.path &&
|
|
418
|
-
toMergeInvalidate.frontmatter?.created
|
|
419
|
-
) {
|
|
420
|
-
itemsDeindexBatch.push({
|
|
421
|
-
path: toMergeInvalidate.path,
|
|
422
|
-
createdAt: toMergeInvalidate.frontmatter.created,
|
|
423
|
-
tags: toMergeInvalidate.frontmatter.tags ?? [],
|
|
424
|
-
});
|
|
425
|
-
}
|
|
609
|
+
let didInvalidate: boolean;
|
|
610
|
+
try {
|
|
611
|
+
didInvalidate = await storage.invalidateMemory(
|
|
612
|
+
item.mergeWith,
|
|
613
|
+
expectedSnapshot ?? undefined,
|
|
614
|
+
{ recordCommitProof: pending?.preparation?.ownsPreparedJob === true },
|
|
615
|
+
);
|
|
616
|
+
} catch (error) {
|
|
617
|
+
const commitState = await classifyInvalidation(storage, item.mergeWith, expectedSnapshot);
|
|
618
|
+
await settleFailedConsolidationPropagation(
|
|
619
|
+
pending,
|
|
620
|
+
commitState,
|
|
621
|
+
item.mergeWith,
|
|
622
|
+
);
|
|
623
|
+
throw error;
|
|
624
|
+
}
|
|
625
|
+
if (!didInvalidate) {
|
|
626
|
+
const commitState = await classifyInvalidation(storage, item.mergeWith, expectedSnapshot);
|
|
627
|
+
await settleFailedConsolidationPropagation(
|
|
628
|
+
pending,
|
|
629
|
+
commitState,
|
|
630
|
+
item.mergeWith,
|
|
631
|
+
);
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
invalidated += 1;
|
|
635
|
+
merged += 1;
|
|
636
|
+
if (pending) await afterDependencyPropagationMutation(pending);
|
|
637
|
+
await this.deps.embeddingFallback.removeFromIndex(item.mergeWith);
|
|
638
|
+
if (toMergeInvalidate?.path && toMergeInvalidate.frontmatter?.created) {
|
|
639
|
+
itemsDeindexBatch.push({
|
|
640
|
+
path: toMergeInvalidate.path,
|
|
641
|
+
createdAt: toMergeInvalidate.frontmatter.created,
|
|
642
|
+
tags: toMergeInvalidate.frontmatter.tags ?? [],
|
|
643
|
+
});
|
|
426
644
|
}
|
|
427
645
|
}
|
|
428
646
|
break;
|