@remnic/core 9.3.643 → 9.3.645
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-cli.js +12 -12
- package/dist/access-http.js +6 -6
- package/dist/access-mcp.js +5 -5
- package/dist/access-service.js +4 -4
- package/dist/briefing.js +2 -2
- package/dist/causal-consolidation.js +3 -3
- package/dist/{chunk-SZL2GGFY.js → chunk-4BISW7RX.js} +2 -2
- package/dist/{chunk-2GCNTHRA.js → chunk-6YLJZ2EU.js} +12 -12
- package/dist/{chunk-GYITUZFT.js → chunk-A4BTPHIN.js} +171 -134
- package/dist/chunk-A4BTPHIN.js.map +1 -0
- package/dist/{chunk-NV2MGIW7.js → chunk-ALUZN7BE.js} +2 -2
- package/dist/{chunk-RFSCIBCB.js → chunk-AMACWKM4.js} +2 -2
- package/dist/{chunk-S2SEPLLA.js → chunk-BTRL6GG7.js} +3 -3
- package/dist/{chunk-RREI7CNM.js → chunk-D6WVJIS3.js} +9 -42
- package/dist/chunk-D6WVJIS3.js.map +1 -0
- package/dist/{chunk-DM4US77W.js → chunk-IZXOO6NP.js} +5 -3
- package/dist/{chunk-DM4US77W.js.map → chunk-IZXOO6NP.js.map} +1 -1
- package/dist/{chunk-3UR4SBZF.js → chunk-MBT3ASYV.js} +9 -9
- package/dist/{chunk-4HYWWO3W.js → chunk-MCYT2RNT.js} +3 -3
- package/dist/{chunk-THWT7RJU.js → chunk-OR7R6M5Z.js} +2 -2
- package/dist/{chunk-4MNDVDBS.js → chunk-OTC2KOZ2.js} +2 -2
- package/dist/{chunk-TTOYT5RB.js → chunk-PQFUUXWK.js} +2 -2
- package/dist/{chunk-EGBH5IPJ.js → chunk-T22TZJWJ.js} +4 -4
- package/dist/{chunk-4HYLRROV.js → chunk-UMKPSD35.js} +2 -2
- package/dist/{chunk-NLPH23IQ.js → chunk-UMTG2BN2.js} +2 -2
- package/dist/{chunk-AK4DSORQ.js → chunk-W5ISYSIL.js} +4 -4
- package/dist/{chunk-GJSNDJHR.js → chunk-YOXCJP3A.js} +3 -3
- package/dist/{chunk-ECMMM2VE.js → chunk-Z3PZRDLW.js} +2 -2
- package/dist/{chunk-TKNTAUA3.js → chunk-ZXWAQFDE.js} +2 -2
- package/dist/cli.js +15 -15
- package/dist/compounding/engine.js +2 -2
- package/dist/connectors/codex-materialize-runner.js +2 -2
- package/dist/connectors/index.js +2 -2
- package/dist/entity-retrieval.js +2 -2
- package/dist/index.js +23 -24
- package/dist/index.js.map +1 -1
- package/dist/maintenance/memory-governance.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +3 -3
- package/dist/namespaces/migrate.js +3 -3
- package/dist/namespaces/storage.js +2 -2
- package/dist/operator-toolkit.js +5 -5
- package/dist/orchestrator.js +10 -10
- package/dist/schemas.d.ts +22 -22
- package/dist/semantic-consolidation.js +3 -3
- package/dist/semantic-rule-promotion.js +2 -2
- package/dist/semantic-rule-verifier.js +2 -2
- package/dist/storage.js +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/verified-recall.js +2 -2
- package/package.json +1 -1
- package/src/storage-fallback-category-dirs.test.ts +389 -0
- package/src/storage.ts +36 -4
- package/src/utils/category-dir.ts +26 -0
- package/dist/chunk-GYITUZFT.js.map +0 -1
- package/dist/chunk-RREI7CNM.js.map +0 -1
- /package/dist/{chunk-SZL2GGFY.js.map → chunk-4BISW7RX.js.map} +0 -0
- /package/dist/{chunk-2GCNTHRA.js.map → chunk-6YLJZ2EU.js.map} +0 -0
- /package/dist/{chunk-NV2MGIW7.js.map → chunk-ALUZN7BE.js.map} +0 -0
- /package/dist/{chunk-RFSCIBCB.js.map → chunk-AMACWKM4.js.map} +0 -0
- /package/dist/{chunk-S2SEPLLA.js.map → chunk-BTRL6GG7.js.map} +0 -0
- /package/dist/{chunk-3UR4SBZF.js.map → chunk-MBT3ASYV.js.map} +0 -0
- /package/dist/{chunk-4HYWWO3W.js.map → chunk-MCYT2RNT.js.map} +0 -0
- /package/dist/{chunk-THWT7RJU.js.map → chunk-OR7R6M5Z.js.map} +0 -0
- /package/dist/{chunk-4MNDVDBS.js.map → chunk-OTC2KOZ2.js.map} +0 -0
- /package/dist/{chunk-TTOYT5RB.js.map → chunk-PQFUUXWK.js.map} +0 -0
- /package/dist/{chunk-EGBH5IPJ.js.map → chunk-T22TZJWJ.js.map} +0 -0
- /package/dist/{chunk-4HYLRROV.js.map → chunk-UMKPSD35.js.map} +0 -0
- /package/dist/{chunk-NLPH23IQ.js.map → chunk-UMTG2BN2.js.map} +0 -0
- /package/dist/{chunk-AK4DSORQ.js.map → chunk-W5ISYSIL.js.map} +0 -0
- /package/dist/{chunk-GJSNDJHR.js.map → chunk-YOXCJP3A.js.map} +0 -0
- /package/dist/{chunk-ECMMM2VE.js.map → chunk-Z3PZRDLW.js.map} +0 -0
- /package/dist/{chunk-TKNTAUA3.js.map → chunk-ZXWAQFDE.js.map} +0 -0
|
@@ -82,7 +82,42 @@ import {
|
|
|
82
82
|
import { access, readdir, readFile, stat, writeFile, mkdir, unlink, appendFile, open } from "fs/promises";
|
|
83
83
|
import { appendFileSync, createReadStream, mkdirSync, statSync } from "fs";
|
|
84
84
|
import { createHash } from "crypto";
|
|
85
|
+
import path2 from "path";
|
|
86
|
+
|
|
87
|
+
// src/utils/category-dir.ts
|
|
85
88
|
import path from "path";
|
|
89
|
+
var CATEGORY_DIR_MAP = {
|
|
90
|
+
correction: "corrections",
|
|
91
|
+
question: "questions",
|
|
92
|
+
preference: "preferences",
|
|
93
|
+
decision: "decisions",
|
|
94
|
+
moment: "moments",
|
|
95
|
+
commitment: "commitments",
|
|
96
|
+
principle: "principles",
|
|
97
|
+
rule: "rules",
|
|
98
|
+
skill: "skills",
|
|
99
|
+
relationship: "relationships",
|
|
100
|
+
procedure: "procedures",
|
|
101
|
+
reasoning_trace: "reasoning-traces"
|
|
102
|
+
};
|
|
103
|
+
var ALL_CATEGORY_DIRS = [
|
|
104
|
+
"facts",
|
|
105
|
+
...Object.values(CATEGORY_DIR_MAP)
|
|
106
|
+
];
|
|
107
|
+
var RECALL_NON_MEMORY_DIRS = /* @__PURE__ */ new Set(["questions"]);
|
|
108
|
+
var RECALL_FALLBACK_DIRS = ALL_CATEGORY_DIRS.filter(
|
|
109
|
+
(dir) => !RECALL_NON_MEMORY_DIRS.has(dir)
|
|
110
|
+
);
|
|
111
|
+
var ALL_CATEGORY_KEYS = [
|
|
112
|
+
"fact",
|
|
113
|
+
...Object.keys(CATEGORY_DIR_MAP)
|
|
114
|
+
];
|
|
115
|
+
function getCategoryDir(memoryDir, category) {
|
|
116
|
+
const dir = Object.hasOwn(CATEGORY_DIR_MAP, category) ? CATEGORY_DIR_MAP[category] : void 0;
|
|
117
|
+
return dir ? path.join(memoryDir, dir) : path.join(memoryDir, "facts");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/storage.ts
|
|
86
121
|
var ARTIFACT_SEARCH_STOPWORDS = /* @__PURE__ */ new Set([
|
|
87
122
|
"a",
|
|
88
123
|
"an",
|
|
@@ -666,17 +701,17 @@ var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set([
|
|
|
666
701
|
"topic"
|
|
667
702
|
]);
|
|
668
703
|
function inferEntityTypeFromFilename(pathRel) {
|
|
669
|
-
const basename =
|
|
704
|
+
const basename = path2.basename(pathRel, ".md").toLowerCase();
|
|
670
705
|
const separator = basename.indexOf("-");
|
|
671
706
|
if (separator <= 0) return void 0;
|
|
672
707
|
const candidate = basename.slice(0, separator);
|
|
673
708
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
674
709
|
}
|
|
675
710
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
676
|
-
const normalizedPath = pathRel.split(
|
|
711
|
+
const normalizedPath = pathRel.split(path2.sep).join("/");
|
|
677
712
|
let normalizedFrontmatter = frontmatter;
|
|
678
713
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
679
|
-
const basename =
|
|
714
|
+
const basename = path2.basename(pathRel, ".md");
|
|
680
715
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
681
716
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
682
717
|
normalizedFrontmatter = {
|
|
@@ -743,8 +778,8 @@ var ContentHashIndex = class _ContentHashIndex {
|
|
|
743
778
|
secureStoreKeyProvider;
|
|
744
779
|
secureStoreWriteKeyProvider;
|
|
745
780
|
memoryDir;
|
|
746
|
-
constructor(stateDir, secureStoreKeyProvider = () => null, secureStoreWriteKeyProvider = secureStoreKeyProvider, memoryDir =
|
|
747
|
-
this.filePath =
|
|
781
|
+
constructor(stateDir, secureStoreKeyProvider = () => null, secureStoreWriteKeyProvider = secureStoreKeyProvider, memoryDir = path2.dirname(stateDir)) {
|
|
782
|
+
this.filePath = path2.join(stateDir, "fact-hashes.txt");
|
|
748
783
|
this.secureStoreKeyProvider = secureStoreKeyProvider;
|
|
749
784
|
this.secureStoreWriteKeyProvider = secureStoreWriteKeyProvider;
|
|
750
785
|
this.memoryDir = memoryDir;
|
|
@@ -791,7 +826,7 @@ var ContentHashIndex = class _ContentHashIndex {
|
|
|
791
826
|
/** Persist index to disk if changed. */
|
|
792
827
|
async save() {
|
|
793
828
|
if (!this.dirty) return;
|
|
794
|
-
await mkdir(
|
|
829
|
+
await mkdir(path2.dirname(this.filePath), { recursive: true });
|
|
795
830
|
await writeMaybeEncryptedFile(
|
|
796
831
|
this.filePath,
|
|
797
832
|
[...this.hashes].join("\n") + "\n",
|
|
@@ -1858,7 +1893,7 @@ var StorageManager = class _StorageManager {
|
|
|
1858
1893
|
void 0,
|
|
1859
1894
|
this.baseDir
|
|
1860
1895
|
);
|
|
1861
|
-
const rel =
|
|
1896
|
+
const rel = path2.relative(this.baseDir, filePath).split(path2.sep).join("/");
|
|
1862
1897
|
return `${rel}:${version.versionId}`;
|
|
1863
1898
|
} catch (err) {
|
|
1864
1899
|
log.warn(
|
|
@@ -1873,13 +1908,13 @@ var StorageManager = class _StorageManager {
|
|
|
1873
1908
|
}
|
|
1874
1909
|
identityFilePath(workspaceDir, namespace) {
|
|
1875
1910
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
1876
|
-
if (!rawNamespace) return
|
|
1911
|
+
if (!rawNamespace) return path2.join(workspaceDir, "IDENTITY.md");
|
|
1877
1912
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
1878
|
-
return
|
|
1913
|
+
return path2.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
1879
1914
|
}
|
|
1880
1915
|
versionFilePath(kind) {
|
|
1881
1916
|
const fileName = kind === "memory-status" ? ".memory-status-version.log" : kind === "artifact-write" ? ".artifact-write-version.log" : ".cold-write-version.log";
|
|
1882
|
-
return
|
|
1917
|
+
return path2.join(this.stateDir, fileName);
|
|
1883
1918
|
}
|
|
1884
1919
|
bumpSharedVersion(kind, fallbackMap) {
|
|
1885
1920
|
const filePath = this.versionFilePath(kind);
|
|
@@ -1925,7 +1960,7 @@ var StorageManager = class _StorageManager {
|
|
|
1925
1960
|
// memories.
|
|
1926
1961
|
// -------------------------------------------------------------------------
|
|
1927
1962
|
get wearablesDir() {
|
|
1928
|
-
return
|
|
1963
|
+
return path2.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
1929
1964
|
}
|
|
1930
1965
|
/**
|
|
1931
1966
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -1943,7 +1978,7 @@ var StorageManager = class _StorageManager {
|
|
|
1943
1978
|
`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
1944
1979
|
);
|
|
1945
1980
|
}
|
|
1946
|
-
return
|
|
1981
|
+
return path2.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
1947
1982
|
}
|
|
1948
1983
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
1949
1984
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -1981,7 +2016,7 @@ var StorageManager = class _StorageManager {
|
|
|
1981
2016
|
if (!/^[a-z][a-z0-9-]{0,63}$/.test(source)) continue;
|
|
1982
2017
|
let entries;
|
|
1983
2018
|
try {
|
|
1984
|
-
entries = await readdir(
|
|
2019
|
+
entries = await readdir(path2.join(this.wearablesDir, source));
|
|
1985
2020
|
} catch (err) {
|
|
1986
2021
|
if (err.code === "ENOENT") continue;
|
|
1987
2022
|
throw err;
|
|
@@ -2064,25 +2099,25 @@ var StorageManager = class _StorageManager {
|
|
|
2064
2099
|
});
|
|
2065
2100
|
}
|
|
2066
2101
|
get factsDir() {
|
|
2067
|
-
return
|
|
2102
|
+
return path2.join(this.baseDir, "facts");
|
|
2068
2103
|
}
|
|
2069
2104
|
get correctionsDir() {
|
|
2070
|
-
return
|
|
2105
|
+
return path2.join(this.baseDir, "corrections");
|
|
2071
2106
|
}
|
|
2072
2107
|
get proceduresDir() {
|
|
2073
|
-
return
|
|
2108
|
+
return path2.join(this.baseDir, "procedures");
|
|
2074
2109
|
}
|
|
2075
2110
|
get reasoningTracesDir() {
|
|
2076
|
-
return
|
|
2111
|
+
return path2.join(this.baseDir, "reasoning-traces");
|
|
2077
2112
|
}
|
|
2078
2113
|
get entitiesDir() {
|
|
2079
|
-
return
|
|
2114
|
+
return path2.join(this.baseDir, "entities");
|
|
2080
2115
|
}
|
|
2081
2116
|
resolveEntityFilePath(name) {
|
|
2082
2117
|
if (typeof name !== "string") return null;
|
|
2083
|
-
const filePath =
|
|
2084
|
-
const relative =
|
|
2085
|
-
if (relative === "" || relative.startsWith("..") ||
|
|
2118
|
+
const filePath = path2.resolve(this.entitiesDir, `${name}.md`);
|
|
2119
|
+
const relative = path2.relative(this.entitiesDir, filePath);
|
|
2120
|
+
if (relative === "" || relative.startsWith("..") || path2.isAbsolute(relative)) {
|
|
2086
2121
|
return null;
|
|
2087
2122
|
}
|
|
2088
2123
|
return filePath;
|
|
@@ -2094,10 +2129,10 @@ var StorageManager = class _StorageManager {
|
|
|
2094
2129
|
return writeMaybeEncryptedFile(filePath, content, this.resolveWriteKey(), {}, this.baseDir);
|
|
2095
2130
|
}
|
|
2096
2131
|
assertManagedStoragePath(filePath, method) {
|
|
2097
|
-
const resolved =
|
|
2098
|
-
const base =
|
|
2099
|
-
const rel =
|
|
2100
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
2132
|
+
const resolved = path2.resolve(filePath);
|
|
2133
|
+
const base = path2.resolve(this.baseDir);
|
|
2134
|
+
const rel = path2.relative(base, resolved);
|
|
2135
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path2.sep}`) || path2.isAbsolute(rel)) {
|
|
2101
2136
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
2102
2137
|
}
|
|
2103
2138
|
return resolved;
|
|
@@ -2109,7 +2144,7 @@ var StorageManager = class _StorageManager {
|
|
|
2109
2144
|
async digestOfflineSyncFile(filePath) {
|
|
2110
2145
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
2111
2146
|
const st = await stat(target);
|
|
2112
|
-
const relPath =
|
|
2147
|
+
const relPath = path2.relative(this.baseDir, target).split(path2.sep).join("/");
|
|
2113
2148
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
2114
2149
|
const cached = cache.get(relPath);
|
|
2115
2150
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -2170,7 +2205,7 @@ var StorageManager = class _StorageManager {
|
|
|
2170
2205
|
const bytes = typeof record.bytes === "number" ? record.bytes : NaN;
|
|
2171
2206
|
const sha256 = typeof record.sha256 === "string" ? record.sha256 : "";
|
|
2172
2207
|
const encrypted = record.encrypted === true;
|
|
2173
|
-
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") ||
|
|
2208
|
+
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") || path2.isAbsolute(cachePath) || !Number.isFinite(statBytes) || !Number.isFinite(mtimeMs) || !Number.isFinite(ctimeMs) || !Number.isFinite(bytes) || !/^[a-f0-9]{64}$/i.test(sha256)) {
|
|
2174
2209
|
continue;
|
|
2175
2210
|
}
|
|
2176
2211
|
cache.set(cachePath, { statBytes, mtimeMs, ctimeMs, encrypted, sha256, bytes });
|
|
@@ -2212,7 +2247,7 @@ var StorageManager = class _StorageManager {
|
|
|
2212
2247
|
const cache = this.offlineSyncDigestCache;
|
|
2213
2248
|
if (!cache) return;
|
|
2214
2249
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
2215
|
-
await mkdir(
|
|
2250
|
+
await mkdir(path2.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
2216
2251
|
await writeFile(
|
|
2217
2252
|
this.offlineSyncDigestCachePath,
|
|
2218
2253
|
`${JSON.stringify({ version: 1, entries })}
|
|
@@ -2266,10 +2301,10 @@ var StorageManager = class _StorageManager {
|
|
|
2266
2301
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2267
2302
|
throw error;
|
|
2268
2303
|
});
|
|
2269
|
-
if (filePath.includes(`${
|
|
2304
|
+
if (filePath.includes(`${path2.sep}cold${path2.sep}`)) {
|
|
2270
2305
|
this.invalidateColdMemoriesCache();
|
|
2271
2306
|
}
|
|
2272
|
-
if (filePath.includes(`${
|
|
2307
|
+
if (filePath.includes(`${path2.sep}artifacts${path2.sep}`)) {
|
|
2273
2308
|
this.bumpArtifactWriteVersion();
|
|
2274
2309
|
}
|
|
2275
2310
|
this.bumpMemoryStatusVersion();
|
|
@@ -2297,7 +2332,7 @@ var StorageManager = class _StorageManager {
|
|
|
2297
2332
|
}
|
|
2298
2333
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
2299
2334
|
const writeKey = this.resolveWriteKey();
|
|
2300
|
-
await mkdir(
|
|
2335
|
+
await mkdir(path2.dirname(filePath), { recursive: true });
|
|
2301
2336
|
if (writeKey === null) {
|
|
2302
2337
|
try {
|
|
2303
2338
|
if (isEncryptedFile(await readFile(filePath))) {
|
|
@@ -2320,16 +2355,16 @@ var StorageManager = class _StorageManager {
|
|
|
2320
2355
|
await writeMaybeEncryptedFile(filePath, `${existing}${content}`, writeKey, {}, this.baseDir);
|
|
2321
2356
|
}
|
|
2322
2357
|
get stateDir() {
|
|
2323
|
-
return
|
|
2358
|
+
return path2.join(this.baseDir, "state");
|
|
2324
2359
|
}
|
|
2325
2360
|
get offlineSyncDigestCachePath() {
|
|
2326
|
-
return
|
|
2361
|
+
return path2.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
2327
2362
|
}
|
|
2328
2363
|
get entitySynthesisQueuePath() {
|
|
2329
|
-
return
|
|
2364
|
+
return path2.join(this.stateDir, "entity-synthesis-queue.json");
|
|
2330
2365
|
}
|
|
2331
2366
|
get factHashIndexReadyPath() {
|
|
2332
|
-
return
|
|
2367
|
+
return path2.join(this.stateDir, "fact-hashes.ready");
|
|
2333
2368
|
}
|
|
2334
2369
|
async getFactHashIndex() {
|
|
2335
2370
|
if (this.factHashIndex) {
|
|
@@ -2396,7 +2431,7 @@ var StorageManager = class _StorageManager {
|
|
|
2396
2431
|
);
|
|
2397
2432
|
}
|
|
2398
2433
|
await factHashIndex.save();
|
|
2399
|
-
await mkdir(
|
|
2434
|
+
await mkdir(path2.dirname(this.factHashIndexReadyPath), { recursive: true });
|
|
2400
2435
|
await writeFile(this.factHashIndexReadyPath, "v1\n", "utf-8");
|
|
2401
2436
|
this.factHashIndexAuthoritative = true;
|
|
2402
2437
|
})().finally(() => {
|
|
@@ -2405,55 +2440,55 @@ var StorageManager = class _StorageManager {
|
|
|
2405
2440
|
await this.factHashIndexAuthoritativePromise;
|
|
2406
2441
|
}
|
|
2407
2442
|
get questionsDir() {
|
|
2408
|
-
return
|
|
2443
|
+
return path2.join(this.baseDir, "questions");
|
|
2409
2444
|
}
|
|
2410
2445
|
get artifactsDir() {
|
|
2411
|
-
return
|
|
2446
|
+
return path2.join(this.baseDir, "artifacts");
|
|
2412
2447
|
}
|
|
2413
2448
|
get identityDir() {
|
|
2414
|
-
return
|
|
2449
|
+
return path2.join(this.baseDir, "identity");
|
|
2415
2450
|
}
|
|
2416
2451
|
get identityAnchorPath() {
|
|
2417
|
-
return
|
|
2452
|
+
return path2.join(this.identityDir, "identity-anchor.md");
|
|
2418
2453
|
}
|
|
2419
2454
|
get identityIncidentsDir() {
|
|
2420
|
-
return
|
|
2455
|
+
return path2.join(this.identityDir, "incidents");
|
|
2421
2456
|
}
|
|
2422
2457
|
get identityAuditsWeeklyDir() {
|
|
2423
|
-
return
|
|
2458
|
+
return path2.join(this.identityDir, "audits", "weekly");
|
|
2424
2459
|
}
|
|
2425
2460
|
get identityAuditsMonthlyDir() {
|
|
2426
|
-
return
|
|
2461
|
+
return path2.join(this.identityDir, "audits", "monthly");
|
|
2427
2462
|
}
|
|
2428
2463
|
get identityImprovementLoopsPath() {
|
|
2429
|
-
return
|
|
2464
|
+
return path2.join(this.identityDir, "improvement-loops.md");
|
|
2430
2465
|
}
|
|
2431
2466
|
get identityReflectionsPath() {
|
|
2432
|
-
return
|
|
2467
|
+
return path2.join(this.identityDir, "reflections.md");
|
|
2433
2468
|
}
|
|
2434
2469
|
get profilePath() {
|
|
2435
|
-
return
|
|
2470
|
+
return path2.join(this.baseDir, "profile.md");
|
|
2436
2471
|
}
|
|
2437
2472
|
get memoryActionsPath() {
|
|
2438
|
-
return
|
|
2473
|
+
return path2.join(this.stateDir, "memory-actions.jsonl");
|
|
2439
2474
|
}
|
|
2440
2475
|
get memoryLifecycleLedgerPath() {
|
|
2441
|
-
return
|
|
2476
|
+
return path2.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
2442
2477
|
}
|
|
2443
2478
|
get compressionGuidelinesPath() {
|
|
2444
|
-
return
|
|
2479
|
+
return path2.join(this.stateDir, "compression-guidelines.md");
|
|
2445
2480
|
}
|
|
2446
2481
|
get compressionGuidelineDraftPath() {
|
|
2447
|
-
return
|
|
2482
|
+
return path2.join(this.stateDir, "compression-guidelines.draft.md");
|
|
2448
2483
|
}
|
|
2449
2484
|
get compressionGuidelineStatePath() {
|
|
2450
|
-
return
|
|
2485
|
+
return path2.join(this.stateDir, "compression-guideline-state.json");
|
|
2451
2486
|
}
|
|
2452
2487
|
get compressionGuidelineDraftStatePath() {
|
|
2453
|
-
return
|
|
2488
|
+
return path2.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
2454
2489
|
}
|
|
2455
2490
|
get behaviorSignalsPath() {
|
|
2456
|
-
return
|
|
2491
|
+
return path2.join(this.stateDir, "behavior-signals.jsonl");
|
|
2457
2492
|
}
|
|
2458
2493
|
/**
|
|
2459
2494
|
* Buffer surprise telemetry ledger (issue #563 PR 3).
|
|
@@ -2466,7 +2501,7 @@ var StorageManager = class _StorageManager {
|
|
|
2466
2501
|
* governance sweeps can treat it uniformly.
|
|
2467
2502
|
*/
|
|
2468
2503
|
get bufferSurpriseLedgerPath() {
|
|
2469
|
-
return
|
|
2504
|
+
return path2.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
2470
2505
|
}
|
|
2471
2506
|
/**
|
|
2472
2507
|
* Load user-defined entity aliases from config/aliases.json in the memory store.
|
|
@@ -2474,7 +2509,7 @@ var StorageManager = class _StorageManager {
|
|
|
2474
2509
|
* Call this once at startup (e.g. from orchestrator.initialize()).
|
|
2475
2510
|
*/
|
|
2476
2511
|
async loadAliases() {
|
|
2477
|
-
const aliasPath =
|
|
2512
|
+
const aliasPath = path2.join(this.baseDir, "config", "aliases.json");
|
|
2478
2513
|
try {
|
|
2479
2514
|
const raw = await readFile(aliasPath, "utf-8");
|
|
2480
2515
|
const parsed = JSON.parse(raw);
|
|
@@ -2488,9 +2523,9 @@ var StorageManager = class _StorageManager {
|
|
|
2488
2523
|
}
|
|
2489
2524
|
async ensureDirectories() {
|
|
2490
2525
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2491
|
-
await mkdir(
|
|
2492
|
-
await mkdir(
|
|
2493
|
-
await mkdir(
|
|
2526
|
+
await mkdir(path2.join(this.factsDir, today), { recursive: true });
|
|
2527
|
+
await mkdir(path2.join(this.proceduresDir, today), { recursive: true });
|
|
2528
|
+
await mkdir(path2.join(this.reasoningTracesDir, today), { recursive: true });
|
|
2494
2529
|
await mkdir(this.correctionsDir, { recursive: true });
|
|
2495
2530
|
await mkdir(this.entitiesDir, { recursive: true });
|
|
2496
2531
|
await mkdir(this.stateDir, { recursive: true });
|
|
@@ -2500,7 +2535,7 @@ var StorageManager = class _StorageManager {
|
|
|
2500
2535
|
await mkdir(this.identityIncidentsDir, { recursive: true });
|
|
2501
2536
|
await mkdir(this.identityAuditsWeeklyDir, { recursive: true });
|
|
2502
2537
|
await mkdir(this.identityAuditsMonthlyDir, { recursive: true });
|
|
2503
|
-
await mkdir(
|
|
2538
|
+
await mkdir(path2.join(this.baseDir, "config"), { recursive: true });
|
|
2504
2539
|
}
|
|
2505
2540
|
async writeMemory(category, content, options = {}) {
|
|
2506
2541
|
await this.ensureDirectories();
|
|
@@ -2570,15 +2605,15 @@ ${sanitized.text}
|
|
|
2570
2605
|
`;
|
|
2571
2606
|
let filePath;
|
|
2572
2607
|
if (category === "correction") {
|
|
2573
|
-
filePath =
|
|
2608
|
+
filePath = path2.join(this.correctionsDir, `${id}.md`);
|
|
2574
2609
|
} else if (category === "procedure") {
|
|
2575
|
-
await mkdir(
|
|
2576
|
-
filePath =
|
|
2610
|
+
await mkdir(path2.join(this.proceduresDir, today), { recursive: true });
|
|
2611
|
+
filePath = path2.join(this.proceduresDir, today, `${id}.md`);
|
|
2577
2612
|
} else if (category === "reasoning_trace") {
|
|
2578
|
-
await mkdir(
|
|
2579
|
-
filePath =
|
|
2613
|
+
await mkdir(path2.join(this.reasoningTracesDir, today), { recursive: true });
|
|
2614
|
+
filePath = path2.join(this.reasoningTracesDir, today, `${id}.md`);
|
|
2580
2615
|
} else {
|
|
2581
|
-
filePath =
|
|
2616
|
+
filePath = path2.join(this.factsDir, today, `${id}.md`);
|
|
2582
2617
|
}
|
|
2583
2618
|
await this.snapshotBeforeWrite(filePath, "write");
|
|
2584
2619
|
await writeMaybeEncryptedFile(filePath, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
@@ -2693,7 +2728,7 @@ ${sanitized.text}
|
|
|
2693
2728
|
await this.ensureDirectories();
|
|
2694
2729
|
const now = /* @__PURE__ */ new Date();
|
|
2695
2730
|
const day = now.toISOString().slice(0, 10);
|
|
2696
|
-
const dir =
|
|
2731
|
+
const dir = path2.join(this.artifactsDir, day);
|
|
2697
2732
|
await mkdir(dir, { recursive: true });
|
|
2698
2733
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
2699
2734
|
const fm = {
|
|
@@ -2717,7 +2752,7 @@ ${sanitized.text}
|
|
|
2717
2752
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
2718
2753
|
return "";
|
|
2719
2754
|
}
|
|
2720
|
-
const filePath =
|
|
2755
|
+
const filePath = path2.join(dir, `${id}.md`);
|
|
2721
2756
|
await writeMaybeEncryptedFile(filePath, `${serializeFrontmatter(fm)}
|
|
2722
2757
|
|
|
2723
2758
|
${sanitized.text}
|
|
@@ -2745,7 +2780,7 @@ ${sanitized.text}
|
|
|
2745
2780
|
try {
|
|
2746
2781
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
2747
2782
|
for (const entry of entries) {
|
|
2748
|
-
const fullPath =
|
|
2783
|
+
const fullPath = path2.join(dir, entry.name);
|
|
2749
2784
|
if (entry.isDirectory()) {
|
|
2750
2785
|
await readDir(fullPath);
|
|
2751
2786
|
continue;
|
|
@@ -2811,7 +2846,7 @@ ${sanitized.text}
|
|
|
2811
2846
|
log.debug(`fuzzy match: "${normalized}" \u2192 existing "${match}"`);
|
|
2812
2847
|
normalized = match;
|
|
2813
2848
|
}
|
|
2814
|
-
const filePath =
|
|
2849
|
+
const filePath = path2.join(this.entitiesDir, `${normalized}.md`);
|
|
2815
2850
|
let entity = {
|
|
2816
2851
|
name,
|
|
2817
2852
|
type,
|
|
@@ -3046,7 +3081,7 @@ ${sanitized.text}
|
|
|
3046
3081
|
* per-process in-memory cache safe across process boundaries.
|
|
3047
3082
|
*/
|
|
3048
3083
|
invalidateColdMemoriesCache() {
|
|
3049
|
-
const coldRoot =
|
|
3084
|
+
const coldRoot = path2.join(this.baseDir, "cold");
|
|
3050
3085
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
3051
3086
|
this.bumpColdWriteVersion();
|
|
3052
3087
|
}
|
|
@@ -3074,7 +3109,7 @@ ${sanitized.text}
|
|
|
3074
3109
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
3075
3110
|
const subdirs = [];
|
|
3076
3111
|
for (const entry of entries) {
|
|
3077
|
-
const fullPath =
|
|
3112
|
+
const fullPath = path2.join(dir, entry.name);
|
|
3078
3113
|
if (entry.isDirectory()) {
|
|
3079
3114
|
subdirs.push(fullPath);
|
|
3080
3115
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -3087,10 +3122,9 @@ ${sanitized.text}
|
|
|
3087
3122
|
} catch {
|
|
3088
3123
|
}
|
|
3089
3124
|
};
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
await collectPaths(this.correctionsDir);
|
|
3125
|
+
for (const dir of RECALL_FALLBACK_DIRS) {
|
|
3126
|
+
await collectPaths(path2.join(this.baseDir, dir));
|
|
3127
|
+
}
|
|
3094
3128
|
return filePaths;
|
|
3095
3129
|
}
|
|
3096
3130
|
async readParsedMemoriesFromPaths(filePaths, batchSize) {
|
|
@@ -3158,7 +3192,7 @@ ${sanitized.text}
|
|
|
3158
3192
|
const correctionPaths = [];
|
|
3159
3193
|
const factPaths = [];
|
|
3160
3194
|
for (const filePath of filePaths) {
|
|
3161
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
3195
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path2.sep}`)) {
|
|
3162
3196
|
correctionPaths.push(filePath);
|
|
3163
3197
|
} else {
|
|
3164
3198
|
factPaths.push(filePath);
|
|
@@ -3278,7 +3312,7 @@ ${sanitized.text}
|
|
|
3278
3312
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
3279
3313
|
const subdirs = [];
|
|
3280
3314
|
for (const entry of entries) {
|
|
3281
|
-
const fullPath =
|
|
3315
|
+
const fullPath = path2.join(dir, entry.name);
|
|
3282
3316
|
if (entry.isDirectory()) {
|
|
3283
3317
|
subdirs.push(fullPath);
|
|
3284
3318
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -3307,7 +3341,7 @@ ${sanitized.text}
|
|
|
3307
3341
|
try {
|
|
3308
3342
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
3309
3343
|
for (const entry of entries) {
|
|
3310
|
-
const fullPath =
|
|
3344
|
+
const fullPath = path2.join(dir, entry.name);
|
|
3311
3345
|
if (entry.isDirectory()) {
|
|
3312
3346
|
await readDir(fullPath);
|
|
3313
3347
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -3352,11 +3386,11 @@ ${sanitized.text}
|
|
|
3352
3386
|
content: parsed.content
|
|
3353
3387
|
};
|
|
3354
3388
|
}
|
|
3355
|
-
const normalizedPath = filePath.split(
|
|
3389
|
+
const normalizedPath = filePath.split(path2.sep).join("/");
|
|
3356
3390
|
if (normalizedPath.includes("/entities/") && filePath.endsWith(".md")) {
|
|
3357
3391
|
const entity = parseEntityFile(raw, this.entitySchemas);
|
|
3358
3392
|
if (!entity.name) return null;
|
|
3359
|
-
const nameWithoutExt =
|
|
3393
|
+
const nameWithoutExt = path2.basename(filePath, ".md");
|
|
3360
3394
|
const fileMtime = entity.updated || await stat(filePath).then((s) => s.mtime.toISOString()).catch(() => (/* @__PURE__ */ new Date(0)).toISOString());
|
|
3361
3395
|
return {
|
|
3362
3396
|
path: filePath,
|
|
@@ -3380,7 +3414,7 @@ ${sanitized.text}
|
|
|
3380
3414
|
}
|
|
3381
3415
|
}
|
|
3382
3416
|
resolveTierRootDir(tier) {
|
|
3383
|
-
return tier === "cold" ?
|
|
3417
|
+
return tier === "cold" ? path2.join(this.baseDir, "cold") : this.baseDir;
|
|
3384
3418
|
}
|
|
3385
3419
|
resolveMemoryDateDir(memory) {
|
|
3386
3420
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -3395,18 +3429,18 @@ ${sanitized.text}
|
|
|
3395
3429
|
buildTierMemoryPath(memory, tier) {
|
|
3396
3430
|
const root = this.resolveTierRootDir(tier);
|
|
3397
3431
|
if (this.isArtifactMemory(memory)) {
|
|
3398
|
-
return
|
|
3432
|
+
return path2.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
3399
3433
|
}
|
|
3400
3434
|
if (memory.frontmatter.category === "correction") {
|
|
3401
|
-
return
|
|
3435
|
+
return path2.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
3402
3436
|
}
|
|
3403
3437
|
if (memory.frontmatter.category === "procedure") {
|
|
3404
|
-
return
|
|
3438
|
+
return path2.join(root, "procedures", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
3405
3439
|
}
|
|
3406
3440
|
if (memory.frontmatter.category === "reasoning_trace") {
|
|
3407
|
-
return
|
|
3441
|
+
return path2.join(root, "reasoning-traces", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
3408
3442
|
}
|
|
3409
|
-
return
|
|
3443
|
+
return path2.join(root, "facts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
3410
3444
|
}
|
|
3411
3445
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
3412
3446
|
const fileContent = `${serializeFrontmatter(memory.frontmatter)}
|
|
@@ -3418,8 +3452,8 @@ ${memory.content}
|
|
|
3418
3452
|
}
|
|
3419
3453
|
async moveMemoryToPath(memory, targetPath) {
|
|
3420
3454
|
await this.writeMemoryFileAtomic(targetPath, memory);
|
|
3421
|
-
const sourcePath =
|
|
3422
|
-
const destPath =
|
|
3455
|
+
const sourcePath = path2.resolve(memory.path);
|
|
3456
|
+
const destPath = path2.resolve(targetPath);
|
|
3423
3457
|
if (sourcePath !== destPath) {
|
|
3424
3458
|
try {
|
|
3425
3459
|
await unlink(memory.path);
|
|
@@ -3434,8 +3468,8 @@ ${memory.content}
|
|
|
3434
3468
|
}
|
|
3435
3469
|
async migrateMemoryToTier(memory, targetTier) {
|
|
3436
3470
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
3437
|
-
const sourcePath =
|
|
3438
|
-
const destPath =
|
|
3471
|
+
const sourcePath = path2.resolve(memory.path);
|
|
3472
|
+
const destPath = path2.resolve(targetPath);
|
|
3439
3473
|
if (sourcePath === destPath) {
|
|
3440
3474
|
return { changed: false, targetPath };
|
|
3441
3475
|
}
|
|
@@ -3461,7 +3495,7 @@ ${memory.content}
|
|
|
3461
3495
|
return { changed: true, targetPath };
|
|
3462
3496
|
}
|
|
3463
3497
|
get archiveDir() {
|
|
3464
|
-
return
|
|
3498
|
+
return path2.join(this.baseDir, "archive");
|
|
3465
3499
|
}
|
|
3466
3500
|
/**
|
|
3467
3501
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -3472,7 +3506,7 @@ ${memory.content}
|
|
|
3472
3506
|
try {
|
|
3473
3507
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
3474
3508
|
const today = now.toISOString().slice(0, 10);
|
|
3475
|
-
const destDir =
|
|
3509
|
+
const destDir = path2.join(this.archiveDir, today);
|
|
3476
3510
|
await mkdir(destDir, { recursive: true });
|
|
3477
3511
|
const updatedFm = {
|
|
3478
3512
|
...memory.frontmatter,
|
|
@@ -3484,7 +3518,7 @@ ${memory.content}
|
|
|
3484
3518
|
|
|
3485
3519
|
${memory.content}
|
|
3486
3520
|
`;
|
|
3487
|
-
const destPath =
|
|
3521
|
+
const destPath = path2.join(destDir, path2.basename(memory.path));
|
|
3488
3522
|
await writeMaybeEncryptedFile(destPath, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
3489
3523
|
await unlink(memory.path);
|
|
3490
3524
|
this.invalidateAllMemoriesCache();
|
|
@@ -3646,7 +3680,7 @@ ${memory.content}
|
|
|
3646
3680
|
`;
|
|
3647
3681
|
await writeMaybeEncryptedFile(memory.path, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
3648
3682
|
this.invalidateAllMemoriesCache();
|
|
3649
|
-
if (memory.path.includes(`${
|
|
3683
|
+
if (memory.path.includes(`${path2.sep}cold${path2.sep}`)) {
|
|
3650
3684
|
this.invalidateColdMemoriesCache();
|
|
3651
3685
|
}
|
|
3652
3686
|
try {
|
|
@@ -3718,7 +3752,7 @@ ${memory.content}
|
|
|
3718
3752
|
return deleted;
|
|
3719
3753
|
}
|
|
3720
3754
|
async loadBuffer() {
|
|
3721
|
-
const bufferPath =
|
|
3755
|
+
const bufferPath = path2.join(this.stateDir, "buffer.json");
|
|
3722
3756
|
try {
|
|
3723
3757
|
const raw = await this.readStorageSecureFile(bufferPath);
|
|
3724
3758
|
return JSON.parse(raw);
|
|
@@ -3730,11 +3764,11 @@ ${memory.content}
|
|
|
3730
3764
|
}
|
|
3731
3765
|
async saveBuffer(state) {
|
|
3732
3766
|
await this.ensureDirectories();
|
|
3733
|
-
const bufferPath =
|
|
3767
|
+
const bufferPath = path2.join(this.stateDir, "buffer.json");
|
|
3734
3768
|
await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));
|
|
3735
3769
|
}
|
|
3736
3770
|
async loadMeta() {
|
|
3737
|
-
const metaPath =
|
|
3771
|
+
const metaPath = path2.join(this.stateDir, "meta.json");
|
|
3738
3772
|
try {
|
|
3739
3773
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
3740
3774
|
const parsed = JSON.parse(raw);
|
|
@@ -3768,7 +3802,7 @@ ${memory.content}
|
|
|
3768
3802
|
}
|
|
3769
3803
|
async saveMeta(state) {
|
|
3770
3804
|
await this.ensureDirectories();
|
|
3771
|
-
const metaPath =
|
|
3805
|
+
const metaPath = path2.join(this.stateDir, "meta.json");
|
|
3772
3806
|
await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
|
|
3773
3807
|
}
|
|
3774
3808
|
async appendMemoryActionEvents(events) {
|
|
@@ -3938,7 +3972,7 @@ ${memory.content}
|
|
|
3938
3972
|
async appendReextractJobs(events) {
|
|
3939
3973
|
if (events.length === 0) return 0;
|
|
3940
3974
|
await this.ensureDirectories();
|
|
3941
|
-
const filePath =
|
|
3975
|
+
const filePath = path2.join(this.stateDir, "reextract-jobs.jsonl");
|
|
3942
3976
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
3943
3977
|
try {
|
|
3944
3978
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -3951,7 +3985,7 @@ ${memory.content}
|
|
|
3951
3985
|
}
|
|
3952
3986
|
async readReextractJobs(limit = 200) {
|
|
3953
3987
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
3954
|
-
const filePath =
|
|
3988
|
+
const filePath = path2.join(this.stateDir, "reextract-jobs.jsonl");
|
|
3955
3989
|
try {
|
|
3956
3990
|
const raw = await this.readStorageSecureFile(filePath);
|
|
3957
3991
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -4205,7 +4239,7 @@ ${memory.content}
|
|
|
4205
4239
|
const date = nowIso.slice(0, 10);
|
|
4206
4240
|
const id = this.generateId("incident");
|
|
4207
4241
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
4208
|
-
const filePath =
|
|
4242
|
+
const filePath = path2.join(this.identityIncidentsDir, `${date}-${id}.md`);
|
|
4209
4243
|
await this.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
4210
4244
|
return { ...incident, filePath };
|
|
4211
4245
|
}
|
|
@@ -4218,7 +4252,7 @@ ${memory.content}
|
|
|
4218
4252
|
const incidents = [];
|
|
4219
4253
|
for (const file of candidates) {
|
|
4220
4254
|
if (incidents.length >= cappedLimit) break;
|
|
4221
|
-
const filePath =
|
|
4255
|
+
const filePath = path2.join(this.identityIncidentsDir, file);
|
|
4222
4256
|
try {
|
|
4223
4257
|
const raw = await this.readStorageSecureFile(filePath);
|
|
4224
4258
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -4249,7 +4283,7 @@ ${memory.content}
|
|
|
4249
4283
|
await this.ensureDirectories();
|
|
4250
4284
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
4251
4285
|
const dir = period === "weekly" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;
|
|
4252
|
-
const filePath =
|
|
4286
|
+
const filePath = path2.join(dir, `${safeKey}.md`);
|
|
4253
4287
|
await this.writeStorageSecureFile(filePath, content);
|
|
4254
4288
|
return filePath;
|
|
4255
4289
|
}
|
|
@@ -4257,7 +4291,7 @@ ${memory.content}
|
|
|
4257
4291
|
try {
|
|
4258
4292
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
4259
4293
|
const dir = period === "weekly" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;
|
|
4260
|
-
return await this.readStorageSecureFile(
|
|
4294
|
+
return await this.readStorageSecureFile(path2.join(dir, `${safeKey}.md`));
|
|
4261
4295
|
} catch (err) {
|
|
4262
4296
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
4263
4297
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -4321,12 +4355,12 @@ ${memory.content}
|
|
|
4321
4355
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
4322
4356
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
4323
4357
|
if (directMatch) {
|
|
4324
|
-
const directPath =
|
|
4358
|
+
const directPath = path2.join(this.identityIncidentsDir, directMatch);
|
|
4325
4359
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
4326
4360
|
if (parsed?.id === id) return directPath;
|
|
4327
4361
|
}
|
|
4328
4362
|
for (const fileName of fileNames) {
|
|
4329
|
-
const filePath =
|
|
4363
|
+
const filePath = path2.join(this.identityIncidentsDir, fileName);
|
|
4330
4364
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
4331
4365
|
if (parsed?.id === id) return filePath;
|
|
4332
4366
|
}
|
|
@@ -4356,7 +4390,7 @@ ${question}
|
|
|
4356
4390
|
|
|
4357
4391
|
**Context:** ${context}
|
|
4358
4392
|
`;
|
|
4359
|
-
const filePath =
|
|
4393
|
+
const filePath = path2.join(this.questionsDir, `${id}.md`);
|
|
4360
4394
|
await writeFile(filePath, content, "utf-8");
|
|
4361
4395
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
4362
4396
|
this.invalidateQuestionsCache();
|
|
@@ -4380,7 +4414,7 @@ ${question}
|
|
|
4380
4414
|
const questions = [];
|
|
4381
4415
|
for (const file of files) {
|
|
4382
4416
|
if (!file.endsWith(".md")) continue;
|
|
4383
|
-
const filePath =
|
|
4417
|
+
const filePath = path2.join(this.questionsDir, file);
|
|
4384
4418
|
const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
4385
4419
|
const parsed = this.parseQuestionFile(raw, filePath);
|
|
4386
4420
|
if (parsed) {
|
|
@@ -4403,7 +4437,7 @@ ${question}
|
|
|
4403
4437
|
if (!match) return null;
|
|
4404
4438
|
const frontmatterStr = match[1];
|
|
4405
4439
|
const body = match[2].trim();
|
|
4406
|
-
const id = this.extractFrontmatterValue(frontmatterStr, "id") ??
|
|
4440
|
+
const id = this.extractFrontmatterValue(frontmatterStr, "id") ?? path2.basename(filePath, ".md");
|
|
4407
4441
|
const created = this.extractFrontmatterValue(frontmatterStr, "created") ?? "";
|
|
4408
4442
|
const priority = parseFloat(
|
|
4409
4443
|
this.extractFrontmatterValue(frontmatterStr, "priority") ?? "0.5"
|
|
@@ -4465,11 +4499,11 @@ ${question}
|
|
|
4465
4499
|
} catch {
|
|
4466
4500
|
}
|
|
4467
4501
|
const hygiene = opts?.hygiene;
|
|
4468
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
4502
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path2.basename(identityPath));
|
|
4469
4503
|
if (rotateEnabled) {
|
|
4470
4504
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
4471
4505
|
if (existing.length > maxBytes) {
|
|
4472
|
-
const archiveDir =
|
|
4506
|
+
const archiveDir = path2.join(workspaceDir, hygiene.archiveDir);
|
|
4473
4507
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
4474
4508
|
filePath: identityPath,
|
|
4475
4509
|
archiveDir,
|
|
@@ -4563,7 +4597,7 @@ ${reflection}
|
|
|
4563
4597
|
* Deduplicates by target+label.
|
|
4564
4598
|
*/
|
|
4565
4599
|
async addEntityRelationship(name, rel) {
|
|
4566
|
-
const filePath =
|
|
4600
|
+
const filePath = path2.join(this.entitiesDir, `${name}.md`);
|
|
4567
4601
|
let entity;
|
|
4568
4602
|
try {
|
|
4569
4603
|
const content = await this.readStorageSecureFile(filePath);
|
|
@@ -4588,7 +4622,7 @@ ${reflection}
|
|
|
4588
4622
|
* Prepends to the beginning, prunes oldest entries beyond maxEntries.
|
|
4589
4623
|
*/
|
|
4590
4624
|
async addEntityActivity(name, entry, maxEntries) {
|
|
4591
|
-
const filePath =
|
|
4625
|
+
const filePath = path2.join(this.entitiesDir, `${name}.md`);
|
|
4592
4626
|
let entity;
|
|
4593
4627
|
try {
|
|
4594
4628
|
const content = await this.readStorageSecureFile(filePath);
|
|
@@ -4611,7 +4645,7 @@ ${reflection}
|
|
|
4611
4645
|
* Add an alias to an entity file. Deduplicates.
|
|
4612
4646
|
*/
|
|
4613
4647
|
async addEntityAlias(name, alias) {
|
|
4614
|
-
const filePath =
|
|
4648
|
+
const filePath = path2.join(this.entitiesDir, `${name}.md`);
|
|
4615
4649
|
let entity;
|
|
4616
4650
|
try {
|
|
4617
4651
|
const content = await this.readStorageSecureFile(filePath);
|
|
@@ -4632,7 +4666,7 @@ ${reflection}
|
|
|
4632
4666
|
* Set or rewrite the synthesis layer of an entity file.
|
|
4633
4667
|
*/
|
|
4634
4668
|
async updateEntitySynthesis(name, synthesis, options = {}) {
|
|
4635
|
-
const filePath =
|
|
4669
|
+
const filePath = path2.join(this.entitiesDir, `${name}.md`);
|
|
4636
4670
|
let entity;
|
|
4637
4671
|
try {
|
|
4638
4672
|
const content = await this.readStorageSecureFile(filePath);
|
|
@@ -4670,7 +4704,7 @@ ${reflection}
|
|
|
4670
4704
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4671
4705
|
let synthesisTimelineCount;
|
|
4672
4706
|
try {
|
|
4673
|
-
const filePath =
|
|
4707
|
+
const filePath = path2.join(this.entitiesDir, `${name}.md`);
|
|
4674
4708
|
const content = await this.readStorageSecureFile(filePath);
|
|
4675
4709
|
synthesisTimelineCount = parseEntityFile(content, this.entitySchemas).timeline.length;
|
|
4676
4710
|
} catch (err) {
|
|
@@ -4753,7 +4787,7 @@ ${reflection}
|
|
|
4753
4787
|
if (!raw) continue;
|
|
4754
4788
|
const serialized = serializeEntityFile(parseEntityFile(raw, this.entitySchemas), this.entitySchemas);
|
|
4755
4789
|
if (raw.trimEnd() === serialized.trimEnd()) continue;
|
|
4756
|
-
await this.writeStorageSecureFile(
|
|
4790
|
+
await this.writeStorageSecureFile(path2.join(this.entitiesDir, `${entityName}.md`), serialized);
|
|
4757
4791
|
migrated += 1;
|
|
4758
4792
|
}
|
|
4759
4793
|
if (migrated > 0) {
|
|
@@ -4789,7 +4823,7 @@ ${reflection}
|
|
|
4789
4823
|
const results = await Promise.all(
|
|
4790
4824
|
batch.map(async (entry) => {
|
|
4791
4825
|
try {
|
|
4792
|
-
return await this.readStorageSecureFile(
|
|
4826
|
+
return await this.readStorageSecureFile(path2.join(this.entitiesDir, entry));
|
|
4793
4827
|
} catch (err) {
|
|
4794
4828
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
4795
4829
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -4935,7 +4969,7 @@ ${rows.join("\n")}
|
|
|
4935
4969
|
extraSections: []
|
|
4936
4970
|
};
|
|
4937
4971
|
for (const file of files) {
|
|
4938
|
-
const filePath =
|
|
4972
|
+
const filePath = path2.join(this.entitiesDir, file);
|
|
4939
4973
|
try {
|
|
4940
4974
|
const content = await this.readStorageSecureFile(filePath);
|
|
4941
4975
|
const parsed = parseEntityFile(content, this.entitySchemas);
|
|
@@ -5066,10 +5100,10 @@ ${rows.join("\n")}
|
|
|
5066
5100
|
}
|
|
5067
5101
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
5068
5102
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
5069
|
-
const canonicalPath =
|
|
5103
|
+
const canonicalPath = path2.join(this.entitiesDir, `${canonical}.md`);
|
|
5070
5104
|
await this.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.entitySchemas));
|
|
5071
5105
|
for (const file of files) {
|
|
5072
|
-
const filePath =
|
|
5106
|
+
const filePath = path2.join(this.entitiesDir, file);
|
|
5073
5107
|
if (filePath !== canonicalPath) {
|
|
5074
5108
|
try {
|
|
5075
5109
|
await unlink(filePath);
|
|
@@ -5168,7 +5202,7 @@ ${memory.content}
|
|
|
5168
5202
|
const filePaths = await this.collectActiveMemoryPaths();
|
|
5169
5203
|
const foundIds = /* @__PURE__ */ new Set();
|
|
5170
5204
|
for (const filePath of filePaths) {
|
|
5171
|
-
const basename =
|
|
5205
|
+
const basename = path2.basename(filePath, ".md");
|
|
5172
5206
|
if (wantedIds.has(basename)) {
|
|
5173
5207
|
foundIds.add(basename);
|
|
5174
5208
|
if (foundIds.size === wantedIds.size) break;
|
|
@@ -5268,15 +5302,15 @@ ${sanitized.text}
|
|
|
5268
5302
|
`;
|
|
5269
5303
|
let filePath;
|
|
5270
5304
|
if (category === "correction") {
|
|
5271
|
-
filePath =
|
|
5305
|
+
filePath = path2.join(this.correctionsDir, `${id}.md`);
|
|
5272
5306
|
} else if (category === "procedure") {
|
|
5273
|
-
await mkdir(
|
|
5274
|
-
filePath =
|
|
5307
|
+
await mkdir(path2.join(this.proceduresDir, today), { recursive: true });
|
|
5308
|
+
filePath = path2.join(this.proceduresDir, today, `${id}.md`);
|
|
5275
5309
|
} else if (category === "reasoning_trace") {
|
|
5276
|
-
await mkdir(
|
|
5277
|
-
filePath =
|
|
5310
|
+
await mkdir(path2.join(this.reasoningTracesDir, today), { recursive: true });
|
|
5311
|
+
filePath = path2.join(this.reasoningTracesDir, today, `${id}.md`);
|
|
5278
5312
|
} else {
|
|
5279
|
-
filePath =
|
|
5313
|
+
filePath = path2.join(this.factsDir, today, `${id}.md`);
|
|
5280
5314
|
}
|
|
5281
5315
|
await this.writeStorageSecureFile(filePath, fileContent);
|
|
5282
5316
|
log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);
|
|
@@ -5345,14 +5379,14 @@ Reason: ${reason}`, {
|
|
|
5345
5379
|
// Memory Summarization (Phase 4A)
|
|
5346
5380
|
// ---------------------------------------------------------------------------
|
|
5347
5381
|
get summariesDir() {
|
|
5348
|
-
return
|
|
5382
|
+
return path2.join(this.baseDir, "summaries");
|
|
5349
5383
|
}
|
|
5350
5384
|
/**
|
|
5351
5385
|
* Write a memory summary.
|
|
5352
5386
|
*/
|
|
5353
5387
|
async writeSummary(summary) {
|
|
5354
5388
|
await mkdir(this.summariesDir, { recursive: true });
|
|
5355
|
-
const filePath =
|
|
5389
|
+
const filePath = path2.join(this.summariesDir, `${summary.id}.json`);
|
|
5356
5390
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
5357
5391
|
log.debug(`wrote summary ${summary.id}`);
|
|
5358
5392
|
}
|
|
@@ -5365,7 +5399,7 @@ Reason: ${reason}`, {
|
|
|
5365
5399
|
const summaries = [];
|
|
5366
5400
|
for (const file of files) {
|
|
5367
5401
|
if (!file.endsWith(".json")) continue;
|
|
5368
|
-
const filePath =
|
|
5402
|
+
const filePath = path2.join(this.summariesDir, file);
|
|
5369
5403
|
const raw = await this.readStorageSecureFile(filePath);
|
|
5370
5404
|
summaries.push(JSON.parse(raw));
|
|
5371
5405
|
}
|
|
@@ -5426,7 +5460,7 @@ ${memory.content}
|
|
|
5426
5460
|
* Save topic scores to meta.json.
|
|
5427
5461
|
*/
|
|
5428
5462
|
async saveTopics(topics) {
|
|
5429
|
-
const metaPath =
|
|
5463
|
+
const metaPath = path2.join(this.stateDir, "topics.json");
|
|
5430
5464
|
await mkdir(this.stateDir, { recursive: true });
|
|
5431
5465
|
await this.writeStorageSecureFile(metaPath, JSON.stringify({ topics, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
5432
5466
|
log.debug(`saved ${topics.length} topic scores`);
|
|
@@ -5435,7 +5469,7 @@ ${memory.content}
|
|
|
5435
5469
|
* Load topic scores from meta.json.
|
|
5436
5470
|
*/
|
|
5437
5471
|
async loadTopics() {
|
|
5438
|
-
const metaPath =
|
|
5472
|
+
const metaPath = path2.join(this.stateDir, "topics.json");
|
|
5439
5473
|
try {
|
|
5440
5474
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
5441
5475
|
return JSON.parse(raw);
|
|
@@ -5513,6 +5547,9 @@ ${memory.content}
|
|
|
5513
5547
|
};
|
|
5514
5548
|
|
|
5515
5549
|
export {
|
|
5550
|
+
ALL_CATEGORY_DIRS,
|
|
5551
|
+
ALL_CATEGORY_KEYS,
|
|
5552
|
+
getCategoryDir,
|
|
5516
5553
|
normalizeEntityName,
|
|
5517
5554
|
ContentHashIndex,
|
|
5518
5555
|
stripAttributesSuffix,
|
|
@@ -5524,4 +5561,4 @@ export {
|
|
|
5524
5561
|
serializeEntityFile,
|
|
5525
5562
|
StorageManager
|
|
5526
5563
|
};
|
|
5527
|
-
//# sourceMappingURL=chunk-
|
|
5564
|
+
//# sourceMappingURL=chunk-A4BTPHIN.js.map
|