@remnic/core 9.38.3 → 9.39.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 +5 -5
- package/dist/access-admin-ops-surface.js +12 -12
- package/dist/access-authorization-probe.d.ts +5 -5
- package/dist/access-authorization-probe.js +13 -13
- package/dist/access-boundary.d.ts +5 -5
- package/dist/access-boundary.js +12 -12
- package/dist/access-cli.js +31 -31
- package/dist/access-extraction-force-flush.d.ts +5 -5
- package/dist/access-extraction-force-flush.js +12 -12
- package/dist/access-http-lcm-compaction.d.ts +5 -5
- package/dist/access-http-lifecycle-flush.d.ts +5 -5
- package/dist/access-http.d.ts +5 -5
- package/dist/access-http.js +17 -17
- package/dist/access-identity-continuity-surface.d.ts +4 -4
- package/dist/access-identity-continuity-surface.js +12 -12
- package/dist/access-lcm-surface.d.ts +5 -5
- package/dist/access-lcm-surface.js +12 -12
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +15 -15
- package/dist/access-namespace-preflight.js +12 -12
- package/dist/access-observe-write-surface.d.ts +5 -5
- package/dist/access-observe-write-surface.js +12 -12
- package/dist/access-operations-batch.js +13 -13
- package/dist/access-operations.d.ts +8 -8
- package/dist/access-operations.js +14 -14
- package/dist/access-recall-concurrency.d.ts +5 -5
- package/dist/access-recall-concurrency.js +12 -12
- package/dist/access-recall-response.d.ts +5 -5
- package/dist/access-recall-response.js +12 -12
- package/dist/access-recall-surface.d.ts +5 -5
- package/dist/access-recall-surface.js +12 -12
- package/dist/access-schema.d.ts +84 -84
- package/dist/{access-service-C2WYT1pO.d.ts → access-service-C6QuKBCG.d.ts} +3 -3
- package/dist/access-service-helpers.d.ts +5 -5
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +12 -12
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/access-wearables-meetings-surface.d.ts +2 -2
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +5 -5
- package/dist/buffer.d.ts +1 -1
- package/dist/causal-consolidation.js +6 -6
- package/dist/{chunk-POQGCS4H.js → chunk-4CSTEPFA.js} +2 -2
- package/dist/{chunk-T3FVAHM7.js → chunk-4VXGRIH6.js} +286 -7
- package/dist/chunk-4VXGRIH6.js.map +1 -0
- package/dist/{chunk-XBJC7RTW.js → chunk-5JUYBWJD.js} +16 -16
- package/dist/{chunk-JYLN6KHH.js → chunk-5TRIAPT4.js} +7 -9
- package/dist/{chunk-JYLN6KHH.js.map → chunk-5TRIAPT4.js.map} +1 -1
- package/dist/{chunk-6D5D5A4M.js → chunk-7ERHAARG.js} +2 -2
- package/dist/{chunk-RMOSIGGI.js → chunk-7OCTH7AJ.js} +2 -2
- package/dist/{chunk-ILGC6JH6.js → chunk-7RJUVTVF.js} +16 -1
- package/dist/chunk-7RJUVTVF.js.map +1 -0
- package/dist/{chunk-FE7MUX7M.js → chunk-AL73FWSS.js} +2 -2
- package/dist/{chunk-6TF4M2LB.js → chunk-AVGTOOYP.js} +2 -2
- package/dist/{chunk-XEM77GGX.js → chunk-BVJIAIB3.js} +7 -7
- package/dist/{chunk-PRP3M5Y3.js → chunk-CMFUYOYB.js} +2 -2
- package/dist/{chunk-AF4HOJMH.js → chunk-CNZLKQEL.js} +2 -2
- package/dist/{chunk-YVMVVE4B.js → chunk-CPD6C6K6.js} +2 -2
- package/dist/{chunk-P2NCTIKE.js → chunk-CYM2PHLB.js} +5 -5
- package/dist/{chunk-RY2XZTFN.js → chunk-DJH35IVS.js} +2 -2
- package/dist/{chunk-Q3CVY7LV.js → chunk-ENLZOWYK.js} +201 -231
- package/dist/chunk-ENLZOWYK.js.map +1 -0
- package/dist/{chunk-IJAQCBGV.js → chunk-F5EVTFQK.js} +2 -2
- package/dist/{chunk-RY7CHVGE.js → chunk-G57BGHQ2.js} +2 -2
- package/dist/{chunk-IMEXE4XS.js → chunk-GYGXKATH.js} +6 -6
- package/dist/{chunk-C3HUHJ4G.js → chunk-JKTHT4KX.js} +3 -3
- package/dist/{chunk-44SRDUI4.js → chunk-KJP2R5MJ.js} +15 -15
- package/dist/{chunk-UBWOCQ3I.js → chunk-MHCRASVK.js} +2 -2
- package/dist/{chunk-DKKZ6SO2.js → chunk-SHTPVI47.js} +22 -45
- package/dist/chunk-SHTPVI47.js.map +1 -0
- package/dist/{chunk-PYTUBWAS.js → chunk-UGAZILZG.js} +2 -2
- package/dist/{chunk-4TAD3B56.js → chunk-VGK33D3K.js} +2 -2
- package/dist/{chunk-BGLDKAYY.js → chunk-VK33JSBR.js} +2 -2
- package/dist/{chunk-NBAEGFXT.js → chunk-VQTRSX4R.js} +11 -14
- package/dist/chunk-VQTRSX4R.js.map +1 -0
- package/dist/{chunk-WET4M3R6.js → chunk-XSPD6KQL.js} +2 -2
- package/dist/{chunk-HUS2XN3T.js → chunk-YFHMW37V.js} +2 -2
- package/dist/{chunk-HKF5VASQ.js → chunk-ZA53AZND.js} +17 -6
- package/dist/chunk-ZA53AZND.js.map +1 -0
- package/dist/{chunk-5ZGHUWTT.js → chunk-ZBDORYWM.js} +2 -2
- package/dist/{cli-jkmzdT8P.d.ts → cli-ClXRCu08.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +26 -26
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +5 -5
- package/dist/connectors/codex-materialize-runner.js +5 -5
- package/dist/connectors/index.js +5 -5
- 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/corpus-watermark.js +7 -7
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/extraction.js +5 -5
- package/dist/index.d.ts +398 -398
- package/dist/index.js +31 -31
- package/dist/maintenance/memory-governance.js +5 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.d.ts +17 -10
- package/dist/maintenance/rebuild-memory-projection.js +6 -6
- package/dist/{maintenance-Ha9Dg93M.d.ts → maintenance-Dsvprbod.d.ts} +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-lifecycle-ledger-utils.d.ts +8 -1
- package/dist/memory-lifecycle-ledger-utils.js +5 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +5 -5
- package/dist/offline-sync-impression-drain.js +5 -3
- package/dist/operator-doctor-corpus.js +8 -8
- 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/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +10 -10
- package/dist/{orchestrator-DV_u9bfx.d.ts → orchestrator-CEhod0MJ.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +31 -31
- package/dist/schemas.d.ts +76 -76
- package/dist/semantic-consolidation.js +6 -6
- package/dist/semantic-rule-promotion.js +5 -5
- package/dist/semantic-rule-verifier.js +5 -5
- package/dist/{service-JxXXY-Eh.d.ts → service-BlOfGid8.d.ts} +1 -1
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/source-agent-qualifier.js +5 -5
- package/dist/{storage-BbH4HDUS.d.ts → storage-CNKZocJF.d.ts} +1 -1
- package/dist/storage-guards.d.ts +9 -2
- package/dist/storage-guards.js +3 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +4 -4
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/transfer/types.d.ts +66 -66
- package/dist/verified-recall.js +5 -5
- package/package.json +2 -2
- package/src/maintenance/projection-support.ts +192 -1
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +5 -16
- package/src/maintenance/rebuild-memory-projection.ts +28 -60
- package/src/memory-lifecycle-ledger-utils.ts +21 -0
- package/src/orchestration/maintenance.test.ts +30 -0
- package/src/storage/memory-lifecycle-ledger-access.ts +198 -1
- package/src/storage/secure-line-reader.ts +3 -1
- package/src/storage-guards.ts +28 -7
- package/src/storage-memory-lifecycle-ledger.test.ts +291 -1
- package/src/storage.ts +11 -21
- package/dist/chunk-DKKZ6SO2.js.map +0 -1
- package/dist/chunk-HKF5VASQ.js.map +0 -1
- package/dist/chunk-ILGC6JH6.js.map +0 -1
- package/dist/chunk-NBAEGFXT.js.map +0 -1
- package/dist/chunk-Q3CVY7LV.js.map +0 -1
- package/dist/chunk-T3FVAHM7.js.map +0 -1
- /package/dist/{chunk-POQGCS4H.js.map → chunk-4CSTEPFA.js.map} +0 -0
- /package/dist/{chunk-XBJC7RTW.js.map → chunk-5JUYBWJD.js.map} +0 -0
- /package/dist/{chunk-6D5D5A4M.js.map → chunk-7ERHAARG.js.map} +0 -0
- /package/dist/{chunk-RMOSIGGI.js.map → chunk-7OCTH7AJ.js.map} +0 -0
- /package/dist/{chunk-FE7MUX7M.js.map → chunk-AL73FWSS.js.map} +0 -0
- /package/dist/{chunk-6TF4M2LB.js.map → chunk-AVGTOOYP.js.map} +0 -0
- /package/dist/{chunk-XEM77GGX.js.map → chunk-BVJIAIB3.js.map} +0 -0
- /package/dist/{chunk-PRP3M5Y3.js.map → chunk-CMFUYOYB.js.map} +0 -0
- /package/dist/{chunk-AF4HOJMH.js.map → chunk-CNZLKQEL.js.map} +0 -0
- /package/dist/{chunk-YVMVVE4B.js.map → chunk-CPD6C6K6.js.map} +0 -0
- /package/dist/{chunk-P2NCTIKE.js.map → chunk-CYM2PHLB.js.map} +0 -0
- /package/dist/{chunk-RY2XZTFN.js.map → chunk-DJH35IVS.js.map} +0 -0
- /package/dist/{chunk-IJAQCBGV.js.map → chunk-F5EVTFQK.js.map} +0 -0
- /package/dist/{chunk-RY7CHVGE.js.map → chunk-G57BGHQ2.js.map} +0 -0
- /package/dist/{chunk-IMEXE4XS.js.map → chunk-GYGXKATH.js.map} +0 -0
- /package/dist/{chunk-C3HUHJ4G.js.map → chunk-JKTHT4KX.js.map} +0 -0
- /package/dist/{chunk-44SRDUI4.js.map → chunk-KJP2R5MJ.js.map} +0 -0
- /package/dist/{chunk-UBWOCQ3I.js.map → chunk-MHCRASVK.js.map} +0 -0
- /package/dist/{chunk-PYTUBWAS.js.map → chunk-UGAZILZG.js.map} +0 -0
- /package/dist/{chunk-4TAD3B56.js.map → chunk-VGK33D3K.js.map} +0 -0
- /package/dist/{chunk-BGLDKAYY.js.map → chunk-VK33JSBR.js.map} +0 -0
- /package/dist/{chunk-WET4M3R6.js.map → chunk-XSPD6KQL.js.map} +0 -0
- /package/dist/{chunk-HUS2XN3T.js.map → chunk-YFHMW37V.js.map} +0 -0
- /package/dist/{chunk-5ZGHUWTT.js.map → chunk-ZBDORYWM.js.map} +0 -0
|
@@ -15,10 +15,6 @@ import {
|
|
|
15
15
|
buildRetiredFactTombstoneInputs,
|
|
16
16
|
collectRetiredMemoriesForRebuild
|
|
17
17
|
} from "./chunk-ENTCVTQR.js";
|
|
18
|
-
import {
|
|
19
|
-
assertMemoryFrontmatterId,
|
|
20
|
-
warnProjectionFallback
|
|
21
|
-
} from "./chunk-HKF5VASQ.js";
|
|
22
18
|
import {
|
|
23
19
|
DEFAULT_CITATION_FORMAT,
|
|
24
20
|
hasCitation,
|
|
@@ -29,24 +25,31 @@ import {
|
|
|
29
25
|
confidenceTier
|
|
30
26
|
} from "./chunk-HXDWZFNP.js";
|
|
31
27
|
import {
|
|
28
|
+
ProjectionLedgerLagManager,
|
|
32
29
|
appendLifecycleEventsSerialized,
|
|
33
30
|
drainPendingLifecycleLedgerForSync,
|
|
34
31
|
drainPendingLifecycleLedgerIfAny,
|
|
32
|
+
formatProjectionAge,
|
|
35
33
|
readAllLifecycleEventsFromLedger,
|
|
36
34
|
readAllLifecycleEventsFromLedgerBuffer,
|
|
37
35
|
readBoundedLifecycleEventsFromLedger,
|
|
38
36
|
readMaybeEncryptedLines,
|
|
39
37
|
readMemoryActionEventRowsFromLines,
|
|
38
|
+
readProjectionRebuiltAt,
|
|
40
39
|
serializeLifecycleAppendPayload
|
|
41
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-4VXGRIH6.js";
|
|
42
41
|
import {
|
|
43
42
|
namespaceIdentityFromToken
|
|
44
43
|
} from "./chunk-EGGE52UU.js";
|
|
44
|
+
import {
|
|
45
|
+
assertMemoryFrontmatterId,
|
|
46
|
+
warnProjectionFallback
|
|
47
|
+
} from "./chunk-ZA53AZND.js";
|
|
45
48
|
import {
|
|
46
49
|
inferMemoryStatus,
|
|
47
50
|
isArchivedMemoryPath,
|
|
48
51
|
toMemoryPathRel
|
|
49
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-7RJUVTVF.js";
|
|
50
53
|
import {
|
|
51
54
|
normalizeProjectionPreview,
|
|
52
55
|
normalizeProjectionTags
|
|
@@ -90,7 +93,6 @@ import {
|
|
|
90
93
|
} from "./chunk-R3DJVOSM.js";
|
|
91
94
|
import {
|
|
92
95
|
markProjectedMemoryPathInvalid,
|
|
93
|
-
openProjectionReadonly,
|
|
94
96
|
readProjectedGovernanceRecord,
|
|
95
97
|
readProjectedMemoryBrowse,
|
|
96
98
|
readProjectedMemoryState,
|
|
@@ -196,29 +198,6 @@ import {
|
|
|
196
198
|
log
|
|
197
199
|
} from "./chunk-3WCASNQZ.js";
|
|
198
200
|
|
|
199
|
-
// src/maintenance/projection-support.ts
|
|
200
|
-
import path from "path";
|
|
201
|
-
function readProjectionRebuiltAt(memoryDir) {
|
|
202
|
-
const db = openProjectionReadonly(memoryDir);
|
|
203
|
-
if (!db) return null;
|
|
204
|
-
try {
|
|
205
|
-
const row = db.prepare("SELECT value FROM meta WHERE key = 'rebuiltAt'").get();
|
|
206
|
-
return typeof row?.value === "string" && row.value.length > 0 ? row.value : null;
|
|
207
|
-
} catch {
|
|
208
|
-
return null;
|
|
209
|
-
} finally {
|
|
210
|
-
db.close();
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
function assertInjectedStorageRooted(label, memoryDir, injected) {
|
|
214
|
-
if (injected && path.resolve(injected.dir) !== path.resolve(memoryDir)) {
|
|
215
|
-
throw new Error(
|
|
216
|
-
`${label}: storage.dir (${injected.dir}) must match memoryDir (${memoryDir})`
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
return injected;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
201
|
// src/storage.ts
|
|
223
202
|
import {
|
|
224
203
|
lstat as lstat3,
|
|
@@ -234,11 +213,11 @@ import {
|
|
|
234
213
|
} from "fs/promises";
|
|
235
214
|
import { appendFileSync, createReadStream, mkdirSync, readFileSync, statSync } from "fs";
|
|
236
215
|
import { createHash as createHash5 } from "crypto";
|
|
237
|
-
import
|
|
216
|
+
import path8 from "path";
|
|
238
217
|
|
|
239
218
|
// src/storage/memory-read-store.ts
|
|
240
219
|
import { lstat, readdir, realpath, stat } from "fs/promises";
|
|
241
|
-
import
|
|
220
|
+
import path from "path";
|
|
242
221
|
|
|
243
222
|
// src/storage/memory-frontmatter-metadata.ts
|
|
244
223
|
var rawFrontmatterByMemory = /* @__PURE__ */ new WeakMap();
|
|
@@ -286,7 +265,7 @@ var MemoryReadStore = class {
|
|
|
286
265
|
if (!/^[a-z][a-z0-9-]{0,63}$/.test(source)) continue;
|
|
287
266
|
let entries;
|
|
288
267
|
try {
|
|
289
|
-
entries = await readdir(
|
|
268
|
+
entries = await readdir(path.join(this.deps.wearablesDir, source));
|
|
290
269
|
} catch (err) {
|
|
291
270
|
if (err.code === "ENOENT") continue;
|
|
292
271
|
throw err;
|
|
@@ -317,7 +296,7 @@ var MemoryReadStore = class {
|
|
|
317
296
|
try {
|
|
318
297
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
319
298
|
for (const entry of entries) {
|
|
320
|
-
const fullPath =
|
|
299
|
+
const fullPath = path.join(dir, entry.name);
|
|
321
300
|
if (entry.isDirectory()) {
|
|
322
301
|
await readDir(fullPath);
|
|
323
302
|
continue;
|
|
@@ -391,7 +370,7 @@ var MemoryReadStore = class {
|
|
|
391
370
|
const subdirs = [];
|
|
392
371
|
for (const entry of entries) {
|
|
393
372
|
if (entry.isSymbolicLink()) continue;
|
|
394
|
-
const fullPath =
|
|
373
|
+
const fullPath = path.join(dir, entry.name);
|
|
395
374
|
if (entry.isDirectory()) {
|
|
396
375
|
subdirs.push(fullPath);
|
|
397
376
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -414,7 +393,7 @@ var MemoryReadStore = class {
|
|
|
414
393
|
}
|
|
415
394
|
async collectActiveMemoryPaths(options) {
|
|
416
395
|
return this.collectContainedMarkdownPaths(
|
|
417
|
-
RECALL_FALLBACK_DIRS.map((dir) =>
|
|
396
|
+
RECALL_FALLBACK_DIRS.map((dir) => path.join(this.deps.baseDir, dir)),
|
|
418
397
|
options?.propagateReadErrors ?? false
|
|
419
398
|
);
|
|
420
399
|
}
|
|
@@ -509,7 +488,7 @@ var MemoryReadStore = class {
|
|
|
509
488
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
510
489
|
const subdirs = [];
|
|
511
490
|
for (const entry of entries) {
|
|
512
|
-
const fullPath =
|
|
491
|
+
const fullPath = path.join(dir, entry.name);
|
|
513
492
|
if (entry.isDirectory()) {
|
|
514
493
|
subdirs.push(fullPath);
|
|
515
494
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -543,11 +522,11 @@ var MemoryReadStore = class {
|
|
|
543
522
|
content: parsed.content
|
|
544
523
|
}, raw);
|
|
545
524
|
}
|
|
546
|
-
const normalizedPath = filePath.split(
|
|
525
|
+
const normalizedPath = filePath.split(path.sep).join("/");
|
|
547
526
|
if (normalizedPath.includes("/entities/") && filePath.endsWith(".md")) {
|
|
548
527
|
const entity = parseEntityFile(raw, this.deps.entitySchemas);
|
|
549
528
|
if (!entity.name) return null;
|
|
550
|
-
const nameWithoutExt =
|
|
529
|
+
const nameWithoutExt = path.basename(filePath, ".md");
|
|
551
530
|
const fileMtime = entity.updated || await stat(filePath).then((s) => s.mtime.toISOString()).catch(() => (/* @__PURE__ */ new Date(0)).toISOString());
|
|
552
531
|
return {
|
|
553
532
|
path: filePath,
|
|
@@ -731,7 +710,7 @@ var MemoryReadStore = class {
|
|
|
731
710
|
const questions = [];
|
|
732
711
|
for (const file of files) {
|
|
733
712
|
if (!file.endsWith(".md")) continue;
|
|
734
|
-
const filePath =
|
|
713
|
+
const filePath = path.join(this.deps.questionsDir, file);
|
|
735
714
|
const raw = await readMaybeEncryptedFile(filePath, this.deps._secureStoreKey, this.deps.baseDir);
|
|
736
715
|
const parsed = this.deps.parseQuestionFile(raw, filePath);
|
|
737
716
|
if (parsed) {
|
|
@@ -1435,7 +1414,7 @@ function selfDeps(self) {
|
|
|
1435
1414
|
|
|
1436
1415
|
// src/storage/entity-store.ts
|
|
1437
1416
|
import { readdir as readdir2, unlink } from "fs/promises";
|
|
1438
|
-
import
|
|
1417
|
+
import path2 from "path";
|
|
1439
1418
|
var EntityStore = class {
|
|
1440
1419
|
constructor(deps) {
|
|
1441
1420
|
this.deps = deps;
|
|
@@ -1455,7 +1434,7 @@ var EntityStore = class {
|
|
|
1455
1434
|
async readEntityForMutation(name, method, historicalIds) {
|
|
1456
1435
|
const canonical = resolveHistoricalEntityCanonicalId(name, historicalIds);
|
|
1457
1436
|
for (const candidate of canonical === name ? [name] : [canonical, name]) {
|
|
1458
|
-
const filePath =
|
|
1437
|
+
const filePath = path2.join(this.deps.entitiesDir, `${candidate}.md`);
|
|
1459
1438
|
try {
|
|
1460
1439
|
const entity = parseEntityFile(await this.deps.readStorageSecureFile(filePath), this.deps.entitySchemas);
|
|
1461
1440
|
return { filePath, entity };
|
|
@@ -1480,7 +1459,7 @@ var EntityStore = class {
|
|
|
1480
1459
|
* `mutate` returns false to skip the write. Resolves true when written.
|
|
1481
1460
|
*/
|
|
1482
1461
|
async mutateEntityFile(name, method, mutate) {
|
|
1483
|
-
const stateDir =
|
|
1462
|
+
const stateDir = path2.join(this.deps.baseDir, "state");
|
|
1484
1463
|
return withEntityCanonicalMutationLock(stateDir, async () => {
|
|
1485
1464
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1486
1465
|
const idsAtResolve = this.deps.currentHistoricalIds();
|
|
@@ -1535,7 +1514,7 @@ var EntityStore = class {
|
|
|
1535
1514
|
async writeEntity(name, type, facts, options = {}) {
|
|
1536
1515
|
await this.deps.ensureDirectories();
|
|
1537
1516
|
return withEntityCanonicalMutationLock(
|
|
1538
|
-
|
|
1517
|
+
path2.join(this.deps.baseDir, "state"),
|
|
1539
1518
|
() => this.writeEntityUnlocked(name, type, facts, options)
|
|
1540
1519
|
);
|
|
1541
1520
|
}
|
|
@@ -1556,7 +1535,7 @@ var EntityStore = class {
|
|
|
1556
1535
|
log.debug(`fuzzy match: "${normalized}" \u2192 existing "${match}"`);
|
|
1557
1536
|
normalized = match;
|
|
1558
1537
|
}
|
|
1559
|
-
const filePath =
|
|
1538
|
+
const filePath = path2.join(this.deps.entitiesDir, `${normalized}.md`);
|
|
1560
1539
|
let entity = {
|
|
1561
1540
|
name,
|
|
1562
1541
|
type,
|
|
@@ -1667,7 +1646,7 @@ var EntityStore = class {
|
|
|
1667
1646
|
/** Re-serialize every entity file into the compiled-truth timeline shape. */
|
|
1668
1647
|
async migrateEntityFilesToCompiledTruthTimeline() {
|
|
1669
1648
|
const entityNames = await this.listEntityNames();
|
|
1670
|
-
const stateDir =
|
|
1649
|
+
const stateDir = path2.join(this.deps.baseDir, "state");
|
|
1671
1650
|
let migrated = 0;
|
|
1672
1651
|
for (const entityName of entityNames) {
|
|
1673
1652
|
const wrote = await withEntityCanonicalMutationLock(stateDir, async () => {
|
|
@@ -1694,12 +1673,12 @@ var EntityStore = class {
|
|
|
1694
1673
|
*/
|
|
1695
1674
|
async updateEntitySynthesis(name, synthesis, options = {}) {
|
|
1696
1675
|
return withEntityCanonicalMutationLock(
|
|
1697
|
-
|
|
1676
|
+
path2.join(this.deps.baseDir, "state"),
|
|
1698
1677
|
() => this.updateEntitySynthesisUnlocked(name, synthesis, options)
|
|
1699
1678
|
);
|
|
1700
1679
|
}
|
|
1701
1680
|
async updateEntitySynthesisUnlocked(name, synthesis, options = {}) {
|
|
1702
|
-
const filePath =
|
|
1681
|
+
const filePath = path2.join(this.deps.entitiesDir, `${name}.md`);
|
|
1703
1682
|
let entity;
|
|
1704
1683
|
try {
|
|
1705
1684
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
@@ -1752,7 +1731,7 @@ var EntityStore = class {
|
|
|
1752
1731
|
const results = await Promise.all(
|
|
1753
1732
|
batch.map(async (entry) => {
|
|
1754
1733
|
try {
|
|
1755
|
-
return await this.deps.readStorageSecureFile(
|
|
1734
|
+
return await this.deps.readStorageSecureFile(path2.join(this.deps.entitiesDir, entry));
|
|
1756
1735
|
} catch (err) {
|
|
1757
1736
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
1758
1737
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -1826,7 +1805,7 @@ ${rows.join("\n")}
|
|
|
1826
1805
|
*/
|
|
1827
1806
|
async mergeFragmentedEntities() {
|
|
1828
1807
|
return withEntityCanonicalMutationLock(
|
|
1829
|
-
|
|
1808
|
+
path2.join(this.deps.baseDir, "state"),
|
|
1830
1809
|
() => this.mergeFragmentedEntitiesUnlocked()
|
|
1831
1810
|
);
|
|
1832
1811
|
}
|
|
@@ -1871,7 +1850,7 @@ ${rows.join("\n")}
|
|
|
1871
1850
|
extraSections: []
|
|
1872
1851
|
};
|
|
1873
1852
|
for (const file of files) {
|
|
1874
|
-
const filePath =
|
|
1853
|
+
const filePath = path2.join(this.deps.entitiesDir, file);
|
|
1875
1854
|
try {
|
|
1876
1855
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
1877
1856
|
const parsed = parseEntityFile(content, this.deps.entitySchemas);
|
|
@@ -2002,11 +1981,11 @@ ${rows.join("\n")}
|
|
|
2002
1981
|
}
|
|
2003
1982
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2004
1983
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2005
|
-
const canonicalPath =
|
|
1984
|
+
const canonicalPath = path2.join(this.deps.entitiesDir, `${canonical}.md`);
|
|
2006
1985
|
await this.deps.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.deps.entitySchemas));
|
|
2007
1986
|
this.deps.bumpEntityMutationVersion();
|
|
2008
1987
|
for (const file of files) {
|
|
2009
|
-
const filePath =
|
|
1988
|
+
const filePath = path2.join(this.deps.entitiesDir, file);
|
|
2010
1989
|
if (filePath !== canonicalPath) {
|
|
2011
1990
|
try {
|
|
2012
1991
|
await unlink(filePath);
|
|
@@ -2026,7 +2005,7 @@ ${rows.join("\n")}
|
|
|
2026
2005
|
|
|
2027
2006
|
// src/storage/identity-continuity-store.ts
|
|
2028
2007
|
import { readdir as readdir3 } from "fs/promises";
|
|
2029
|
-
import
|
|
2008
|
+
import path3 from "path";
|
|
2030
2009
|
var IdentityContinuityStore = class {
|
|
2031
2010
|
constructor(deps) {
|
|
2032
2011
|
this.deps = deps;
|
|
@@ -2051,7 +2030,7 @@ var IdentityContinuityStore = class {
|
|
|
2051
2030
|
const date = nowIso.slice(0, 10);
|
|
2052
2031
|
const id = this.deps.generateId("incident");
|
|
2053
2032
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
2054
|
-
const filePath =
|
|
2033
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);
|
|
2055
2034
|
await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
2056
2035
|
return { ...incident, filePath };
|
|
2057
2036
|
}
|
|
@@ -2064,7 +2043,7 @@ var IdentityContinuityStore = class {
|
|
|
2064
2043
|
const incidents = [];
|
|
2065
2044
|
for (const file of candidates) {
|
|
2066
2045
|
if (incidents.length >= cappedLimit) break;
|
|
2067
|
-
const filePath =
|
|
2046
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, file);
|
|
2068
2047
|
try {
|
|
2069
2048
|
const raw = await this.deps.readStorageSecureFile(filePath);
|
|
2070
2049
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -2095,7 +2074,7 @@ var IdentityContinuityStore = class {
|
|
|
2095
2074
|
await this.deps.ensureDirectories();
|
|
2096
2075
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2097
2076
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2098
|
-
const filePath =
|
|
2077
|
+
const filePath = path3.join(dir, `${safeKey}.md`);
|
|
2099
2078
|
await this.deps.writeStorageSecureFile(filePath, content);
|
|
2100
2079
|
return filePath;
|
|
2101
2080
|
}
|
|
@@ -2103,7 +2082,7 @@ var IdentityContinuityStore = class {
|
|
|
2103
2082
|
try {
|
|
2104
2083
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2105
2084
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2106
|
-
return await this.deps.readStorageSecureFile(
|
|
2085
|
+
return await this.deps.readStorageSecureFile(path3.join(dir, `${safeKey}.md`));
|
|
2107
2086
|
} catch (err) {
|
|
2108
2087
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
2109
2088
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -2159,12 +2138,12 @@ var IdentityContinuityStore = class {
|
|
|
2159
2138
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
2160
2139
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
2161
2140
|
if (directMatch) {
|
|
2162
|
-
const directPath =
|
|
2141
|
+
const directPath = path3.join(this.deps.identityIncidentsDir, directMatch);
|
|
2163
2142
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
2164
2143
|
if (parsed?.id === id) return directPath;
|
|
2165
2144
|
}
|
|
2166
2145
|
for (const fileName of fileNames) {
|
|
2167
|
-
const filePath =
|
|
2146
|
+
const filePath = path3.join(this.deps.identityIncidentsDir, fileName);
|
|
2168
2147
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
2169
2148
|
if (parsed?.id === id) return filePath;
|
|
2170
2149
|
}
|
|
@@ -2192,7 +2171,7 @@ import {
|
|
|
2192
2171
|
unlink as unlink2,
|
|
2193
2172
|
writeFile
|
|
2194
2173
|
} from "fs/promises";
|
|
2195
|
-
import
|
|
2174
|
+
import path4 from "path";
|
|
2196
2175
|
import { z } from "zod";
|
|
2197
2176
|
var ENTITY_CANONICAL_ID_MIGRATION_VERSION = 1;
|
|
2198
2177
|
var ENTITY_CANONICAL_ID_MIGRATION_LOCK_STALE_MS = 6e4;
|
|
@@ -2226,11 +2205,11 @@ async function fingerprintPath(filePath) {
|
|
|
2226
2205
|
async function getFingerprint(baseDir, entitiesDir, getEntityMutationVersion) {
|
|
2227
2206
|
const [entityFingerprint, aliasFingerprint, reconcileFingerprint, consumingFingerprint] = await Promise.all([
|
|
2228
2207
|
fingerprintPath(entitiesDir),
|
|
2229
|
-
fingerprintPath(
|
|
2230
|
-
fingerprintPath(
|
|
2208
|
+
fingerprintPath(path4.join(baseDir, "config", "aliases.json")),
|
|
2209
|
+
fingerprintPath(path4.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_MARKER)),
|
|
2231
2210
|
// A `.consuming` generation stranded by a crashed PEER process must also
|
|
2232
2211
|
// re-invoke a live runner whose cached fingerprint predates it.
|
|
2233
|
-
fingerprintPath(
|
|
2212
|
+
fingerprintPath(path4.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER))
|
|
2234
2213
|
]);
|
|
2235
2214
|
return [entityFingerprint, aliasFingerprint, reconcileFingerprint, consumingFingerprint, getEntityMutationVersion()].join(":");
|
|
2236
2215
|
}
|
|
@@ -2249,8 +2228,8 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2249
2228
|
const roots = [
|
|
2250
2229
|
entitiesDir,
|
|
2251
2230
|
stateDir,
|
|
2252
|
-
...RECALL_FALLBACK_DIRS.map((directory) =>
|
|
2253
|
-
|
|
2231
|
+
...RECALL_FALLBACK_DIRS.map((directory) => path4.join(baseDir, directory)),
|
|
2232
|
+
path4.join(baseDir, "cold"),
|
|
2254
2233
|
archiveDir
|
|
2255
2234
|
];
|
|
2256
2235
|
for (const root of roots) {
|
|
@@ -2268,7 +2247,7 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2268
2247
|
}
|
|
2269
2248
|
}
|
|
2270
2249
|
function statePath(deps) {
|
|
2271
|
-
return
|
|
2250
|
+
return path4.join(deps.stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE);
|
|
2272
2251
|
}
|
|
2273
2252
|
async function assertSafeMigrationStateFile(deps) {
|
|
2274
2253
|
const migrationStatePath = statePath(deps);
|
|
@@ -2311,7 +2290,7 @@ async function assertSafeTombstoneFile(deps, tombstonePath) {
|
|
|
2311
2290
|
return true;
|
|
2312
2291
|
}
|
|
2313
2292
|
function lockPath(deps) {
|
|
2314
|
-
return
|
|
2293
|
+
return path4.join(deps.stateDir, "entity-canonical-id-migration.lock");
|
|
2315
2294
|
}
|
|
2316
2295
|
async function readState(deps) {
|
|
2317
2296
|
await assertSafeMigrationStateFile(deps);
|
|
@@ -2408,7 +2387,7 @@ async function readSafeEntityEntries(entitiesDir) {
|
|
|
2408
2387
|
}
|
|
2409
2388
|
const entries = await readdir4(entitiesDir);
|
|
2410
2389
|
for (const entry of entries) {
|
|
2411
|
-
await assertNotSymlink(
|
|
2390
|
+
await assertNotSymlink(path4.join(entitiesDir, entry), entry);
|
|
2412
2391
|
}
|
|
2413
2392
|
return entries;
|
|
2414
2393
|
}
|
|
@@ -2470,7 +2449,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
2470
2449
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
2471
2450
|
let rewroteAny = false;
|
|
2472
2451
|
for (const memory of [...hotMemories, ...coldMemories, ...archivedMemories]) {
|
|
2473
|
-
const memoryPath =
|
|
2452
|
+
const memoryPath = path4.resolve(memory.path);
|
|
2474
2453
|
if (seenPaths.has(memoryPath)) continue;
|
|
2475
2454
|
seenPaths.add(memoryPath);
|
|
2476
2455
|
const previousEntityRef = memory.frontmatter.entityRef;
|
|
@@ -2502,7 +2481,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
2502
2481
|
latestCanonicalId
|
|
2503
2482
|
);
|
|
2504
2483
|
rewroteAny = true;
|
|
2505
|
-
rewroteColdMemory ||= latestMemory.path.includes(`${
|
|
2484
|
+
rewroteColdMemory ||= latestMemory.path.includes(`${path4.sep}cold${path4.sep}`);
|
|
2506
2485
|
}
|
|
2507
2486
|
if (!rewroteAny) return { rewroteColdMemory };
|
|
2508
2487
|
}
|
|
@@ -2541,7 +2520,7 @@ function rewriteTombstoneLine(line, mappings, normalizedMappings) {
|
|
|
2541
2520
|
return changed ? JSON.stringify(tombstone) : line;
|
|
2542
2521
|
}
|
|
2543
2522
|
async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
2544
|
-
const tombstonePath =
|
|
2523
|
+
const tombstonePath = path4.join(deps.stateDir, "tombstones.jsonl");
|
|
2545
2524
|
const normalizedMappings = /* @__PURE__ */ new Map();
|
|
2546
2525
|
for (const [legacyId, canonicalId] of Object.entries(mappings)) {
|
|
2547
2526
|
const normalizedLegacyId = normalizeSupersessionKey(legacyId);
|
|
@@ -2550,7 +2529,7 @@ async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
|
2550
2529
|
}
|
|
2551
2530
|
}
|
|
2552
2531
|
await withHeldFileLock(
|
|
2553
|
-
|
|
2532
|
+
path4.join(deps.stateDir, "tombstones.lock"),
|
|
2554
2533
|
{
|
|
2555
2534
|
staleMs: TOMBSTONE_LOCK_STALE_MS,
|
|
2556
2535
|
maxWaitMs: TOMBSTONE_LOCK_MAX_WAIT_MS
|
|
@@ -2789,8 +2768,8 @@ async function migrateLegacyEntityCanonicalIds(deps) {
|
|
|
2789
2768
|
if (!acquired) throw new Error("Timed out waiting for active entity canonical-id migration.");
|
|
2790
2769
|
await deps.validateMemoryScanRoots?.();
|
|
2791
2770
|
await readSafeEntityEntries(deps.entitiesDir);
|
|
2792
|
-
const reconcileMarkerPath =
|
|
2793
|
-
const consumingMarkerPath =
|
|
2771
|
+
const reconcileMarkerPath = path4.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER);
|
|
2772
|
+
const consumingMarkerPath = path4.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER);
|
|
2794
2773
|
let reconcileRequested = await fileExists(consumingMarkerPath);
|
|
2795
2774
|
if (await fileExists(reconcileMarkerPath)) {
|
|
2796
2775
|
try {
|
|
@@ -3202,9 +3181,9 @@ function decodeYamlScalar(value) {
|
|
|
3202
3181
|
}
|
|
3203
3182
|
|
|
3204
3183
|
// src/orchestration/qmd-result-resolver.ts
|
|
3205
|
-
import
|
|
3184
|
+
import path5 from "path";
|
|
3206
3185
|
function qmdCollectionPathParts(resultPath) {
|
|
3207
|
-
if (!resultPath ||
|
|
3186
|
+
if (!resultPath || path5.isAbsolute(resultPath)) return null;
|
|
3208
3187
|
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3209
3188
|
const slashIndex = normalized.indexOf("/");
|
|
3210
3189
|
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
@@ -3217,9 +3196,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3217
3196
|
}
|
|
3218
3197
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3219
3198
|
const candidates = /* @__PURE__ */ new Set();
|
|
3220
|
-
const storageRoot =
|
|
3199
|
+
const storageRoot = path5.resolve(storageDir);
|
|
3221
3200
|
const addCandidate = (candidate) => {
|
|
3222
|
-
const resolved =
|
|
3201
|
+
const resolved = path5.resolve(candidate);
|
|
3223
3202
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3224
3203
|
candidates.add(resolved);
|
|
3225
3204
|
}
|
|
@@ -3227,18 +3206,18 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3227
3206
|
const addRelativeCandidates = (relativePath) => {
|
|
3228
3207
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3229
3208
|
if (!normalized) return;
|
|
3230
|
-
addCandidate(
|
|
3209
|
+
addCandidate(path5.join(storageRoot, normalized));
|
|
3231
3210
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3232
|
-
addCandidate(
|
|
3211
|
+
addCandidate(path5.join(storageRoot, "facts", normalized));
|
|
3233
3212
|
}
|
|
3234
3213
|
};
|
|
3235
|
-
if (
|
|
3214
|
+
if (path5.isAbsolute(resultPath)) {
|
|
3236
3215
|
addCandidate(resultPath);
|
|
3237
|
-
const relative2 =
|
|
3238
|
-
if (relative2 && !relative2.startsWith("..") && !
|
|
3239
|
-
const normalized = relative2.split(
|
|
3216
|
+
const relative2 = path5.relative(storageRoot, path5.resolve(resultPath));
|
|
3217
|
+
if (relative2 && !relative2.startsWith("..") && !path5.isAbsolute(relative2)) {
|
|
3218
|
+
const normalized = relative2.split(path5.sep).join("/");
|
|
3240
3219
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3241
|
-
addCandidate(
|
|
3220
|
+
addCandidate(path5.join(storageRoot, "facts", normalized));
|
|
3242
3221
|
}
|
|
3243
3222
|
}
|
|
3244
3223
|
} else {
|
|
@@ -3273,7 +3252,7 @@ var QmdResultResolver = class {
|
|
|
3273
3252
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
3274
3253
|
const addStorage = (storage) => {
|
|
3275
3254
|
const storageDir = storageDirOrNull(storage);
|
|
3276
|
-
const storageKey = storageDir ?
|
|
3255
|
+
const storageKey = storageDir ? path5.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
3277
3256
|
if (seenStorageDirs.has(storageKey)) return;
|
|
3278
3257
|
seenStorageDirs.add(storageKey);
|
|
3279
3258
|
storages.push(storage);
|
|
@@ -3303,7 +3282,7 @@ var QmdResultResolver = class {
|
|
|
3303
3282
|
continue;
|
|
3304
3283
|
}
|
|
3305
3284
|
try {
|
|
3306
|
-
const coldRoot =
|
|
3285
|
+
const coldRoot = path5.join(storageDir, "cold");
|
|
3307
3286
|
for (const candidate of qmdResultPathCandidates(
|
|
3308
3287
|
coldRoot,
|
|
3309
3288
|
parts.relativePath
|
|
@@ -3362,9 +3341,9 @@ var QmdResultResolver = class {
|
|
|
3362
3341
|
error: err.message
|
|
3363
3342
|
});
|
|
3364
3343
|
}
|
|
3365
|
-
if (!
|
|
3344
|
+
if (!path5.isAbsolute(resultPath)) return null;
|
|
3366
3345
|
}
|
|
3367
|
-
if (
|
|
3346
|
+
if (path5.isAbsolute(resultPath)) {
|
|
3368
3347
|
if (!fallbackStorageDir) {
|
|
3369
3348
|
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
3370
3349
|
}
|
|
@@ -3404,7 +3383,7 @@ var QmdResultResolver = class {
|
|
|
3404
3383
|
);
|
|
3405
3384
|
if (!memory) return null;
|
|
3406
3385
|
let ownerNamespace = null;
|
|
3407
|
-
if (
|
|
3386
|
+
if (path5.isAbsolute(memory.path)) {
|
|
3408
3387
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
3409
3388
|
memory.path,
|
|
3410
3389
|
fallbackStorage,
|
|
@@ -3428,17 +3407,17 @@ var QmdResultResolver = class {
|
|
|
3428
3407
|
};
|
|
3429
3408
|
}
|
|
3430
3409
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
3431
|
-
const resolvedPath =
|
|
3410
|
+
const resolvedPath = path5.resolve(resultPath);
|
|
3432
3411
|
const config = this.getConfig();
|
|
3433
|
-
const memoryRoot =
|
|
3434
|
-
const namespacesRoot =
|
|
3412
|
+
const memoryRoot = path5.resolve(config.memoryDir);
|
|
3413
|
+
const namespacesRoot = path5.join(memoryRoot, "namespaces");
|
|
3435
3414
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
3436
3415
|
const matches = [];
|
|
3437
3416
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
3438
3417
|
const maybeAddStorage = (storage, namespace) => {
|
|
3439
3418
|
const storageDir = storageDirOrNull(storage);
|
|
3440
3419
|
if (!storageDir) return;
|
|
3441
|
-
const candidateRoot =
|
|
3420
|
+
const candidateRoot = path5.resolve(storageDir);
|
|
3442
3421
|
if (seenDirs.has(candidateRoot)) return;
|
|
3443
3422
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
3444
3423
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -3456,7 +3435,7 @@ var QmdResultResolver = class {
|
|
|
3456
3435
|
candidateNamespaces.add(ns);
|
|
3457
3436
|
}
|
|
3458
3437
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
3459
|
-
const relativeToNamespaces =
|
|
3438
|
+
const relativeToNamespaces = path5.relative(namespacesRoot, resolvedPath);
|
|
3460
3439
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
3461
3440
|
if (namespaceSegment) {
|
|
3462
3441
|
candidateNamespaces.add(
|
|
@@ -4105,7 +4084,7 @@ function fuseDay(date, inputs, options = {}) {
|
|
|
4105
4084
|
|
|
4106
4085
|
// src/wearables/fusion/store.ts
|
|
4107
4086
|
import { createHash as createHash2 } from "crypto";
|
|
4108
|
-
import * as
|
|
4087
|
+
import * as path6 from "path";
|
|
4109
4088
|
var FUSION_KIND = "wearable-fusion";
|
|
4110
4089
|
function hashFusionBody(conversations) {
|
|
4111
4090
|
return createHash2("sha256").update(JSON.stringify(conversations), "utf-8").digest("hex");
|
|
@@ -4292,7 +4271,7 @@ var FusionArtifactStore = class {
|
|
|
4292
4271
|
`invalid wearable fusion date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
4293
4272
|
);
|
|
4294
4273
|
}
|
|
4295
|
-
return
|
|
4274
|
+
return path6.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);
|
|
4296
4275
|
}
|
|
4297
4276
|
async writeFusedDay(date, serialized) {
|
|
4298
4277
|
const filePath = this.fusedDayPath(date);
|
|
@@ -4329,7 +4308,7 @@ var FusionArtifactStore = class {
|
|
|
4329
4308
|
}
|
|
4330
4309
|
/** List dates with stored fused artifacts, newest first. */
|
|
4331
4310
|
async listFusedDays() {
|
|
4332
|
-
const fusionDir =
|
|
4311
|
+
const fusionDir = path6.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4333
4312
|
await this.assertPathContained(fusionDir);
|
|
4334
4313
|
let entries;
|
|
4335
4314
|
try {
|
|
@@ -4373,10 +4352,10 @@ var FusionArtifactStore = class {
|
|
|
4373
4352
|
try {
|
|
4374
4353
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4375
4354
|
} catch {
|
|
4376
|
-
rootReal =
|
|
4355
|
+
rootReal = path6.resolve(this.memoryDir);
|
|
4377
4356
|
}
|
|
4378
4357
|
await this.assertNoEscape(rootReal, this.wearablesDir);
|
|
4379
|
-
await this.assertNoEscape(rootReal,
|
|
4358
|
+
await this.assertNoEscape(rootReal, path6.dirname(targetPath));
|
|
4380
4359
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4381
4360
|
await this.assertFusionDirNotSymlinked();
|
|
4382
4361
|
}
|
|
@@ -4390,7 +4369,7 @@ var FusionArtifactStore = class {
|
|
|
4390
4369
|
* (a fresh write creates a real directory lexically under the root).
|
|
4391
4370
|
*/
|
|
4392
4371
|
async assertFusionDirNotSymlinked() {
|
|
4393
|
-
const fusionDir =
|
|
4372
|
+
const fusionDir = path6.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4394
4373
|
let stat3;
|
|
4395
4374
|
try {
|
|
4396
4375
|
stat3 = await this.io.lstat(fusionDir);
|
|
@@ -4526,7 +4505,7 @@ function reconstructFusionInputs(date, dayTranscripts) {
|
|
|
4526
4505
|
|
|
4527
4506
|
// src/meetings/store.ts
|
|
4528
4507
|
import { createHash as createHash3 } from "crypto";
|
|
4529
|
-
import * as
|
|
4508
|
+
import * as path7 from "path";
|
|
4530
4509
|
var MEETINGS_DIR_NAME = "meetings";
|
|
4531
4510
|
var MEETING_KIND = "meeting";
|
|
4532
4511
|
var MEETING_FORMAT_VERSION = 1;
|
|
@@ -4695,7 +4674,7 @@ var MeetingRecordStore = class {
|
|
|
4695
4674
|
constructor(memoryDir, io) {
|
|
4696
4675
|
this.memoryDir = memoryDir;
|
|
4697
4676
|
this.io = io;
|
|
4698
|
-
this.meetingsDir =
|
|
4677
|
+
this.meetingsDir = path7.join(memoryDir, MEETINGS_DIR_NAME);
|
|
4699
4678
|
}
|
|
4700
4679
|
memoryDir;
|
|
4701
4680
|
io;
|
|
@@ -4711,7 +4690,7 @@ var MeetingRecordStore = class {
|
|
|
4711
4690
|
if (idDate !== date) {
|
|
4712
4691
|
throw new Error(`meeting id '${id}' does not belong to date '${date}'`);
|
|
4713
4692
|
}
|
|
4714
|
-
return
|
|
4693
|
+
return path7.join(this.meetingsDir, date, `${id}.md`);
|
|
4715
4694
|
}
|
|
4716
4695
|
/** Idempotently persist a record: skip the write when contentHash is unchanged. */
|
|
4717
4696
|
async saveMeetingRecord(record) {
|
|
@@ -4742,7 +4721,7 @@ var MeetingRecordStore = class {
|
|
|
4742
4721
|
if (!isValidTranscriptDate(date)) {
|
|
4743
4722
|
throw new Error(`invalid meeting date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
4744
4723
|
}
|
|
4745
|
-
const dayDir =
|
|
4724
|
+
const dayDir = path7.join(this.meetingsDir, date);
|
|
4746
4725
|
await this.assertPathContained(dayDir);
|
|
4747
4726
|
let entries;
|
|
4748
4727
|
try {
|
|
@@ -4810,10 +4789,10 @@ var MeetingRecordStore = class {
|
|
|
4810
4789
|
try {
|
|
4811
4790
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4812
4791
|
} catch {
|
|
4813
|
-
rootReal =
|
|
4792
|
+
rootReal = path7.resolve(this.memoryDir);
|
|
4814
4793
|
}
|
|
4815
4794
|
await this.assertNoEscape(rootReal, this.meetingsDir);
|
|
4816
|
-
await this.assertNoEscape(rootReal,
|
|
4795
|
+
await this.assertNoEscape(rootReal, path7.dirname(targetPath));
|
|
4817
4796
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4818
4797
|
await this.assertNotSymlink(this.meetingsDir, "directory");
|
|
4819
4798
|
const dayDir = this.dayDirWithin(targetPath);
|
|
@@ -4823,11 +4802,11 @@ var MeetingRecordStore = class {
|
|
|
4823
4802
|
/** The `<meetings>/<date>` directory on the path to `targetPath`, or null when
|
|
4824
4803
|
* `targetPath` is the meetings root itself. */
|
|
4825
4804
|
dayDirWithin(targetPath) {
|
|
4826
|
-
const rel =
|
|
4827
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
4828
|
-
const first = rel.split(
|
|
4805
|
+
const rel = path7.relative(this.meetingsDir, targetPath);
|
|
4806
|
+
if (rel === "" || rel.startsWith("..") || path7.isAbsolute(rel)) return null;
|
|
4807
|
+
const first = rel.split(path7.sep)[0];
|
|
4829
4808
|
if (first === void 0 || first.length === 0) return null;
|
|
4830
|
-
return
|
|
4809
|
+
return path7.join(this.meetingsDir, first);
|
|
4831
4810
|
}
|
|
4832
4811
|
async assertNotSymlink(target, kind) {
|
|
4833
4812
|
let stat3;
|
|
@@ -4838,7 +4817,7 @@ var MeetingRecordStore = class {
|
|
|
4838
4817
|
throw err;
|
|
4839
4818
|
}
|
|
4840
4819
|
if (stat3.isSymbolicLink) {
|
|
4841
|
-
const label =
|
|
4820
|
+
const label = path7.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;
|
|
4842
4821
|
throw new Error(
|
|
4843
4822
|
`meetings ${kind} '${label}' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`
|
|
4844
4823
|
);
|
|
@@ -5880,17 +5859,17 @@ function inferEntityTypeFromContent(content) {
|
|
|
5880
5859
|
}
|
|
5881
5860
|
var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set(["company", "other", "person", "place", "project", "tool", "topic"]);
|
|
5882
5861
|
function inferEntityTypeFromFilename(pathRel) {
|
|
5883
|
-
const basename =
|
|
5862
|
+
const basename = path8.basename(pathRel, ".md").toLowerCase();
|
|
5884
5863
|
const separator = basename.indexOf("-");
|
|
5885
5864
|
if (separator <= 0) return void 0;
|
|
5886
5865
|
const candidate = basename.slice(0, separator);
|
|
5887
5866
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
5888
5867
|
}
|
|
5889
5868
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
5890
|
-
const normalizedPath = pathRel.split(
|
|
5869
|
+
const normalizedPath = pathRel.split(path8.sep).join("/");
|
|
5891
5870
|
let normalizedFrontmatter = frontmatter;
|
|
5892
5871
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
5893
|
-
const basename =
|
|
5872
|
+
const basename = path8.basename(pathRel, ".md");
|
|
5894
5873
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
5895
5874
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
5896
5875
|
normalizedFrontmatter = {
|
|
@@ -6362,7 +6341,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6362
6341
|
entitySchemas;
|
|
6363
6342
|
knowledgeIndexCache = null;
|
|
6364
6343
|
artifactIndexCache = null;
|
|
6365
|
-
|
|
6344
|
+
projectionLedgerLagManager = new ProjectionLedgerLagManager();
|
|
6366
6345
|
static KNOWLEDGE_INDEX_CACHE_TTL_MS = 6e5;
|
|
6367
6346
|
// 10 minutes (entity mutations invalidate)
|
|
6368
6347
|
/** Read by storage/memory-read-store.ts (decomposition). */
|
|
@@ -6538,8 +6517,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6538
6517
|
}
|
|
6539
6518
|
/** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */
|
|
6540
6519
|
isStateFilePath(filePath) {
|
|
6541
|
-
const rel =
|
|
6542
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
6520
|
+
const rel = path8.relative(this.stateDir, path8.resolve(filePath));
|
|
6521
|
+
return rel === "" || !rel.startsWith("..") && !path8.isAbsolute(rel);
|
|
6543
6522
|
}
|
|
6544
6523
|
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
6545
6524
|
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
@@ -6656,8 +6635,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6656
6635
|
* /srv/cold/remnic), skipping the patch and stranding a stale hot entry.
|
|
6657
6636
|
*/
|
|
6658
6637
|
isColdOrArchiveTierPath(p) {
|
|
6659
|
-
const rel =
|
|
6660
|
-
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${
|
|
6638
|
+
const rel = path8.relative(this.baseDir, p);
|
|
6639
|
+
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${path8.sep}`) || rel.startsWith(`archive${path8.sep}`);
|
|
6661
6640
|
}
|
|
6662
6641
|
/**
|
|
6663
6642
|
* Mark the secure-store as required for this storage instance.
|
|
@@ -6744,7 +6723,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6744
6723
|
void 0,
|
|
6745
6724
|
this.baseDir
|
|
6746
6725
|
);
|
|
6747
|
-
const rel =
|
|
6726
|
+
const rel = path8.relative(this.baseDir, filePath).split(path8.sep).join("/");
|
|
6748
6727
|
return `${rel}:${version.versionId}`;
|
|
6749
6728
|
} catch (err) {
|
|
6750
6729
|
log.warn(
|
|
@@ -6824,12 +6803,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6824
6803
|
}
|
|
6825
6804
|
identityFilePath(workspaceDir, namespace) {
|
|
6826
6805
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
6827
|
-
if (!rawNamespace) return
|
|
6806
|
+
if (!rawNamespace) return path8.join(workspaceDir, "IDENTITY.md");
|
|
6828
6807
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
6829
|
-
return
|
|
6808
|
+
return path8.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
6830
6809
|
}
|
|
6831
6810
|
versionFilePath(kind) {
|
|
6832
|
-
return
|
|
6811
|
+
return path8.join(this.stateDir, `.${kind}-version.log`);
|
|
6833
6812
|
}
|
|
6834
6813
|
bumpSharedVersion(kind, fallbackMap) {
|
|
6835
6814
|
const filePath = this.versionFilePath(kind);
|
|
@@ -6927,7 +6906,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6927
6906
|
// memories.
|
|
6928
6907
|
// -------------------------------------------------------------------------
|
|
6929
6908
|
get wearablesDir() {
|
|
6930
|
-
return
|
|
6909
|
+
return path8.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
6931
6910
|
}
|
|
6932
6911
|
/**
|
|
6933
6912
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -6943,7 +6922,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6943
6922
|
if (!isValidTranscriptDate(date)) {
|
|
6944
6923
|
throw new Error(`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
6945
6924
|
}
|
|
6946
|
-
return
|
|
6925
|
+
return path8.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
6947
6926
|
}
|
|
6948
6927
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
6949
6928
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -7059,25 +7038,25 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7059
7038
|
});
|
|
7060
7039
|
}
|
|
7061
7040
|
get factsDir() {
|
|
7062
|
-
return
|
|
7041
|
+
return path8.join(this.baseDir, "facts");
|
|
7063
7042
|
}
|
|
7064
7043
|
get correctionsDir() {
|
|
7065
|
-
return
|
|
7044
|
+
return path8.join(this.baseDir, "corrections");
|
|
7066
7045
|
}
|
|
7067
7046
|
get proceduresDir() {
|
|
7068
|
-
return
|
|
7047
|
+
return path8.join(this.baseDir, "procedures");
|
|
7069
7048
|
}
|
|
7070
7049
|
get reasoningTracesDir() {
|
|
7071
|
-
return
|
|
7050
|
+
return path8.join(this.baseDir, "reasoning-traces");
|
|
7072
7051
|
}
|
|
7073
7052
|
get entitiesDir() {
|
|
7074
|
-
return
|
|
7053
|
+
return path8.join(this.baseDir, "entities");
|
|
7075
7054
|
}
|
|
7076
7055
|
resolveEntityFilePath(name) {
|
|
7077
7056
|
if (typeof name !== "string") return null;
|
|
7078
|
-
const filePath =
|
|
7079
|
-
const relative2 =
|
|
7080
|
-
if (relative2 === "" || relative2.startsWith("..") ||
|
|
7057
|
+
const filePath = path8.resolve(this.entitiesDir, `${name}.md`);
|
|
7058
|
+
const relative2 = path8.relative(this.entitiesDir, filePath);
|
|
7059
|
+
if (relative2 === "" || relative2.startsWith("..") || path8.isAbsolute(relative2)) {
|
|
7081
7060
|
return null;
|
|
7082
7061
|
}
|
|
7083
7062
|
return filePath;
|
|
@@ -7092,10 +7071,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7092
7071
|
});
|
|
7093
7072
|
}
|
|
7094
7073
|
assertManagedStoragePath(filePath, method) {
|
|
7095
|
-
const resolved =
|
|
7096
|
-
const base =
|
|
7097
|
-
const rel =
|
|
7098
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
7074
|
+
const resolved = path8.resolve(filePath);
|
|
7075
|
+
const base = path8.resolve(this.baseDir);
|
|
7076
|
+
const rel = path8.relative(base, resolved);
|
|
7077
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path8.sep}`) || path8.isAbsolute(rel)) {
|
|
7099
7078
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
7100
7079
|
}
|
|
7101
7080
|
return resolved;
|
|
@@ -7107,7 +7086,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7107
7086
|
async digestOfflineSyncFile(filePath) {
|
|
7108
7087
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
7109
7088
|
const st = await stat2(target);
|
|
7110
|
-
const relPath =
|
|
7089
|
+
const relPath = path8.relative(this.baseDir, target).split(path8.sep).join("/");
|
|
7111
7090
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
7112
7091
|
const cached = cache.get(relPath);
|
|
7113
7092
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -7168,7 +7147,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7168
7147
|
const bytes = typeof record.bytes === "number" ? record.bytes : NaN;
|
|
7169
7148
|
const sha256 = typeof record.sha256 === "string" ? record.sha256 : "";
|
|
7170
7149
|
const encrypted = record.encrypted === true;
|
|
7171
|
-
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") ||
|
|
7150
|
+
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") || path8.isAbsolute(cachePath) || !Number.isFinite(statBytes) || !Number.isFinite(mtimeMs) || !Number.isFinite(ctimeMs) || !Number.isFinite(bytes) || !/^[a-f0-9]{64}$/i.test(sha256)) {
|
|
7172
7151
|
continue;
|
|
7173
7152
|
}
|
|
7174
7153
|
cache.set(cachePath, { statBytes, mtimeMs, ctimeMs, encrypted, sha256, bytes });
|
|
@@ -7210,7 +7189,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7210
7189
|
const cache = this.offlineSyncDigestCache;
|
|
7211
7190
|
if (!cache) return;
|
|
7212
7191
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
7213
|
-
await mkdir(
|
|
7192
|
+
await mkdir(path8.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
7214
7193
|
await writeFile2(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}
|
|
7215
7194
|
`, "utf-8");
|
|
7216
7195
|
}).catch((err) => {
|
|
@@ -7299,7 +7278,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7299
7278
|
}
|
|
7300
7279
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
7301
7280
|
const writeKey = this.resolveWriteKey();
|
|
7302
|
-
await mkdir(
|
|
7281
|
+
await mkdir(path8.dirname(filePath), { recursive: true });
|
|
7303
7282
|
if (writeKey === null) {
|
|
7304
7283
|
try {
|
|
7305
7284
|
if (await this.isEncryptedFileHeader(filePath)) {
|
|
@@ -7325,13 +7304,13 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7325
7304
|
this.notifyCatalogWriteForPath(filePath);
|
|
7326
7305
|
}
|
|
7327
7306
|
get stateDir() {
|
|
7328
|
-
return
|
|
7307
|
+
return path8.join(this.baseDir, "state");
|
|
7329
7308
|
}
|
|
7330
7309
|
get offlineSyncDigestCachePath() {
|
|
7331
|
-
return
|
|
7310
|
+
return path8.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
7332
7311
|
}
|
|
7333
7312
|
get entitySynthesisQueuePath() {
|
|
7334
|
-
return
|
|
7313
|
+
return path8.join(this.stateDir, "entity-synthesis-queue.json");
|
|
7335
7314
|
}
|
|
7336
7315
|
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
7337
7316
|
/**
|
|
@@ -7341,7 +7320,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7341
7320
|
* helpers are injected into the store).
|
|
7342
7321
|
*/
|
|
7343
7322
|
get tombstonesPath() {
|
|
7344
|
-
return
|
|
7323
|
+
return path8.join(this.stateDir, "tombstones.jsonl");
|
|
7345
7324
|
}
|
|
7346
7325
|
/**
|
|
7347
7326
|
* Configure the tombstone invariant for this storage instance. Installed
|
|
@@ -7638,55 +7617,55 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7638
7617
|
return null;
|
|
7639
7618
|
}
|
|
7640
7619
|
get questionsDir() {
|
|
7641
|
-
return
|
|
7620
|
+
return path8.join(this.baseDir, "questions");
|
|
7642
7621
|
}
|
|
7643
7622
|
get artifactsDir() {
|
|
7644
|
-
return
|
|
7623
|
+
return path8.join(this.baseDir, "artifacts");
|
|
7645
7624
|
}
|
|
7646
7625
|
get identityDir() {
|
|
7647
|
-
return
|
|
7626
|
+
return path8.join(this.baseDir, "identity");
|
|
7648
7627
|
}
|
|
7649
7628
|
get identityAnchorPath() {
|
|
7650
|
-
return
|
|
7629
|
+
return path8.join(this.identityDir, "identity-anchor.md");
|
|
7651
7630
|
}
|
|
7652
7631
|
get identityIncidentsDir() {
|
|
7653
|
-
return
|
|
7632
|
+
return path8.join(this.identityDir, "incidents");
|
|
7654
7633
|
}
|
|
7655
7634
|
get identityAuditsWeeklyDir() {
|
|
7656
|
-
return
|
|
7635
|
+
return path8.join(this.identityDir, "audits", "weekly");
|
|
7657
7636
|
}
|
|
7658
7637
|
get identityAuditsMonthlyDir() {
|
|
7659
|
-
return
|
|
7638
|
+
return path8.join(this.identityDir, "audits", "monthly");
|
|
7660
7639
|
}
|
|
7661
7640
|
get identityImprovementLoopsPath() {
|
|
7662
|
-
return
|
|
7641
|
+
return path8.join(this.identityDir, "improvement-loops.md");
|
|
7663
7642
|
}
|
|
7664
7643
|
get identityReflectionsPath() {
|
|
7665
|
-
return
|
|
7644
|
+
return path8.join(this.identityDir, "reflections.md");
|
|
7666
7645
|
}
|
|
7667
7646
|
get profilePath() {
|
|
7668
|
-
return
|
|
7647
|
+
return path8.join(this.baseDir, "profile.md");
|
|
7669
7648
|
}
|
|
7670
7649
|
get memoryActionsPath() {
|
|
7671
|
-
return
|
|
7650
|
+
return path8.join(this.stateDir, "memory-actions.jsonl");
|
|
7672
7651
|
}
|
|
7673
7652
|
get memoryLifecycleLedgerPath() {
|
|
7674
|
-
return
|
|
7653
|
+
return path8.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
7675
7654
|
}
|
|
7676
7655
|
get compressionGuidelinesPath() {
|
|
7677
|
-
return
|
|
7656
|
+
return path8.join(this.stateDir, "compression-guidelines.md");
|
|
7678
7657
|
}
|
|
7679
7658
|
get compressionGuidelineDraftPath() {
|
|
7680
|
-
return
|
|
7659
|
+
return path8.join(this.stateDir, "compression-guidelines.draft.md");
|
|
7681
7660
|
}
|
|
7682
7661
|
get compressionGuidelineStatePath() {
|
|
7683
|
-
return
|
|
7662
|
+
return path8.join(this.stateDir, "compression-guideline-state.json");
|
|
7684
7663
|
}
|
|
7685
7664
|
get compressionGuidelineDraftStatePath() {
|
|
7686
|
-
return
|
|
7665
|
+
return path8.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
7687
7666
|
}
|
|
7688
7667
|
get behaviorSignalsPath() {
|
|
7689
|
-
return
|
|
7668
|
+
return path8.join(this.stateDir, "behavior-signals.jsonl");
|
|
7690
7669
|
}
|
|
7691
7670
|
/**
|
|
7692
7671
|
* In-memory dedup key set for behavior-signals appends (issue #1909),
|
|
@@ -7718,7 +7697,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7718
7697
|
* governance sweeps can treat it uniformly.
|
|
7719
7698
|
*/
|
|
7720
7699
|
get bufferSurpriseLedgerPath() {
|
|
7721
|
-
return
|
|
7700
|
+
return path8.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
7722
7701
|
}
|
|
7723
7702
|
/**
|
|
7724
7703
|
* Entity alias table loaded from THIS store's config/aliases.json.
|
|
@@ -7779,7 +7758,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7779
7758
|
this.loadAliasesSync();
|
|
7780
7759
|
}
|
|
7781
7760
|
loadAliasesSync() {
|
|
7782
|
-
const aliasPath =
|
|
7761
|
+
const aliasPath = path8.join(this.baseDir, "config", "aliases.json");
|
|
7783
7762
|
this.userAliases = {};
|
|
7784
7763
|
try {
|
|
7785
7764
|
const raw = readFileSync(aliasPath, "utf-8");
|
|
@@ -7813,9 +7792,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7813
7792
|
await mkdir(this.baseDir, { recursive: true });
|
|
7814
7793
|
await validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);
|
|
7815
7794
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
7816
|
-
await mkdir(
|
|
7817
|
-
await mkdir(
|
|
7818
|
-
await mkdir(
|
|
7795
|
+
await mkdir(path8.join(this.factsDir, today), { recursive: true });
|
|
7796
|
+
await mkdir(path8.join(this.proceduresDir, today), { recursive: true });
|
|
7797
|
+
await mkdir(path8.join(this.reasoningTracesDir, today), { recursive: true });
|
|
7819
7798
|
await mkdir(this.correctionsDir, { recursive: true });
|
|
7820
7799
|
await mkdir(this.entitiesDir, { recursive: true });
|
|
7821
7800
|
await mkdir(this.stateDir, { recursive: true });
|
|
@@ -7825,7 +7804,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7825
7804
|
await mkdir(this.identityIncidentsDir, { recursive: true });
|
|
7826
7805
|
await mkdir(this.identityAuditsWeeklyDir, { recursive: true });
|
|
7827
7806
|
await mkdir(this.identityAuditsMonthlyDir, { recursive: true });
|
|
7828
|
-
await mkdir(
|
|
7807
|
+
await mkdir(path8.join(this.baseDir, "config"), { recursive: true });
|
|
7829
7808
|
await this.entityCanonicalIdMigration.ensure();
|
|
7830
7809
|
if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {
|
|
7831
7810
|
this.bumpMemoryCorpusVersion();
|
|
@@ -7847,11 +7826,11 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7847
7826
|
async resolveCategoryWritePath(category, id, today) {
|
|
7848
7827
|
if (category === "correction") {
|
|
7849
7828
|
await mkdir(this.correctionsDir, { recursive: true });
|
|
7850
|
-
return
|
|
7829
|
+
return path8.join(this.correctionsDir, `${id}.md`);
|
|
7851
7830
|
}
|
|
7852
|
-
const datedDir =
|
|
7831
|
+
const datedDir = path8.join(getCategoryDir(this.baseDir, category), today);
|
|
7853
7832
|
await mkdir(datedDir, { recursive: true });
|
|
7854
|
-
return
|
|
7833
|
+
return path8.join(datedDir, `${id}.md`);
|
|
7855
7834
|
}
|
|
7856
7835
|
async findExistingTombstoneBlockedMemory(content, category, sourceConnector) {
|
|
7857
7836
|
const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);
|
|
@@ -8211,7 +8190,7 @@ ${sanitized.text}
|
|
|
8211
8190
|
await this.ensureDirectories();
|
|
8212
8191
|
const now = /* @__PURE__ */ new Date();
|
|
8213
8192
|
const day = now.toISOString().slice(0, 10);
|
|
8214
|
-
const dir =
|
|
8193
|
+
const dir = path8.join(this.artifactsDir, day);
|
|
8215
8194
|
await mkdir(dir, { recursive: true });
|
|
8216
8195
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
8217
8196
|
const fm = {
|
|
@@ -8236,7 +8215,7 @@ ${sanitized.text}
|
|
|
8236
8215
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
8237
8216
|
return "";
|
|
8238
8217
|
}
|
|
8239
|
-
const filePath =
|
|
8218
|
+
const filePath = path8.join(dir, `${id}.md`);
|
|
8240
8219
|
await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(fm)}
|
|
8241
8220
|
|
|
8242
8221
|
${sanitized.text}
|
|
@@ -8507,7 +8486,7 @@ ${sanitized.text}
|
|
|
8507
8486
|
* per-process in-memory cache safe across process boundaries.
|
|
8508
8487
|
*/
|
|
8509
8488
|
invalidateColdMemoriesCache() {
|
|
8510
|
-
const coldRoot =
|
|
8489
|
+
const coldRoot = path8.join(this.baseDir, "cold");
|
|
8511
8490
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
8512
8491
|
this.bumpColdWriteVersion();
|
|
8513
8492
|
invalidateAllForDir(this.baseDir);
|
|
@@ -8622,7 +8601,7 @@ ${sanitized.text}
|
|
|
8622
8601
|
const correctionPaths = [];
|
|
8623
8602
|
const factPaths = [];
|
|
8624
8603
|
for (const filePath of filePaths) {
|
|
8625
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
8604
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path8.sep}`)) {
|
|
8626
8605
|
correctionPaths.push(filePath);
|
|
8627
8606
|
} else {
|
|
8628
8607
|
factPaths.push(filePath);
|
|
@@ -8685,7 +8664,7 @@ ${sanitized.text}
|
|
|
8685
8664
|
try {
|
|
8686
8665
|
const entries = await readdir5(dir, { withFileTypes: true });
|
|
8687
8666
|
for (const entry of entries) {
|
|
8688
|
-
const fullPath =
|
|
8667
|
+
const fullPath = path8.join(dir, entry.name);
|
|
8689
8668
|
if (entry.isDirectory()) {
|
|
8690
8669
|
await readDir(fullPath);
|
|
8691
8670
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -8718,7 +8697,7 @@ ${sanitized.text}
|
|
|
8718
8697
|
return this.memoryReadStore.readMemoryByPath(filePath);
|
|
8719
8698
|
}
|
|
8720
8699
|
resolveTierRootDir(tier) {
|
|
8721
|
-
return tier === "cold" ?
|
|
8700
|
+
return tier === "cold" ? path8.join(this.baseDir, "cold") : this.baseDir;
|
|
8722
8701
|
}
|
|
8723
8702
|
resolveMemoryDateDir(memory) {
|
|
8724
8703
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -8733,13 +8712,13 @@ ${sanitized.text}
|
|
|
8733
8712
|
buildTierMemoryPath(memory, tier) {
|
|
8734
8713
|
const root = this.resolveTierRootDir(tier);
|
|
8735
8714
|
if (this.isArtifactMemory(memory)) {
|
|
8736
|
-
return
|
|
8715
|
+
return path8.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
8737
8716
|
}
|
|
8738
8717
|
if (memory.frontmatter.category === "correction") {
|
|
8739
|
-
return
|
|
8718
|
+
return path8.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
8740
8719
|
}
|
|
8741
8720
|
const dir = categoryDirName(memory.frontmatter.category);
|
|
8742
|
-
return
|
|
8721
|
+
return path8.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
8743
8722
|
}
|
|
8744
8723
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
8745
8724
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
@@ -8787,8 +8766,8 @@ ${memory.content}
|
|
|
8787
8766
|
}
|
|
8788
8767
|
async moveMemoryToPath(memory, targetPath) {
|
|
8789
8768
|
await this.writeMemoryFileAtomic(targetPath, memory);
|
|
8790
|
-
const sourcePath =
|
|
8791
|
-
const destPath =
|
|
8769
|
+
const sourcePath = path8.resolve(memory.path);
|
|
8770
|
+
const destPath = path8.resolve(targetPath);
|
|
8792
8771
|
if (sourcePath !== destPath) {
|
|
8793
8772
|
try {
|
|
8794
8773
|
await unlink4(memory.path);
|
|
@@ -8804,8 +8783,8 @@ ${memory.content}
|
|
|
8804
8783
|
}
|
|
8805
8784
|
async migrateMemoryToTier(memory, targetTier) {
|
|
8806
8785
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
8807
|
-
const sourcePath =
|
|
8808
|
-
const destPath =
|
|
8786
|
+
const sourcePath = path8.resolve(memory.path);
|
|
8787
|
+
const destPath = path8.resolve(targetPath);
|
|
8809
8788
|
if (sourcePath === destPath) {
|
|
8810
8789
|
return { changed: false, targetPath };
|
|
8811
8790
|
}
|
|
@@ -8832,7 +8811,7 @@ ${memory.content}
|
|
|
8832
8811
|
return { changed: true, targetPath };
|
|
8833
8812
|
}
|
|
8834
8813
|
get archiveDir() {
|
|
8835
|
-
return
|
|
8814
|
+
return path8.join(this.baseDir, "archive");
|
|
8836
8815
|
}
|
|
8837
8816
|
/**
|
|
8838
8817
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -8844,7 +8823,7 @@ ${memory.content}
|
|
|
8844
8823
|
try {
|
|
8845
8824
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
8846
8825
|
const today = now.toISOString().slice(0, 10);
|
|
8847
|
-
const destDir =
|
|
8826
|
+
const destDir = path8.join(this.archiveDir, today);
|
|
8848
8827
|
await mkdir(destDir, { recursive: true });
|
|
8849
8828
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
8850
8829
|
const updatedFm = canonicalizeEntityRefOption(
|
|
@@ -8860,7 +8839,7 @@ ${memory.content}
|
|
|
8860
8839
|
|
|
8861
8840
|
${current.content}
|
|
8862
8841
|
`;
|
|
8863
|
-
const destPath =
|
|
8842
|
+
const destPath = path8.join(destDir, path8.basename(current.path));
|
|
8864
8843
|
const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
|
|
8865
8844
|
await this.writeStorageSecureFile(destPath, fileContent);
|
|
8866
8845
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
@@ -9047,7 +9026,7 @@ ${memory.content}
|
|
|
9047
9026
|
`;
|
|
9048
9027
|
await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {
|
|
9049
9028
|
this.invalidateAllMemoriesCache();
|
|
9050
|
-
if (memory.path.includes(`${
|
|
9029
|
+
if (memory.path.includes(`${path8.sep}cold${path8.sep}`)) {
|
|
9051
9030
|
this.invalidateColdMemoriesCache();
|
|
9052
9031
|
}
|
|
9053
9032
|
});
|
|
@@ -9063,7 +9042,7 @@ ${memory.content}
|
|
|
9063
9042
|
);
|
|
9064
9043
|
}
|
|
9065
9044
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
9066
|
-
if (memory.path.includes(`${
|
|
9045
|
+
if (memory.path.includes(`${path8.sep}cold${path8.sep}`)) {
|
|
9067
9046
|
this.invalidateColdMemoriesCache();
|
|
9068
9047
|
}
|
|
9069
9048
|
try {
|
|
@@ -9133,7 +9112,7 @@ ${memory.content}
|
|
|
9133
9112
|
return deleted;
|
|
9134
9113
|
}
|
|
9135
9114
|
async loadBuffer() {
|
|
9136
|
-
const bufferPath =
|
|
9115
|
+
const bufferPath = path8.join(this.stateDir, "buffer.json");
|
|
9137
9116
|
try {
|
|
9138
9117
|
const raw = await this.readStorageSecureFile(bufferPath);
|
|
9139
9118
|
return JSON.parse(raw);
|
|
@@ -9145,11 +9124,11 @@ ${memory.content}
|
|
|
9145
9124
|
}
|
|
9146
9125
|
async saveBuffer(state) {
|
|
9147
9126
|
await this.ensureDirectories();
|
|
9148
|
-
const bufferPath =
|
|
9127
|
+
const bufferPath = path8.join(this.stateDir, "buffer.json");
|
|
9149
9128
|
await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));
|
|
9150
9129
|
}
|
|
9151
9130
|
async loadMeta() {
|
|
9152
|
-
const metaPath =
|
|
9131
|
+
const metaPath = path8.join(this.stateDir, "meta.json");
|
|
9153
9132
|
try {
|
|
9154
9133
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
9155
9134
|
const parsed = JSON.parse(raw);
|
|
@@ -9182,7 +9161,7 @@ ${memory.content}
|
|
|
9182
9161
|
}
|
|
9183
9162
|
async saveMeta(state) {
|
|
9184
9163
|
await this.ensureDirectories();
|
|
9185
|
-
const metaPath =
|
|
9164
|
+
const metaPath = path8.join(this.stateDir, "meta.json");
|
|
9186
9165
|
await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
|
|
9187
9166
|
}
|
|
9188
9167
|
async appendMemoryActionEvents(events) {
|
|
@@ -9246,7 +9225,7 @@ ${memory.content}
|
|
|
9246
9225
|
},
|
|
9247
9226
|
(payload) => this.appendStorageSecureFile(target, payload),
|
|
9248
9227
|
async () => {
|
|
9249
|
-
await mkdir(
|
|
9228
|
+
await mkdir(path8.dirname(target), { recursive: true });
|
|
9250
9229
|
}
|
|
9251
9230
|
);
|
|
9252
9231
|
}
|
|
@@ -9344,7 +9323,7 @@ ${memory.content}
|
|
|
9344
9323
|
async appendReextractJobs(events) {
|
|
9345
9324
|
if (events.length === 0) return 0;
|
|
9346
9325
|
await this.ensureDirectories();
|
|
9347
|
-
const filePath =
|
|
9326
|
+
const filePath = path8.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9348
9327
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
9349
9328
|
try {
|
|
9350
9329
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -9357,7 +9336,7 @@ ${memory.content}
|
|
|
9357
9336
|
}
|
|
9358
9337
|
async readReextractJobs(limit = 200) {
|
|
9359
9338
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
9360
|
-
const filePath =
|
|
9339
|
+
const filePath = path8.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9361
9340
|
try {
|
|
9362
9341
|
const raw = await this.readStorageSecureFile(filePath);
|
|
9363
9342
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -9584,7 +9563,7 @@ ${question}
|
|
|
9584
9563
|
|
|
9585
9564
|
**Context:** ${context}
|
|
9586
9565
|
`;
|
|
9587
|
-
const filePath =
|
|
9566
|
+
const filePath = path8.join(this.questionsDir, `${id}.md`);
|
|
9588
9567
|
await this.writeStorageSecureFile(filePath, content);
|
|
9589
9568
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
9590
9569
|
this.invalidateQuestionsCache();
|
|
@@ -9602,7 +9581,7 @@ ${question}
|
|
|
9602
9581
|
if (!match) return null;
|
|
9603
9582
|
const frontmatterStr = match[1];
|
|
9604
9583
|
const body = match[2].trim();
|
|
9605
|
-
const id = this.extractFrontmatterValue(frontmatterStr, "id") ??
|
|
9584
|
+
const id = this.extractFrontmatterValue(frontmatterStr, "id") ?? path8.basename(filePath, ".md");
|
|
9606
9585
|
const created = this.extractFrontmatterValue(frontmatterStr, "created") ?? "";
|
|
9607
9586
|
const priority = parseFloat(this.extractFrontmatterValue(frontmatterStr, "priority") ?? "0.5");
|
|
9608
9587
|
const resolved = this.extractFrontmatterValue(frontmatterStr, "resolved") === "true";
|
|
@@ -9658,11 +9637,11 @@ ${question}
|
|
|
9658
9637
|
} catch {
|
|
9659
9638
|
}
|
|
9660
9639
|
const hygiene = opts?.hygiene;
|
|
9661
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
9640
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path8.basename(identityPath));
|
|
9662
9641
|
if (rotateEnabled) {
|
|
9663
9642
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
9664
9643
|
if (existing.length > maxBytes) {
|
|
9665
|
-
const archiveDir =
|
|
9644
|
+
const archiveDir = path8.join(workspaceDir, hygiene.archiveDir);
|
|
9666
9645
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
9667
9646
|
filePath: identityPath,
|
|
9668
9647
|
archiveDir,
|
|
@@ -9922,14 +9901,14 @@ ${reflection}
|
|
|
9922
9901
|
if (entries.length === 0) return 0;
|
|
9923
9902
|
const memories = await this.readAllMemories();
|
|
9924
9903
|
const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));
|
|
9925
|
-
const memoryPathMap = new Map(memories.map((m) => [
|
|
9904
|
+
const memoryPathMap = new Map(memories.map((m) => [path8.resolve(m.path), m]));
|
|
9926
9905
|
let updated = 0;
|
|
9927
9906
|
const prevVersion = this.getMemoryCorpusVersion();
|
|
9928
9907
|
const keyId = this.hotCacheKeyId();
|
|
9929
9908
|
const warm = this.hotMemoriesCacheEnabled && getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;
|
|
9930
9909
|
const appliedPatches = /* @__PURE__ */ new Map();
|
|
9931
9910
|
for (const entry of entries) {
|
|
9932
|
-
const memory = entry.memoryPath ? memoryPathMap.get(
|
|
9911
|
+
const memory = entry.memoryPath ? memoryPathMap.get(path8.resolve(entry.memoryPath)) : memoryMap.get(entry.memoryId);
|
|
9933
9912
|
if (!memory) continue;
|
|
9934
9913
|
const rowIds = this.currentHistoricalIds();
|
|
9935
9914
|
const newFm = canonicalizeEntityRefOption(
|
|
@@ -9955,7 +9934,7 @@ ${memory.content}
|
|
|
9955
9934
|
if (warm) {
|
|
9956
9935
|
updateCacheOnWrite(this.baseDir, { ...memory, frontmatter: newFm }, keyId);
|
|
9957
9936
|
}
|
|
9958
|
-
appliedPatches.set(
|
|
9937
|
+
appliedPatches.set(path8.resolve(memory.path), {
|
|
9959
9938
|
accessCount: entry.newCount,
|
|
9960
9939
|
lastAccessed: entry.lastAccessed
|
|
9961
9940
|
});
|
|
@@ -9971,7 +9950,7 @@ ${memory.content}
|
|
|
9971
9950
|
const cur = getCachedMemories(this.baseDir, prevVersion, keyId);
|
|
9972
9951
|
if (cur) {
|
|
9973
9952
|
const reapplied = cur.map((m) => {
|
|
9974
|
-
const patch = appliedPatches.get(
|
|
9953
|
+
const patch = appliedPatches.get(path8.resolve(m.path));
|
|
9975
9954
|
return patch ? {
|
|
9976
9955
|
...m,
|
|
9977
9956
|
frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed }
|
|
@@ -10006,7 +9985,7 @@ ${memory.content}
|
|
|
10006
9985
|
const pathsById = /* @__PURE__ */ new Map();
|
|
10007
9986
|
const filePathsById = /* @__PURE__ */ new Map();
|
|
10008
9987
|
for (const filePath of filePaths) {
|
|
10009
|
-
const memoryId =
|
|
9988
|
+
const memoryId = path8.basename(filePath, ".md");
|
|
10010
9989
|
if (!wantedIds.has(memoryId)) continue;
|
|
10011
9990
|
const paths = filePathsById.get(memoryId) ?? [];
|
|
10012
9991
|
paths.push(filePath);
|
|
@@ -10018,7 +9997,7 @@ ${memory.content}
|
|
|
10018
9997
|
const preferredMatches = [];
|
|
10019
9998
|
for (const preferredPath of preferred) {
|
|
10020
9999
|
const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));
|
|
10021
|
-
const directMatch = existingPaths.find((filePath) => directCandidates.has(
|
|
10000
|
+
const directMatch = existingPaths.find((filePath) => directCandidates.has(path8.resolve(filePath)));
|
|
10022
10001
|
if (directMatch) {
|
|
10023
10002
|
preferredMatches.push(directMatch);
|
|
10024
10003
|
continue;
|
|
@@ -10030,7 +10009,7 @@ ${memory.content}
|
|
|
10030
10009
|
candidates.add(candidate);
|
|
10031
10010
|
}
|
|
10032
10011
|
}
|
|
10033
|
-
const match = existingPaths.find((filePath) => candidates.has(
|
|
10012
|
+
const match = existingPaths.find((filePath) => candidates.has(path8.resolve(filePath)));
|
|
10034
10013
|
if (match) preferredMatches.push(match);
|
|
10035
10014
|
}
|
|
10036
10015
|
if (preferredMatches.length > 0) {
|
|
@@ -10092,21 +10071,14 @@ ${memory.content}
|
|
|
10092
10071
|
if (cappedLimit === 0) return [];
|
|
10093
10072
|
const projected = readProjectedMemoryTimeline(this.baseDir, memoryId, cappedLimit);
|
|
10094
10073
|
if (projected && projected.length > 0) return projected;
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
if (!Number.isFinite(ageMs)) return `projection rebuiltAt=${rebuiltAt}`;
|
|
10100
|
-
const ageMin = Math.max(0, Math.round(ageMs / 6e4));
|
|
10101
|
-
const age = ageMin >= 120 ? `${Math.round(ageMin / 60)}h` : `${ageMin}m`;
|
|
10102
|
-
return `projection ${age} stale, last rebuilt ${rebuiltAt}`;
|
|
10103
|
-
});
|
|
10104
|
-
return readBoundedLifecycleEventsFromLedger(
|
|
10105
|
-
this.memoryLifecycleLedgerPath,
|
|
10106
|
-
(p) => this.readStorageSecureFile(p),
|
|
10074
|
+
return this.projectionLedgerLagManager.resolveTimelineWithLag({
|
|
10075
|
+
baseDir: this.baseDir,
|
|
10076
|
+
ledgerPath: this.memoryLifecycleLedgerPath,
|
|
10077
|
+
memoryId,
|
|
10107
10078
|
cappedLimit,
|
|
10108
|
-
|
|
10109
|
-
|
|
10079
|
+
readSecureFile: (p) => this.readStorageSecureFile(p),
|
|
10080
|
+
projectionAge: () => formatProjectionAge(readProjectionRebuiltAt(this.baseDir))
|
|
10081
|
+
});
|
|
10110
10082
|
}
|
|
10111
10083
|
// ---------------------------------------------------------------------------
|
|
10112
10084
|
// Chunking (Phase 2A)
|
|
@@ -10289,14 +10261,14 @@ Reason: ${reason}`;
|
|
|
10289
10261
|
// Memory Summarization (Phase 4A)
|
|
10290
10262
|
// ---------------------------------------------------------------------------
|
|
10291
10263
|
get summariesDir() {
|
|
10292
|
-
return
|
|
10264
|
+
return path8.join(this.baseDir, "summaries");
|
|
10293
10265
|
}
|
|
10294
10266
|
/**
|
|
10295
10267
|
* Write a memory summary.
|
|
10296
10268
|
*/
|
|
10297
10269
|
async writeSummary(summary) {
|
|
10298
10270
|
await mkdir(this.summariesDir, { recursive: true });
|
|
10299
|
-
const filePath =
|
|
10271
|
+
const filePath = path8.join(this.summariesDir, `${summary.id}.json`);
|
|
10300
10272
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
10301
10273
|
log.debug(`wrote summary ${summary.id}`);
|
|
10302
10274
|
}
|
|
@@ -10309,7 +10281,7 @@ Reason: ${reason}`;
|
|
|
10309
10281
|
const summaries = [];
|
|
10310
10282
|
for (const file of files) {
|
|
10311
10283
|
if (!file.endsWith(".json")) continue;
|
|
10312
|
-
const filePath =
|
|
10284
|
+
const filePath = path8.join(this.summariesDir, file);
|
|
10313
10285
|
const raw = await this.readStorageSecureFile(filePath);
|
|
10314
10286
|
summaries.push(JSON.parse(raw));
|
|
10315
10287
|
}
|
|
@@ -10380,7 +10352,7 @@ ${memory.content}
|
|
|
10380
10352
|
* Save topic scores to meta.json.
|
|
10381
10353
|
*/
|
|
10382
10354
|
async saveTopics(topics) {
|
|
10383
|
-
const metaPath =
|
|
10355
|
+
const metaPath = path8.join(this.stateDir, "topics.json");
|
|
10384
10356
|
await mkdir(this.stateDir, { recursive: true });
|
|
10385
10357
|
await this.writeStorageSecureFile(
|
|
10386
10358
|
metaPath,
|
|
@@ -10392,7 +10364,7 @@ ${memory.content}
|
|
|
10392
10364
|
* Load topic scores from meta.json.
|
|
10393
10365
|
*/
|
|
10394
10366
|
async loadTopics() {
|
|
10395
|
-
const metaPath =
|
|
10367
|
+
const metaPath = path8.join(this.stateDir, "topics.json");
|
|
10396
10368
|
try {
|
|
10397
10369
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
10398
10370
|
return JSON.parse(raw);
|
|
@@ -10470,8 +10442,6 @@ ${memory.content}
|
|
|
10470
10442
|
};
|
|
10471
10443
|
|
|
10472
10444
|
export {
|
|
10473
|
-
readProjectionRebuiltAt,
|
|
10474
|
-
assertInjectedStorageRooted,
|
|
10475
10445
|
selfDeps,
|
|
10476
10446
|
qmdCollectionPathParts,
|
|
10477
10447
|
qmdResultPathCandidates,
|
|
@@ -10512,4 +10482,4 @@ export {
|
|
|
10512
10482
|
isValidBufferSurpriseEvent,
|
|
10513
10483
|
StorageManager3 as StorageManager
|
|
10514
10484
|
};
|
|
10515
|
-
//# sourceMappingURL=chunk-
|
|
10485
|
+
//# sourceMappingURL=chunk-ENLZOWYK.js.map
|