@remnic/core 9.3.725 → 9.3.726
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.js +26 -25
- package/dist/access-cli.js +64 -62
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.js +33 -32
- package/dist/access-mcp.js +30 -29
- package/dist/access-operations-batch.js +27 -26
- package/dist/access-operations.js +29 -28
- package/dist/access-schema.js +3 -3
- package/dist/access-service.js +25 -24
- package/dist/active-recall.js +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/briefing.js +6 -5
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/causal-consolidation.js +7 -6
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-C6BWLYW5.js → chunk-2NBP25BG.js} +7 -7
- package/dist/{chunk-YUYPWJD3.js → chunk-3MS3QVX6.js} +2 -2
- package/dist/{chunk-FVZ2ISIX.js → chunk-3TUT4PWB.js} +2 -2
- package/dist/{chunk-HCVWF657.js → chunk-53EEQYE5.js} +7 -7
- package/dist/{chunk-TAPSNIMA.js → chunk-5CEJH5ZN.js} +4 -4
- package/dist/{chunk-D7EBTQ24.js → chunk-5NWYQUQC.js} +2 -2
- package/dist/{chunk-NT36GU6X.js → chunk-5OOA7SGX.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-5W7CTZ2E.js} +4 -4
- package/dist/{chunk-QR67FU5G.js → chunk-6AFVIOVZ.js} +2 -2
- package/dist/{chunk-UBHVAGO7.js → chunk-6WAJQKBS.js} +2 -2
- package/dist/{chunk-6CWGS2LY.js → chunk-7NS7AWMZ.js} +3 -3
- package/dist/{chunk-T55EGZSJ.js → chunk-BB57OZWC.js} +2 -2
- package/dist/{chunk-YQMPUYHE.js → chunk-BBIE7W52.js} +2 -2
- package/dist/{chunk-WAFDHKES.js → chunk-BEUCACTV.js} +2 -2
- package/dist/{chunk-4SF232E6.js → chunk-BIA7ELIB.js} +17 -5
- package/dist/chunk-BIA7ELIB.js.map +1 -0
- package/dist/{chunk-GZQXOQQ2.js → chunk-DCKNMLEQ.js} +4 -4
- package/dist/{chunk-ZUDM75KG.js → chunk-DCWIQFNA.js} +4 -4
- package/dist/{chunk-VI5SGGXB.js → chunk-DQXPJ6HD.js} +4 -4
- package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
- package/dist/{chunk-Z3FGC3QE.js → chunk-EZNDNMRH.js} +139 -30
- package/dist/chunk-EZNDNMRH.js.map +1 -0
- package/dist/{chunk-FACTVMXQ.js → chunk-FO3HO52S.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-JJJCVCCQ.js → chunk-JPUT5NGH.js} +2 -2
- package/dist/{chunk-5OPYYPJN.js → chunk-K4ZNARDO.js} +2 -2
- package/dist/{chunk-4WZ3J7M6.js → chunk-KJR66XOM.js} +2 -2
- package/dist/{chunk-LD53WPMU.js → chunk-LQ6JI4VH.js} +4 -4
- package/dist/chunk-LTHVM4XN.js +109 -0
- package/dist/chunk-LTHVM4XN.js.map +1 -0
- package/dist/{chunk-4R3CGCI5.js → chunk-MQVKHFIU.js} +16 -13
- package/dist/chunk-MQVKHFIU.js.map +1 -0
- package/dist/{chunk-FXCIOLRB.js → chunk-NPL7VDM6.js} +2 -2
- package/dist/{chunk-KLFYKC3K.js → chunk-OAHOL3ZC.js} +112 -72
- package/dist/chunk-OAHOL3ZC.js.map +1 -0
- package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
- package/dist/{chunk-I2HL5M6T.js → chunk-PLG6JHQS.js} +42 -42
- package/dist/{chunk-KGZF2VO3.js → chunk-Q6D75LVH.js} +15 -15
- package/dist/{chunk-SC2YAWRF.js → chunk-RRHHQYJS.js} +2 -2
- package/dist/{chunk-J334N6QV.js → chunk-TA3Y6GEX.js} +2 -2
- package/dist/{chunk-FN6QP7JQ.js → chunk-TQQH2FTX.js} +4 -4
- package/dist/{chunk-DF3I6JGP.js → chunk-UKTDXTWX.js} +15 -15
- package/dist/{chunk-ARV3AUOM.js → chunk-UNNDFYUX.js} +5 -5
- package/dist/{chunk-ZK2L72VN.js → chunk-UQSVUEN2.js} +2 -2
- package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/{chunk-H7HUQIY7.js → chunk-V7CMKMHM.js} +3 -3
- package/dist/chunk-W5H6ZRPT.js +14 -0
- package/dist/chunk-W5H6ZRPT.js.map +1 -0
- package/dist/{chunk-TT5U3UDO.js → chunk-WGTWGDR5.js} +5 -5
- package/dist/{chunk-YQGHW5ML.js → chunk-WRFKZEO6.js} +4 -4
- package/dist/{chunk-WM7DNKBD.js → chunk-YTZ3VGC7.js} +2 -2
- package/dist/cli.js +54 -53
- package/dist/compounding/engine.js +6 -5
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.js +6 -5
- package/dist/connectors/index.js +6 -5
- package/dist/content-hash.d.ts +14 -0
- package/dist/content-hash.js +10 -0
- package/dist/content-hash.js.map +1 -0
- package/dist/conversation-index/backend.js +2 -2
- package/dist/dashboard-runtime.js +2 -2
- package/dist/entity-retrieval.js +6 -5
- package/dist/extraction-redaction-rules.d.ts +33 -0
- package/dist/extraction-redaction-rules.js +14 -0
- package/dist/extraction-redaction-rules.js.map +1 -0
- package/dist/extraction.js +2 -2
- package/dist/{forget-OEE5OELK.js → forget-WYLR4ZFV.js} +2 -2
- package/dist/index.js +102 -100
- package/dist/index.js.map +1 -1
- package/dist/lcm/index.js +3 -3
- package/dist/maintenance/memory-governance.js +6 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +6 -5
- package/dist/maintenance/rebuild-memory-projection.js +7 -6
- package/dist/namespaces/migrate.js +16 -15
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.js +6 -5
- package/dist/operator-toolkit.js +24 -23
- package/dist/orchestration/maintenance.js +8 -7
- package/dist/orchestrator.js +48 -46
- package/dist/resume-bundles.js +2 -2
- package/dist/search/factory.js +8 -8
- package/dist/search/index.js +12 -12
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/semantic-consolidation.js +7 -6
- package/dist/semantic-rule-promotion.js +6 -5
- package/dist/semantic-rule-verifier.js +6 -5
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +6 -5
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/verified-recall.js +6 -5
- package/package.json +2 -2
- package/src/config.test.ts +50 -0
- package/src/config.ts +21 -4
- package/src/content-hash.ts +24 -0
- package/src/correction/correction-access-wiring.ts +104 -19
- package/src/correction/correction-contract.ts +68 -10
- package/src/correction/correction-executor.test.ts +112 -2
- package/src/correction/correction-executor.ts +65 -5
- package/src/correction/correction-planner.test.ts +47 -0
- package/src/correction/correction-planner.ts +40 -1
- package/src/correction/correction-storage-integration.test.ts +183 -0
- package/src/extraction-redaction-rules.test.ts +213 -0
- package/src/extraction-redaction-rules.ts +208 -0
- package/src/orchestrator.ts +52 -1
- package/src/storage.ts +6 -10
- package/dist/chunk-4R3CGCI5.js.map +0 -1
- package/dist/chunk-4SF232E6.js.map +0 -1
- package/dist/chunk-KLFYKC3K.js.map +0 -1
- package/dist/chunk-Z3FGC3QE.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{chunk-C6BWLYW5.js.map → chunk-2NBP25BG.js.map} +0 -0
- /package/dist/{chunk-YUYPWJD3.js.map → chunk-3MS3QVX6.js.map} +0 -0
- /package/dist/{chunk-FVZ2ISIX.js.map → chunk-3TUT4PWB.js.map} +0 -0
- /package/dist/{chunk-HCVWF657.js.map → chunk-53EEQYE5.js.map} +0 -0
- /package/dist/{chunk-TAPSNIMA.js.map → chunk-5CEJH5ZN.js.map} +0 -0
- /package/dist/{chunk-D7EBTQ24.js.map → chunk-5NWYQUQC.js.map} +0 -0
- /package/dist/{chunk-NT36GU6X.js.map → chunk-5OOA7SGX.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-5W7CTZ2E.js.map} +0 -0
- /package/dist/{chunk-QR67FU5G.js.map → chunk-6AFVIOVZ.js.map} +0 -0
- /package/dist/{chunk-UBHVAGO7.js.map → chunk-6WAJQKBS.js.map} +0 -0
- /package/dist/{chunk-6CWGS2LY.js.map → chunk-7NS7AWMZ.js.map} +0 -0
- /package/dist/{chunk-T55EGZSJ.js.map → chunk-BB57OZWC.js.map} +0 -0
- /package/dist/{chunk-YQMPUYHE.js.map → chunk-BBIE7W52.js.map} +0 -0
- /package/dist/{chunk-WAFDHKES.js.map → chunk-BEUCACTV.js.map} +0 -0
- /package/dist/{chunk-GZQXOQQ2.js.map → chunk-DCKNMLEQ.js.map} +0 -0
- /package/dist/{chunk-ZUDM75KG.js.map → chunk-DCWIQFNA.js.map} +0 -0
- /package/dist/{chunk-VI5SGGXB.js.map → chunk-DQXPJ6HD.js.map} +0 -0
- /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
- /package/dist/{chunk-FACTVMXQ.js.map → chunk-FO3HO52S.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-JJJCVCCQ.js.map → chunk-JPUT5NGH.js.map} +0 -0
- /package/dist/{chunk-5OPYYPJN.js.map → chunk-K4ZNARDO.js.map} +0 -0
- /package/dist/{chunk-4WZ3J7M6.js.map → chunk-KJR66XOM.js.map} +0 -0
- /package/dist/{chunk-LD53WPMU.js.map → chunk-LQ6JI4VH.js.map} +0 -0
- /package/dist/{chunk-FXCIOLRB.js.map → chunk-NPL7VDM6.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-I2HL5M6T.js.map → chunk-PLG6JHQS.js.map} +0 -0
- /package/dist/{chunk-KGZF2VO3.js.map → chunk-Q6D75LVH.js.map} +0 -0
- /package/dist/{chunk-SC2YAWRF.js.map → chunk-RRHHQYJS.js.map} +0 -0
- /package/dist/{chunk-J334N6QV.js.map → chunk-TA3Y6GEX.js.map} +0 -0
- /package/dist/{chunk-FN6QP7JQ.js.map → chunk-TQQH2FTX.js.map} +0 -0
- /package/dist/{chunk-DF3I6JGP.js.map → chunk-UKTDXTWX.js.map} +0 -0
- /package/dist/{chunk-ARV3AUOM.js.map → chunk-UNNDFYUX.js.map} +0 -0
- /package/dist/{chunk-ZK2L72VN.js.map → chunk-UQSVUEN2.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-H7HUQIY7.js.map → chunk-V7CMKMHM.js.map} +0 -0
- /package/dist/{chunk-TT5U3UDO.js.map → chunk-WGTWGDR5.js.map} +0 -0
- /package/dist/{chunk-YQGHW5ML.js.map → chunk-WRFKZEO6.js.map} +0 -0
- /package/dist/{chunk-WM7DNKBD.js.map → chunk-YTZ3VGC7.js.map} +0 -0
- /package/dist/{forget-OEE5OELK.js.map → forget-WYLR4ZFV.js.map} +0 -0
|
@@ -19,14 +19,14 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
LocalLlmClient
|
|
21
21
|
} from "./chunk-24D66MMN.js";
|
|
22
|
-
import {
|
|
23
|
-
delinearize
|
|
24
|
-
} from "./chunk-VEWZZM3H.js";
|
|
25
22
|
import {
|
|
26
23
|
buildExtensionsFooterForSummary,
|
|
27
24
|
formatDaySummaryMemories,
|
|
28
25
|
loadDaySummaryPrompt
|
|
29
26
|
} from "./chunk-EO5QWINU.js";
|
|
27
|
+
import {
|
|
28
|
+
delinearize
|
|
29
|
+
} from "./chunk-VEWZZM3H.js";
|
|
30
30
|
import {
|
|
31
31
|
applyWorkExtractionBoundary
|
|
32
32
|
} from "./chunk-EI6V5UXY.js";
|
|
@@ -2422,4 +2422,4 @@ ${memoryList}` }
|
|
|
2422
2422
|
export {
|
|
2423
2423
|
ExtractionEngine
|
|
2424
2424
|
};
|
|
2425
|
-
//# sourceMappingURL=chunk-
|
|
2425
|
+
//# sourceMappingURL=chunk-DCKNMLEQ.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
failOpenFaissHealth
|
|
3
|
+
} from "./chunk-XBZQRZ6G.js";
|
|
1
4
|
import {
|
|
2
5
|
rebuildConversationChunksFailOpen,
|
|
3
6
|
upsertConversationChunksFailOpen
|
|
@@ -6,9 +9,6 @@ import {
|
|
|
6
9
|
searchConversationIndex,
|
|
7
10
|
searchConversationIndexFaissFailOpen
|
|
8
11
|
} from "./chunk-SJHM6I4J.js";
|
|
9
|
-
import {
|
|
10
|
-
failOpenFaissHealth
|
|
11
|
-
} from "./chunk-XBZQRZ6G.js";
|
|
12
12
|
|
|
13
13
|
// src/conversation-index/backend.ts
|
|
14
14
|
function createConversationIndexBackend(options) {
|
|
@@ -235,4 +235,4 @@ function createFaissBackend(getFaiss) {
|
|
|
235
235
|
export {
|
|
236
236
|
createConversationIndexBackend
|
|
237
237
|
};
|
|
238
|
-
//# sourceMappingURL=chunk-
|
|
238
|
+
//# sourceMappingURL=chunk-DCWIQFNA.js.map
|
|
@@ -21,16 +21,16 @@ import {
|
|
|
21
21
|
} from "./chunk-T4WDJPEZ.js";
|
|
22
22
|
import {
|
|
23
23
|
defineOperation
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-5OOA7SGX.js";
|
|
25
25
|
import {
|
|
26
26
|
EngramAccessInputError
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-Q6D75LVH.js";
|
|
28
28
|
import {
|
|
29
29
|
projectTagProjectId
|
|
30
30
|
} from "./chunk-J6BH2OBA.js";
|
|
31
31
|
import {
|
|
32
32
|
validateBriefingFormat
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-KJR66XOM.js";
|
|
34
34
|
import {
|
|
35
35
|
resolvePrincipal
|
|
36
36
|
} from "./chunk-UZYLX7M6.js";
|
|
@@ -417,4 +417,4 @@ defineOperation({ name: "offline_sync_snapshot_stream", description: "SSE stream
|
|
|
417
417
|
defineOperation({ name: "graph_events", description: "SSE graph events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
|
|
418
418
|
defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
|
|
419
419
|
defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
|
|
420
|
-
//# sourceMappingURL=chunk-
|
|
420
|
+
//# sourceMappingURL=chunk-DQXPJ6HD.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
diffGraphSnapshots
|
|
3
|
-
} from "./chunk-AUDJPF4N.js";
|
|
4
1
|
import {
|
|
5
2
|
graphSnapshotFromMemoryDir
|
|
6
3
|
} from "./chunk-44442YCH.js";
|
|
4
|
+
import {
|
|
5
|
+
diffGraphSnapshots
|
|
6
|
+
} from "./chunk-AUDJPF4N.js";
|
|
7
7
|
|
|
8
8
|
// src/dashboard-runtime.ts
|
|
9
9
|
import { createHash, timingSafeEqual } from "crypto";
|
|
@@ -370,4 +370,4 @@ var GraphDashboardServer = class {
|
|
|
370
370
|
export {
|
|
371
371
|
GraphDashboardServer
|
|
372
372
|
};
|
|
373
|
-
//# sourceMappingURL=chunk-
|
|
373
|
+
//# sourceMappingURL=chunk-EZ25VE3G.js.map
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
enqueuePassiveCorrectionNotification
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KJR66XOM.js";
|
|
4
4
|
import {
|
|
5
5
|
stripAttributesSuffix
|
|
6
6
|
} from "./chunk-SVOZFLIQ.js";
|
|
7
7
|
import {
|
|
8
8
|
serializeMutations
|
|
9
9
|
} from "./chunk-LTJAMRGI.js";
|
|
10
|
+
import {
|
|
11
|
+
supersessionKeysForFact
|
|
12
|
+
} from "./chunk-TKZ3AL5V.js";
|
|
13
|
+
import {
|
|
14
|
+
computeContentHash
|
|
15
|
+
} from "./chunk-W5H6ZRPT.js";
|
|
16
|
+
import {
|
|
17
|
+
sanitizeMemoryContent
|
|
18
|
+
} from "./chunk-5GKPFL3S.js";
|
|
10
19
|
import {
|
|
11
20
|
log
|
|
12
21
|
} from "./chunk-NU3CSQ4H.js";
|
|
@@ -79,22 +88,68 @@ function validateRedactionPattern(pattern) {
|
|
|
79
88
|
`redaction_rule.pattern exceeds the ${REDACTION_PATTERN_MAX}-character bound.`
|
|
80
89
|
);
|
|
81
90
|
}
|
|
82
|
-
if (isRegexLike(trimmed) &&
|
|
91
|
+
if (isRegexLike(trimmed) && isUnsafeRedactionRegex(trimmed)) {
|
|
83
92
|
throw new CorrectionContractError(
|
|
84
|
-
"redaction_rule.pattern is
|
|
93
|
+
"redaction_rule.pattern is unsafe \u2014 use a bounded literal or a regex without nested quantifiers / overlapping alternation."
|
|
85
94
|
);
|
|
86
95
|
}
|
|
96
|
+
if (isRegexLike(trimmed)) {
|
|
97
|
+
const regexBody = trimmed.slice(1, -1);
|
|
98
|
+
if (regexBody.length === 0) {
|
|
99
|
+
throw new CorrectionContractError("redaction_rule.pattern body is empty \u2014 use a non-empty regex.");
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
if (new RegExp(regexBody).test("")) {
|
|
103
|
+
throw new CorrectionContractError(
|
|
104
|
+
"redaction_rule.pattern matches the empty string \u2014 it would withhold every fact."
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
} catch (e) {
|
|
108
|
+
if (e instanceof CorrectionContractError) throw e;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
87
111
|
return trimmed;
|
|
88
112
|
}
|
|
89
113
|
function isRegexLike(pattern) {
|
|
90
|
-
|
|
91
|
-
return /[\\^$.|?*+()[\]{}]/.test(pattern);
|
|
114
|
+
return pattern.startsWith("/") && pattern.endsWith("/") && pattern.length >= 2;
|
|
92
115
|
}
|
|
93
|
-
function
|
|
116
|
+
function isUnsafeRedactionRegex(pattern) {
|
|
94
117
|
const body = pattern.startsWith("/") && pattern.endsWith("/") ? pattern.slice(1, -1) : pattern;
|
|
95
118
|
if (/(?:^|[^\\])\(\.\*\)|(?:^|[^\\])\.\*|(?:^|[^\\])\.\+|^\.([^*+]?)$/.test(body)) {
|
|
96
119
|
return true;
|
|
97
120
|
}
|
|
121
|
+
if (body.length > 512) return true;
|
|
122
|
+
for (let i = 0; i < body.length; i++) {
|
|
123
|
+
if (body[i] !== "(") continue;
|
|
124
|
+
let depth = 1;
|
|
125
|
+
let j = i + 1;
|
|
126
|
+
while (j < body.length && depth > 0) {
|
|
127
|
+
if (body[j] === "\\") {
|
|
128
|
+
j += 2;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (body[j] === "(") depth++;
|
|
132
|
+
else if (body[j] === ")") depth--;
|
|
133
|
+
j++;
|
|
134
|
+
}
|
|
135
|
+
if (depth !== 0) continue;
|
|
136
|
+
const afterGroup = body[j];
|
|
137
|
+
if (afterGroup !== "+" && afterGroup !== "*" && afterGroup !== "{") continue;
|
|
138
|
+
const groupBody = body.slice(i + 1, j - 1);
|
|
139
|
+
if (/[+*?]$/.test(groupBody) || /\{\d+,?\d*\}[+*?]?$/.test(groupBody)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (groupBody.includes("|")) {
|
|
143
|
+
const branches = groupBody.split("|");
|
|
144
|
+
if (branches.length >= 2) {
|
|
145
|
+
const firstChars = new Set(branches.map((b) => b[0]).filter(Boolean));
|
|
146
|
+
if (firstChars.size < branches.filter((b) => b.length > 0).length) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
i = j;
|
|
152
|
+
}
|
|
98
153
|
return false;
|
|
99
154
|
}
|
|
100
155
|
function validateCorrectionAction(action) {
|
|
@@ -198,11 +253,13 @@ var CorrectionContractError = class extends Error {
|
|
|
198
253
|
|
|
199
254
|
// src/correction/correction-access-wiring.ts
|
|
200
255
|
import path2 from "path";
|
|
256
|
+
import { createHash } from "crypto";
|
|
201
257
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
202
258
|
|
|
203
259
|
// src/correction/correction-planner.ts
|
|
204
260
|
import { mkdir, readFile, rename, unlink, readdir, writeFile } from "fs/promises";
|
|
205
261
|
import path from "path";
|
|
262
|
+
var REDACTED_REQUEST_TEXT = "[redacted \u2014 never-store/redaction correction text withheld from the pending-plan file]";
|
|
206
263
|
var CorrectionPlanner = class {
|
|
207
264
|
constructor(deps) {
|
|
208
265
|
this.deps = deps;
|
|
@@ -386,10 +443,12 @@ var CorrectionPlanner = class {
|
|
|
386
443
|
async persist(plan) {
|
|
387
444
|
const dir = await this.pendingDir(plan.namespace);
|
|
388
445
|
const target = path.join(dir, `${plan.planId}.json`);
|
|
446
|
+
const sensitive = plan.classification === "never_store" || plan.actions.some((a) => a.kind === "redaction_rule");
|
|
447
|
+
const persistedPlan = sensitive ? { ...plan, request: { ...plan.request, text: REDACTED_REQUEST_TEXT } } : plan;
|
|
389
448
|
await serializeMutations(`correction-plan:${target}`, async () => {
|
|
390
449
|
await mkdir(dir, { recursive: true });
|
|
391
450
|
const tmp = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
392
|
-
await writeFile(tmp, `${JSON.stringify(
|
|
451
|
+
await writeFile(tmp, `${JSON.stringify(persistedPlan)}
|
|
393
452
|
`, "utf-8");
|
|
394
453
|
await rename(tmp, target);
|
|
395
454
|
});
|
|
@@ -451,6 +510,11 @@ var CorrectionPlanner = class {
|
|
|
451
510
|
const plan = parsePlan(raw);
|
|
452
511
|
if (!plan) return;
|
|
453
512
|
plan.status = status;
|
|
513
|
+
if (status !== "applying") {
|
|
514
|
+
plan.actions = plan.actions.map(
|
|
515
|
+
(a) => a.kind === "redaction_rule" ? { ...a, pattern: "[redacted \u2014 pattern applied]" } : a
|
|
516
|
+
);
|
|
517
|
+
}
|
|
454
518
|
const tmp = `${file}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
455
519
|
await writeFile(tmp, `${JSON.stringify(plan)}
|
|
456
520
|
`, "utf-8");
|
|
@@ -652,7 +716,7 @@ var CorrectionExecutor = class {
|
|
|
652
716
|
continue;
|
|
653
717
|
}
|
|
654
718
|
const destId = await this.deps.rescopeMemory(namespace, action.memoryId, action.toNamespace);
|
|
655
|
-
results.push({ action, status: "applied", memoryId:
|
|
719
|
+
results.push({ action, status: "applied", memoryId: destId });
|
|
656
720
|
appliedTouched.push(action.memoryId);
|
|
657
721
|
try {
|
|
658
722
|
await this.deps.propagate(action.toNamespace, [destId]);
|
|
@@ -726,7 +790,14 @@ var CorrectionExecutor = class {
|
|
|
726
790
|
sourceMemoryId: memoryId,
|
|
727
791
|
rawContent: memory.rawContent,
|
|
728
792
|
...memory.entityRef ? { entityRef: memory.entityRef } : {},
|
|
729
|
-
...memory.supersessionKey ? { supersessionKey: memory.supersessionKey } : {}
|
|
793
|
+
...memory.supersessionKey ? { supersessionKey: memory.supersessionKey } : {},
|
|
794
|
+
// #1672 item 4: carry the canonical contentHash (exact tier) and the
|
|
795
|
+
// full supersession-key set (keyed tier) so paraphrased re-observations
|
|
796
|
+
// of the same supersession identity are blocked, not just the literal
|
|
797
|
+
// body. Without these the tombstone projected from a structured fact
|
|
798
|
+
// dropped both fields and the fact could resurrect.
|
|
799
|
+
...memory.contentHash ? { contentHash: memory.contentHash } : {},
|
|
800
|
+
...memory.supersessionKeys && memory.supersessionKeys.length > 0 ? { supersessionKeys: memory.supersessionKeys } : {}
|
|
730
801
|
});
|
|
731
802
|
await this.deps.retireMemory(namespace, memoryId, {
|
|
732
803
|
status: reason === "supersession" ? "superseded" : "retracted",
|
|
@@ -745,9 +816,15 @@ var CorrectionExecutor = class {
|
|
|
745
816
|
}
|
|
746
817
|
}
|
|
747
818
|
};
|
|
819
|
+
var CORRECTION_ERROR_MAX = 500;
|
|
820
|
+
function sanitizeErrorMessage(raw) {
|
|
821
|
+
const stripped = raw.replace(/(^|[\s:'"(])\/(?:[^\s'">)\\]+\/)+[^\s'">)\\]*/g, "$1<path>").replace(/(^|[\s:'"(])[A-Za-z]:\\[^\s'">)\\]+(?:\\[^\s'">) ]*)*/g, "$1<path>");
|
|
822
|
+
const trimmed = stripped.trim();
|
|
823
|
+
return trimmed.length > CORRECTION_ERROR_MAX ? `${trimmed.slice(0, CORRECTION_ERROR_MAX)}\u2026` : trimmed;
|
|
824
|
+
}
|
|
748
825
|
function errMsg(err) {
|
|
749
|
-
|
|
750
|
-
return
|
|
826
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
827
|
+
return sanitizeErrorMessage(raw);
|
|
751
828
|
}
|
|
752
829
|
|
|
753
830
|
// src/correction/correction-service.ts
|
|
@@ -868,7 +945,7 @@ async function searchMemories(wiring, text, namespaces, limit) {
|
|
|
868
945
|
const storage = await wiring.orchestrator.getStorage(ns);
|
|
869
946
|
const all = await storage.readAllMemories();
|
|
870
947
|
for (const m of all) {
|
|
871
|
-
if (m
|
|
948
|
+
if (!isEligibleCorrectionCandidate(m)) continue;
|
|
872
949
|
const hay = `${m.content} ${m.frontmatter.tags?.join(" ") ?? ""}`.toLowerCase();
|
|
873
950
|
let hits = 0;
|
|
874
951
|
for (const tok of tokens) {
|
|
@@ -1016,7 +1093,7 @@ async function expandEntityNeighbors(wiring, seedIds, namespaces, limit) {
|
|
|
1016
1093
|
for (const m of all) {
|
|
1017
1094
|
if (out.length >= limit) break;
|
|
1018
1095
|
if (seen.has(m.frontmatter.id)) continue;
|
|
1019
|
-
if (m
|
|
1096
|
+
if (!isEligibleCorrectionCandidate(m)) continue;
|
|
1020
1097
|
if (m.frontmatter.entityRef && seedRefs.has(m.frontmatter.entityRef)) {
|
|
1021
1098
|
out.push(toCandidate(m, ns, 0.5));
|
|
1022
1099
|
seen.add(m.frontmatter.id);
|
|
@@ -1107,9 +1184,13 @@ async function applyEditMemory(wiring, namespace, memoryId, patch) {
|
|
|
1107
1184
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
1108
1185
|
const existing = await storage.getMemoryById(memoryId);
|
|
1109
1186
|
if (!existing) throw new CorrectionContractError(`memory not found for edit: ${memoryId}`);
|
|
1187
|
+
const contentHashForPatch = existing.frontmatter.category === "fact" ? computeContentHash(sanitizeMemoryContent(patch).text) : void 0;
|
|
1110
1188
|
await storage.writeMemoryFrontmatter(
|
|
1111
1189
|
{ ...existing, content: patch },
|
|
1112
|
-
{
|
|
1190
|
+
{
|
|
1191
|
+
updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1192
|
+
...contentHashForPatch ? { contentHash: contentHashForPatch } : {}
|
|
1193
|
+
}
|
|
1113
1194
|
);
|
|
1114
1195
|
return memoryId;
|
|
1115
1196
|
}
|
|
@@ -1173,26 +1254,42 @@ async function rescopeMemoryFn(wiring, namespace, memoryId, toNamespace) {
|
|
|
1173
1254
|
async function appendTombstoneFn(wiring, namespace, input) {
|
|
1174
1255
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
1175
1256
|
const enabled = typeof storage.isTombstonesEnabled === "function" ? storage.isTombstonesEnabled() : true;
|
|
1176
|
-
const
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1257
|
+
const keys = input.supersessionKeys && input.supersessionKeys.length > 0 ? input.supersessionKeys : input.supersessionKey ? [input.supersessionKey] : [void 0];
|
|
1258
|
+
const writtenIds = [];
|
|
1259
|
+
let firstId = null;
|
|
1260
|
+
for (const key of keys) {
|
|
1261
|
+
const result = await storage.appendTombstone({
|
|
1262
|
+
reason: input.reason,
|
|
1263
|
+
createdBy: "user_correction",
|
|
1264
|
+
sourceMemoryId: input.sourceMemoryId,
|
|
1265
|
+
rawContent: input.rawContent,
|
|
1266
|
+
...input.entityRef ? { entityRef: input.entityRef } : {},
|
|
1267
|
+
...key ? { supersessionKey: key } : {},
|
|
1268
|
+
...input.contentHash ? { contentHash: input.contentHash } : {}
|
|
1269
|
+
});
|
|
1270
|
+
if (result === null && enabled) {
|
|
1271
|
+
for (const id of writtenIds) {
|
|
1272
|
+
try {
|
|
1273
|
+
await storage.revokeTombstone(id, "user_correction");
|
|
1274
|
+
} catch {
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
throw new CorrectionContractError(
|
|
1278
|
+
`tombstone persistence failed for memory ${input.sourceMemoryId} (tombstones enabled but store returned null \u2014 I/O error swallowed)`
|
|
1279
|
+
);
|
|
1280
|
+
}
|
|
1281
|
+
if (firstId === null) firstId = result;
|
|
1282
|
+
if (result) writtenIds.push(result);
|
|
1188
1283
|
}
|
|
1189
|
-
return
|
|
1284
|
+
return firstId;
|
|
1190
1285
|
}
|
|
1191
1286
|
async function registerRedactionRuleFn(wiring, namespace, pattern) {
|
|
1192
1287
|
const storage = await wiring.orchestrator.getStorage(namespace);
|
|
1193
1288
|
const dir = path2.join(storage.dir, "state", "corrections", "redaction-rules");
|
|
1194
1289
|
await mkdir2(dir, { recursive: true });
|
|
1195
|
-
const
|
|
1290
|
+
const slugBase = pattern.replace(/[^a-zA-Z0-9]+/g, "-").slice(0, 48) || "rule";
|
|
1291
|
+
const patternHash = createHash("sha256").update(pattern).digest("hex").slice(0, 16);
|
|
1292
|
+
const slug = `${slugBase}-${patternHash}`;
|
|
1196
1293
|
await writeFile2(
|
|
1197
1294
|
path2.join(dir, `${slug}.json`),
|
|
1198
1295
|
`${JSON.stringify({ pattern, namespace, createdAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
@@ -1252,15 +1349,27 @@ function toCandidate(m, namespace, score) {
|
|
|
1252
1349
|
// candidate for diff rendering if needed.
|
|
1253
1350
|
};
|
|
1254
1351
|
}
|
|
1352
|
+
function isEligibleCorrectionCandidate(m) {
|
|
1353
|
+
if (m.frontmatter.status && m.frontmatter.status !== "active") return false;
|
|
1354
|
+
if (typeof m.frontmatter.archivedAt === "string" && m.frontmatter.archivedAt.length > 0) return false;
|
|
1355
|
+
return true;
|
|
1356
|
+
}
|
|
1255
1357
|
function toExecutorMemory(m) {
|
|
1256
1358
|
const fm = m.frontmatter;
|
|
1257
1359
|
const rawBody = fm.structuredAttributes ? stripAttributesSuffix(m.content) : m.content;
|
|
1360
|
+
const supersessionKeys = supersessionKeysForFact({
|
|
1361
|
+
entityRef: fm.entityRef,
|
|
1362
|
+
structuredAttributes: fm.structuredAttributes
|
|
1363
|
+
});
|
|
1258
1364
|
return {
|
|
1259
1365
|
memoryId: fm.id,
|
|
1260
1366
|
content: m.content,
|
|
1261
1367
|
category: fm.category,
|
|
1262
1368
|
rawContent: rawBody,
|
|
1263
|
-
...fm.entityRef ? { entityRef: fm.entityRef } : {}
|
|
1369
|
+
...fm.entityRef ? { entityRef: fm.entityRef } : {},
|
|
1370
|
+
...supersessionKeys.length > 0 ? { supersessionKeys } : {},
|
|
1371
|
+
...supersessionKeys.length > 0 ? { supersessionKey: supersessionKeys[0] } : {},
|
|
1372
|
+
...typeof fm.contentHash === "string" && fm.contentHash.length > 0 ? { contentHash: fm.contentHash } : {}
|
|
1264
1373
|
};
|
|
1265
1374
|
}
|
|
1266
1375
|
function isCorrectionFeatureEnabled(config) {
|
|
@@ -1685,4 +1794,4 @@ export {
|
|
|
1685
1794
|
capturePassiveCorrections,
|
|
1686
1795
|
clusterByKey
|
|
1687
1796
|
};
|
|
1688
|
-
//# sourceMappingURL=chunk-
|
|
1797
|
+
//# sourceMappingURL=chunk-EZNDNMRH.js.map
|