@remnic/core 9.3.699 → 9.3.701
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.d.ts +5 -5
- package/dist/access-boundary.js +14 -10
- package/dist/access-cli.js +30 -28
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +5 -5
- package/dist/access-http.js +18 -14
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +17 -13
- package/dist/access-operations.d.ts +5 -5
- package/dist/access-operations.js +16 -12
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DftqtNUy.d.ts → access-service-CGVWK6lZ.d.ts} +2 -2
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +13 -9
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/action-confidence.js +2 -2
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +7 -3
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-D7YDNNF7.d.ts → catalog-DBIghceA.d.ts} +27 -53
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +8 -4
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-E6GOVHHJ.js → chunk-27LQPUMZ.js} +3 -3
- package/dist/{chunk-XJNBEDFE.js → chunk-3FAMU5TX.js} +31 -74
- package/dist/chunk-3FAMU5TX.js.map +1 -0
- package/dist/chunk-3JJWNZTT.js +446 -0
- package/dist/chunk-3JJWNZTT.js.map +1 -0
- package/dist/{chunk-JYVD2XZ4.js → chunk-4HIAWLA2.js} +58 -25
- package/dist/chunk-4HIAWLA2.js.map +1 -0
- package/dist/{chunk-A62RAIBN.js → chunk-6W2D6FGG.js} +2 -2
- package/dist/{chunk-COEZR6F5.js → chunk-7TAQEPLE.js} +2 -2
- package/dist/{chunk-TIVZ4MCG.js → chunk-D75JXBV4.js} +3 -3
- package/dist/{chunk-YY2HGKWR.js → chunk-DEDQXIDL.js} +2 -2
- package/dist/{chunk-XFG3PVZE.js → chunk-FUCJAZ25.js} +8 -8
- package/dist/{chunk-EZWQZYLK.js → chunk-HF4N43Q7.js} +2 -2
- package/dist/{chunk-HZ5DRA4Q.js → chunk-HXHKLVAS.js} +20 -20
- package/dist/{chunk-AC5LO7IU.js → chunk-I4WBNM3M.js} +7 -1
- package/dist/chunk-I4WBNM3M.js.map +1 -0
- package/dist/{chunk-QVTSLRKT.js → chunk-IJEZMWKA.js} +3 -3
- package/dist/{chunk-ZXUOAFUG.js → chunk-IKNQAGBV.js} +1 -1
- package/dist/chunk-IKNQAGBV.js.map +1 -0
- package/dist/{chunk-RC3CNIPK.js → chunk-IO5NQEGZ.js} +2 -2
- package/dist/{chunk-2ULWWAQH.js → chunk-ISLJ5WIM.js} +2 -2
- package/dist/{chunk-2KJG6ZZK.js → chunk-IYOPIG3E.js} +2 -2
- package/dist/{chunk-M4DQWUKX.js → chunk-JKOKX3PS.js} +62 -163
- package/dist/chunk-JKOKX3PS.js.map +1 -0
- package/dist/{chunk-SJQ4HY3E.js → chunk-JO3E5VGS.js} +2 -2
- package/dist/{chunk-3LSSFCB4.js → chunk-K4DWSPMW.js} +11 -1
- package/dist/chunk-K4DWSPMW.js.map +1 -0
- package/dist/{chunk-IZ5E6ZTK.js → chunk-KF4TXW7Z.js} +6 -6
- package/dist/{chunk-CQ4PGFMC.js → chunk-KS7WQ4BZ.js} +4 -4
- package/dist/chunk-LTJAMRGI.js +286 -0
- package/dist/chunk-LTJAMRGI.js.map +1 -0
- package/dist/{chunk-PJIHCOGV.js → chunk-MNU5G4TK.js} +2 -2
- package/dist/{chunk-2K64VH66.js → chunk-ODTWHSY2.js} +69 -45
- package/dist/chunk-ODTWHSY2.js.map +1 -0
- package/dist/{chunk-LIWU4QI6.js → chunk-OLOYQZFB.js} +5 -5
- package/dist/{chunk-MRFVMSTR.js → chunk-OMNTQPZO.js} +20 -1
- package/dist/{chunk-MRFVMSTR.js.map → chunk-OMNTQPZO.js.map} +1 -1
- package/dist/{chunk-JI6HWBYL.js → chunk-Q4O3ET6F.js} +2 -2
- package/dist/{chunk-N55RJT4N.js → chunk-QP37KL5H.js} +2 -2
- package/dist/{chunk-LPIWEKZ3.js → chunk-SDPDU2PM.js} +3 -3
- package/dist/{chunk-RIC5U67B.js → chunk-SFMRLXIV.js} +232 -4
- package/dist/chunk-SFMRLXIV.js.map +1 -0
- package/dist/{chunk-RTN2BLZM.js → chunk-T5QAZIBO.js} +2 -2
- package/dist/{chunk-ANZLT74L.js → chunk-TFVVONWD.js} +2 -2
- package/dist/{chunk-SIDSEXUG.js → chunk-WFEZUGU5.js} +2 -2
- package/dist/{chunk-FSEQXHEZ.js → chunk-XTIRCSIH.js} +2 -2
- package/dist/{chunk-XL5RSHZP.js → chunk-YO4MBK3I.js} +2 -2
- package/dist/{chunk-AH2JUU6X.js → chunk-Z2YFLXHU.js} +2 -2
- package/dist/{chunk-MRX6S22R.js → chunk-ZT7B64BE.js} +2 -2
- package/dist/{chunk-UDDSC6PO.js → chunk-ZYNMX6IU.js} +54 -6
- package/dist/chunk-ZYNMX6IU.js.map +1 -0
- package/dist/{cli-DUMkkdLl.d.ts → cli-D3XeenwN.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +32 -28
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +7 -3
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +7 -3
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +7 -3
- 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/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +7 -3
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +6 -6
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-PLR6J5DN.js → forget-6SOIPUMQ.js} +32 -1
- package/dist/forget-6SOIPUMQ.js.map +1 -0
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +21 -10
- package/dist/index.js +65 -43
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +7 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -3
- package/dist/maintenance/rebuild-memory-projection.js +8 -4
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-provenance.js +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +8 -4
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +32 -3
- package/dist/namespaces/storage.js +7 -3
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +19 -2
- package/dist/operator-toolkit.js +17 -11
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +9 -5
- package/dist/{orchestrator-Dv8JQu3-.d.ts → orchestrator-BzMCZlKn.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +22 -20
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +4 -4
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +5 -5
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +4 -4
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +3 -3
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +28 -28
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-CgREi9E0.d.ts → semantic-consolidation-BtUfv-AL.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +8 -4
- package/dist/semantic-rule-promotion.js +7 -3
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +7 -3
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +306 -2
- package/dist/storage.js +6 -2
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/summary-snapshot.js +2 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/{types-CeZYSC-E.d.ts → types-PuiPZ9iE.d.ts} +34 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/utils/serialize-mutations.js +5 -280
- package/dist/utils/serialize-mutations.js.map +1 -1
- package/dist/verified-recall.js +7 -3
- package/package.json +2 -2
- package/src/config.ts +10 -0
- package/src/lifecycle/tombstones.test.ts +355 -0
- package/src/lifecycle/tombstones.ts +807 -0
- package/src/maintenance/forget.ts +41 -0
- package/src/maintenance/pattern-reinforcement.ts +47 -0
- package/src/memory-provenance.ts +12 -0
- package/src/namespaces/catalog.test.ts +222 -14
- package/src/namespaces/catalog.ts +54 -187
- package/src/namespaces/storage.ts +120 -80
- package/src/operator-toolkit.ts +77 -0
- package/src/orchestrator.ts +16 -0
- package/src/review/index.ts +48 -3
- package/src/storage.ts +329 -2
- package/src/summary-snapshot.test.ts +63 -1
- package/src/summary-snapshot.ts +61 -80
- package/src/temporal-supersession.ts +38 -0
- package/src/types.ts +34 -0
- package/src/utils/serialize-mutations.ts +10 -6
- package/dist/chunk-2K64VH66.js.map +0 -1
- package/dist/chunk-3LSSFCB4.js.map +0 -1
- package/dist/chunk-AC5LO7IU.js.map +0 -1
- package/dist/chunk-JYVD2XZ4.js.map +0 -1
- package/dist/chunk-M4DQWUKX.js.map +0 -1
- package/dist/chunk-RIC5U67B.js.map +0 -1
- package/dist/chunk-UDDSC6PO.js.map +0 -1
- package/dist/chunk-XJNBEDFE.js.map +0 -1
- package/dist/chunk-ZXUOAFUG.js.map +0 -1
- package/dist/forget-PLR6J5DN.js.map +0 -1
- /package/dist/{chunk-E6GOVHHJ.js.map → chunk-27LQPUMZ.js.map} +0 -0
- /package/dist/{chunk-A62RAIBN.js.map → chunk-6W2D6FGG.js.map} +0 -0
- /package/dist/{chunk-COEZR6F5.js.map → chunk-7TAQEPLE.js.map} +0 -0
- /package/dist/{chunk-TIVZ4MCG.js.map → chunk-D75JXBV4.js.map} +0 -0
- /package/dist/{chunk-YY2HGKWR.js.map → chunk-DEDQXIDL.js.map} +0 -0
- /package/dist/{chunk-XFG3PVZE.js.map → chunk-FUCJAZ25.js.map} +0 -0
- /package/dist/{chunk-EZWQZYLK.js.map → chunk-HF4N43Q7.js.map} +0 -0
- /package/dist/{chunk-HZ5DRA4Q.js.map → chunk-HXHKLVAS.js.map} +0 -0
- /package/dist/{chunk-QVTSLRKT.js.map → chunk-IJEZMWKA.js.map} +0 -0
- /package/dist/{chunk-RC3CNIPK.js.map → chunk-IO5NQEGZ.js.map} +0 -0
- /package/dist/{chunk-2ULWWAQH.js.map → chunk-ISLJ5WIM.js.map} +0 -0
- /package/dist/{chunk-2KJG6ZZK.js.map → chunk-IYOPIG3E.js.map} +0 -0
- /package/dist/{chunk-SJQ4HY3E.js.map → chunk-JO3E5VGS.js.map} +0 -0
- /package/dist/{chunk-IZ5E6ZTK.js.map → chunk-KF4TXW7Z.js.map} +0 -0
- /package/dist/{chunk-CQ4PGFMC.js.map → chunk-KS7WQ4BZ.js.map} +0 -0
- /package/dist/{chunk-PJIHCOGV.js.map → chunk-MNU5G4TK.js.map} +0 -0
- /package/dist/{chunk-LIWU4QI6.js.map → chunk-OLOYQZFB.js.map} +0 -0
- /package/dist/{chunk-JI6HWBYL.js.map → chunk-Q4O3ET6F.js.map} +0 -0
- /package/dist/{chunk-N55RJT4N.js.map → chunk-QP37KL5H.js.map} +0 -0
- /package/dist/{chunk-LPIWEKZ3.js.map → chunk-SDPDU2PM.js.map} +0 -0
- /package/dist/{chunk-RTN2BLZM.js.map → chunk-T5QAZIBO.js.map} +0 -0
- /package/dist/{chunk-ANZLT74L.js.map → chunk-TFVVONWD.js.map} +0 -0
- /package/dist/{chunk-SIDSEXUG.js.map → chunk-WFEZUGU5.js.map} +0 -0
- /package/dist/{chunk-FSEQXHEZ.js.map → chunk-XTIRCSIH.js.map} +0 -0
- /package/dist/{chunk-XL5RSHZP.js.map → chunk-YO4MBK3I.js.map} +0 -0
- /package/dist/{chunk-AH2JUU6X.js.map → chunk-Z2YFLXHU.js.map} +0 -0
- /package/dist/{chunk-MRX6S22R.js.map → chunk-ZT7B64BE.js.map} +0 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TombstoneStore,
|
|
3
|
+
buildRetiredFactTombstoneInputs,
|
|
4
|
+
collectRetiredMemoriesForRebuild
|
|
5
|
+
} from "./chunk-3JJWNZTT.js";
|
|
1
6
|
import {
|
|
2
7
|
WEARABLES_DIR_NAME,
|
|
3
8
|
isValidTranscriptDate
|
|
@@ -8,6 +13,9 @@ import {
|
|
|
8
13
|
import {
|
|
9
14
|
assertPathInsideRoot
|
|
10
15
|
} from "./chunk-5GPPACXK.js";
|
|
16
|
+
import {
|
|
17
|
+
supersessionKeysForFact
|
|
18
|
+
} from "./chunk-OMNTQPZO.js";
|
|
11
19
|
import {
|
|
12
20
|
stripAttributesSuffix
|
|
13
21
|
} from "./chunk-SVOZFLIQ.js";
|
|
@@ -19,7 +27,7 @@ import {
|
|
|
19
27
|
import {
|
|
20
28
|
SPECULATIVE_TTL_DAYS,
|
|
21
29
|
confidenceTier
|
|
22
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-IKNQAGBV.js";
|
|
23
31
|
import {
|
|
24
32
|
normalizeProjectionPreview,
|
|
25
33
|
normalizeProjectionTags
|
|
@@ -257,6 +265,8 @@ function serializeFrontmatter(fm) {
|
|
|
257
265
|
lines.push(`lineage: [${fm.lineage.map((l) => `"${l}"`).join(", ")}]`);
|
|
258
266
|
}
|
|
259
267
|
if (fm.status && fm.status !== "active") lines.push(`status: ${fm.status}`);
|
|
268
|
+
if (fm.blockedBy) lines.push(`blockedBy: ${fm.blockedBy}`);
|
|
269
|
+
if (fm.tombstoneBlockTier) lines.push(`tombstoneBlockTier: ${fm.tombstoneBlockTier}`);
|
|
260
270
|
if (fm.supersededBy) lines.push(`supersededBy: ${fm.supersededBy}`);
|
|
261
271
|
if (fm.supersededAt) lines.push(`supersededAt: ${fm.supersededAt}`);
|
|
262
272
|
if (fm.archivedAt) lines.push(`archivedAt: ${fm.archivedAt}`);
|
|
@@ -615,6 +625,9 @@ function parseFrontmatter(raw) {
|
|
|
615
625
|
lineage: lineage && lineage.length > 0 ? lineage : void 0,
|
|
616
626
|
// Status management
|
|
617
627
|
status: fm.status || "active",
|
|
628
|
+
// Tombstone block visibility (issue #1579) — read-through.
|
|
629
|
+
blockedBy: fm.blockedBy || void 0,
|
|
630
|
+
tombstoneBlockTier: fm.tombstoneBlockTier === "exact" || fm.tombstoneBlockTier === "normalized" || fm.tombstoneBlockTier === "keyed" || fm.tombstoneBlockTier === "semantic" ? fm.tombstoneBlockTier : void 0,
|
|
618
631
|
supersededBy: fm.supersededBy || void 0,
|
|
619
632
|
supersededAt: fm.supersededAt || void 0,
|
|
620
633
|
archivedAt: fm.archivedAt || void 0,
|
|
@@ -1751,6 +1764,13 @@ var StorageManager = class _StorageManager {
|
|
|
1751
1764
|
} catch {
|
|
1752
1765
|
}
|
|
1753
1766
|
}
|
|
1767
|
+
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
1768
|
+
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
1769
|
+
// Lazily loaded from <stateDir>/tombstones.jsonl; invalidated together with
|
|
1770
|
+
// every other cache layer via invalidateAllMemoriesCache (rule 25).
|
|
1771
|
+
tombstoneStore = null;
|
|
1772
|
+
tombstoneStoreLoadPromise = null;
|
|
1773
|
+
tombstonesConfig = { enabled: false, semanticMatch: false, semanticThreshold: 0.9, namespace: "default" };
|
|
1754
1774
|
/** Page-versioning configuration. Set by the orchestrator after construction. */
|
|
1755
1775
|
_versioningConfig = null;
|
|
1756
1776
|
/** Set the page-versioning configuration. When `enabled` is false (default), all versioning calls are no-ops. */
|
|
@@ -2048,13 +2068,17 @@ var StorageManager = class _StorageManager {
|
|
|
2048
2068
|
* Promote a pending_review wearable memory to active in place,
|
|
2049
2069
|
* merging updated trust evidence into structuredAttributes. Returns
|
|
2050
2070
|
* false when the memory is missing or no longer pending_review (a
|
|
2051
|
-
* concurrent review decision wins)
|
|
2071
|
+
* concurrent review decision wins), or when the row is tombstone-blocked
|
|
2072
|
+
* (`blockedBy` — issue #1579 threads OcuDx/Ocu1l): writeMemoryFrontmatter
|
|
2073
|
+
* bypasses the writeMemory chokepoint, so a blocked row must first be
|
|
2074
|
+
* cleared via revokeTombstone before promotion can proceed.
|
|
2052
2075
|
*/
|
|
2053
2076
|
async promoteWearableMemory(id, attributeUpdates, confidence) {
|
|
2054
2077
|
const memories = await this.readAllMemories();
|
|
2055
2078
|
const memory = memories.find((entry) => entry.frontmatter.id === id);
|
|
2056
2079
|
if (!memory) return false;
|
|
2057
2080
|
if (memory.frontmatter.status !== "pending_review") return false;
|
|
2081
|
+
if (memory.frontmatter.blockedBy) return false;
|
|
2058
2082
|
return this.writeMemoryFrontmatter(memory, {
|
|
2059
2083
|
status: "active",
|
|
2060
2084
|
// Keep frontmatter confidence in step with the re-scored trust —
|
|
@@ -2361,6 +2385,139 @@ var StorageManager = class _StorageManager {
|
|
|
2361
2385
|
get factHashIndexReadyPath() {
|
|
2362
2386
|
return path.join(this.stateDir, "fact-hashes.ready");
|
|
2363
2387
|
}
|
|
2388
|
+
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
2389
|
+
/**
|
|
2390
|
+
* The on-disk tombstone log path. Lives under `<stateDir>/tombstones.jsonl`
|
|
2391
|
+
* so it is co-located with the fact-hash index and encrypted at rest when
|
|
2392
|
+
* the secure-store is enabled (the StorageManager's secure read/write
|
|
2393
|
+
* helpers are injected into the store).
|
|
2394
|
+
*/
|
|
2395
|
+
get tombstonesPath() {
|
|
2396
|
+
return path.join(this.stateDir, "tombstones.jsonl");
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Configure the tombstone invariant for this storage instance. Installed
|
|
2400
|
+
* by the orchestrator after construction (same pattern as
|
|
2401
|
+
* `setVersioningConfig` / `citationTemplate`). When `enabled` is false
|
|
2402
|
+
* (default until the orchestrator wires config), the chokepoint check is a
|
|
2403
|
+
* no-op — pre-feature behavior for rollback safety (rule 30).
|
|
2404
|
+
*/
|
|
2405
|
+
setTombstonesConfig(config) {
|
|
2406
|
+
this.tombstonesConfig = { ...config };
|
|
2407
|
+
if (this.tombstoneStore) {
|
|
2408
|
+
this.tombstoneStore.invalidate();
|
|
2409
|
+
this.tombstoneStore = null;
|
|
2410
|
+
this.tombstoneStoreLoadPromise = null;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
buildTombstoneStore() {
|
|
2414
|
+
const options = {
|
|
2415
|
+
enabled: this.tombstonesConfig.enabled,
|
|
2416
|
+
semanticMatch: this.tombstonesConfig.semanticMatch,
|
|
2417
|
+
semanticThreshold: this.tombstonesConfig.semanticThreshold,
|
|
2418
|
+
// Wire the SAME helpers the dedup index uses (rule 23 / checklist §13):
|
|
2419
|
+
// hashContent = ContentHashIndex.computeHash, normalizeText =
|
|
2420
|
+
// ContentHashIndex.normalizeContent. Importing them here (not copying)
|
|
2421
|
+
// guarantees the tombstone tiers can never drift from dedup.
|
|
2422
|
+
hashContent: ContentHashIndex.computeHash,
|
|
2423
|
+
normalizeText: ContentHashIndex.normalizeContent
|
|
2424
|
+
};
|
|
2425
|
+
const io = {
|
|
2426
|
+
read: (filePath) => this.readStorageSecureFile(filePath),
|
|
2427
|
+
append: (filePath, content) => this.appendStorageSecureFile(filePath, content),
|
|
2428
|
+
write: (filePath, content) => this.writeStorageSecureFile(filePath, content),
|
|
2429
|
+
// stat lets the store own its cross-process staleness probe (#1579).
|
|
2430
|
+
stat: (filePath) => statSync(filePath)
|
|
2431
|
+
};
|
|
2432
|
+
return new TombstoneStore(
|
|
2433
|
+
this.tombstonesPath,
|
|
2434
|
+
this.tombstonesConfig.namespace,
|
|
2435
|
+
options,
|
|
2436
|
+
io
|
|
2437
|
+
);
|
|
2438
|
+
}
|
|
2439
|
+
/**
|
|
2440
|
+
* Lazily load the tombstone store. Mirrors the fact-hash-index lazy-load
|
|
2441
|
+
* pattern: a single in-flight load promise dedups concurrent first-access.
|
|
2442
|
+
* The cross-process staleness probe lives inside the store now (#1579): on
|
|
2443
|
+
* each cached access it stats its own file and invalidates if a peer process
|
|
2444
|
+
* appended, so the next lookup reloads from disk. If the probe just
|
|
2445
|
+
* invalidated the store, fall through to the reload branch — returning null
|
|
2446
|
+
* here was the original regression (the chokepoint threw and failed OPEN).
|
|
2447
|
+
*/
|
|
2448
|
+
getTombstoneStore() {
|
|
2449
|
+
if (this.tombstoneStore) {
|
|
2450
|
+
const cached = this.tombstoneStore;
|
|
2451
|
+
return cached.ensureFreshAgainstDisk().then(() => cached);
|
|
2452
|
+
}
|
|
2453
|
+
if (!this.tombstoneStoreLoadPromise) {
|
|
2454
|
+
const store = this.buildTombstoneStore();
|
|
2455
|
+
this.tombstoneStoreLoadPromise = store.load().then(() => {
|
|
2456
|
+
this.tombstoneStore = store;
|
|
2457
|
+
return store;
|
|
2458
|
+
}).catch((err) => {
|
|
2459
|
+
this.tombstoneStoreLoadPromise = null;
|
|
2460
|
+
throw err;
|
|
2461
|
+
});
|
|
2462
|
+
}
|
|
2463
|
+
return this.tombstoneStoreLoadPromise;
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* Append a tombstone for a retired memory (issue #1579 emitters).
|
|
2467
|
+
* Best-effort: a tombstone append failure MUST NOT fail the supersession /
|
|
2468
|
+
* correction that triggered it (gotcha #13 / rule 34). The memory is
|
|
2469
|
+
* already retired on disk; the tombstone is the non-resurrection guard.
|
|
2470
|
+
*/
|
|
2471
|
+
async appendTombstone(input) {
|
|
2472
|
+
if (!this.tombstonesConfig.enabled) return null;
|
|
2473
|
+
try {
|
|
2474
|
+
const store = await this.getTombstoneStore();
|
|
2475
|
+
const strippedRawContent = stripCitationForTemplate(input.rawContent, this.citationTemplate);
|
|
2476
|
+
return await store.appendTombstone({ ...input, rawContent: strippedRawContent });
|
|
2477
|
+
} catch (err) {
|
|
2478
|
+
log.warn(`tombstone append failed (memory=${input.sourceMemoryId}): ${err}`);
|
|
2479
|
+
return null;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Revoke a tombstone (re-allow the content). Used by the review-queue
|
|
2484
|
+
* approval path when an operator approves a blocked memory.
|
|
2485
|
+
*/
|
|
2486
|
+
async revokeTombstone(tombstoneId, createdBy) {
|
|
2487
|
+
if (!this.tombstonesConfig.enabled) return null;
|
|
2488
|
+
try {
|
|
2489
|
+
const store = await this.getTombstoneStore();
|
|
2490
|
+
return await store.revoke(tombstoneId, createdBy);
|
|
2491
|
+
} catch (err) {
|
|
2492
|
+
log.warn(`tombstone revoke failed (id=${tombstoneId}): ${err}`);
|
|
2493
|
+
return null;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
/** Aggregate tombstone stats for `remnic doctor`. */
|
|
2497
|
+
async getTombstoneStats() {
|
|
2498
|
+
if (!this.tombstonesConfig.enabled) return null;
|
|
2499
|
+
try {
|
|
2500
|
+
const store = await this.getTombstoneStore();
|
|
2501
|
+
return store.stats();
|
|
2502
|
+
} catch (err) {
|
|
2503
|
+
log.warn(`tombstone stats failed: ${err}`);
|
|
2504
|
+
return null;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
/**
|
|
2508
|
+
* Rebuild the tombstone log from retired memories on disk. Exposed for
|
|
2509
|
+
* `remnic doctor --rebuild-tombstones` and tests.
|
|
2510
|
+
*/
|
|
2511
|
+
async rebuildTombstonesFromFiles() {
|
|
2512
|
+
if (!this.tombstonesConfig.enabled) return 0;
|
|
2513
|
+
const store = await this.getTombstoneStore();
|
|
2514
|
+
const all = [...await this.readAllMemories(), ...await this.readAllColdMemories()];
|
|
2515
|
+
const retired = collectRetiredMemoriesForRebuild(all, {
|
|
2516
|
+
stripCitation: (text) => stripCitationForTemplate(text, this.citationTemplate),
|
|
2517
|
+
supersessionKeysForFact
|
|
2518
|
+
});
|
|
2519
|
+
return await store.rebuild(retired);
|
|
2520
|
+
}
|
|
2364
2521
|
async getFactHashIndex() {
|
|
2365
2522
|
if (this.factHashIndex) {
|
|
2366
2523
|
return this.factHashIndex;
|
|
@@ -2655,9 +2812,45 @@ var StorageManager = class _StorageManager {
|
|
|
2655
2812
|
if (!sanitized.clean) {
|
|
2656
2813
|
log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
2657
2814
|
}
|
|
2815
|
+
let factHashSourceForTombstone = null;
|
|
2658
2816
|
if (category === "fact") {
|
|
2659
2817
|
const hashSource = options.contentHashSource !== void 0 && options.contentHashSource.length > 0 ? sanitizeMemoryContent(options.contentHashSource).text : sanitized.text;
|
|
2660
2818
|
fm.contentHash = ContentHashIndex.computeHash(hashSource);
|
|
2819
|
+
factHashSourceForTombstone = hashSource;
|
|
2820
|
+
}
|
|
2821
|
+
let tombstoneBlocked = false;
|
|
2822
|
+
if (category === "fact" && this.tombstonesConfig.enabled && factHashSourceForTombstone !== null && // Block facts that would become ACTIVE or are already pending_review
|
|
2823
|
+
// (issue #1579 thread ObteQ: wearable/native imports write fact
|
|
2824
|
+
// candidates with status: pending_review; without checking them here,
|
|
2825
|
+
// promoteWearableMemory could later flip a retired fact active without
|
|
2826
|
+
// a tombstone check). A caller that explicitly requests a terminal
|
|
2827
|
+
// non-active status (rejected/retracted/superseded) is respected.
|
|
2828
|
+
(fm.status === void 0 || fm.status === "active" || fm.status === "pending_review")) {
|
|
2829
|
+
try {
|
|
2830
|
+
const tombstoneStore = await this.getTombstoneStore();
|
|
2831
|
+
const keyedSupersession = options.entityRef && options.structuredAttributes ? supersessionKeysForFact({
|
|
2832
|
+
entityRef: options.entityRef,
|
|
2833
|
+
structuredAttributes: options.structuredAttributes
|
|
2834
|
+
}) : [];
|
|
2835
|
+
const match = tombstoneStore.lookup({
|
|
2836
|
+
contentHash: fm.contentHash,
|
|
2837
|
+
normalizedText: ContentHashIndex.normalizeContent(factHashSourceForTombstone),
|
|
2838
|
+
...options.entityRef ? { entityRef: options.entityRef } : {},
|
|
2839
|
+
...keyedSupersession.length > 0 ? { supersessionKeys: keyedSupersession } : {},
|
|
2840
|
+
namespace: this.tombstonesConfig.namespace
|
|
2841
|
+
});
|
|
2842
|
+
if (match) {
|
|
2843
|
+
tombstoneBlocked = true;
|
|
2844
|
+
fm.status = "pending_review";
|
|
2845
|
+
fm.blockedBy = match.tombstoneId;
|
|
2846
|
+
fm.tombstoneBlockTier = match.matchedTier;
|
|
2847
|
+
log.info(
|
|
2848
|
+
`tombstone: blocked resurrection of fact ${id} (tier=${match.matchedTier}, tombstone=${match.tombstoneId}, reason=${match.reason})`
|
|
2849
|
+
);
|
|
2850
|
+
}
|
|
2851
|
+
} catch (err) {
|
|
2852
|
+
log.warn(`tombstone lookup failed for fact ${id} (fail-open): ${err}`);
|
|
2853
|
+
}
|
|
2661
2854
|
}
|
|
2662
2855
|
const fileContent = `${serializeFrontmatter(fm)}
|
|
2663
2856
|
|
|
@@ -2678,7 +2871,7 @@ ${sanitized.text}
|
|
|
2678
2871
|
...(options.lineage ?? []).filter(Boolean)
|
|
2679
2872
|
]
|
|
2680
2873
|
});
|
|
2681
|
-
if (category === "fact") {
|
|
2874
|
+
if (category === "fact" && !tombstoneBlocked) {
|
|
2682
2875
|
try {
|
|
2683
2876
|
const factHashIndex = await this.getFactHashIndex();
|
|
2684
2877
|
if (options.contentHashSource !== void 0 && options.contentHashSource.length > 0) {
|
|
@@ -2720,6 +2913,22 @@ ${sanitized.text}
|
|
|
2720
2913
|
factHashIndex.addByHash(hash);
|
|
2721
2914
|
await factHashIndex.save();
|
|
2722
2915
|
}
|
|
2916
|
+
/**
|
|
2917
|
+
* Re-register a fact's contentHash in the dedup index after a tombstone
|
|
2918
|
+
* block is lifted on approval (issue #1579 thread ObnTy). `writeMemory`
|
|
2919
|
+
* skips hash-index registration for tombstone-blocked facts (rule 44); when
|
|
2920
|
+
* the review queue later promotes such a fact back to `status: active`, the
|
|
2921
|
+
* hash must enter the index or the next extraction of the same content
|
|
2922
|
+
* creates a second active fact. Reads the memory by id so the caller (the
|
|
2923
|
+
* review CLI) does not need to re-parse the file. No-op for non-facts or
|
|
2924
|
+
* facts that are not active.
|
|
2925
|
+
*/
|
|
2926
|
+
async restoreFactHashAfterApproval(memoryId) {
|
|
2927
|
+
const all = await this.readAllMemories();
|
|
2928
|
+
const memory = all.find((m) => m.frontmatter.id === memoryId);
|
|
2929
|
+
if (!memory) return;
|
|
2930
|
+
await this.addActiveFactContentHash(memory);
|
|
2931
|
+
}
|
|
2723
2932
|
async syncFactHashIndexAfterRewrite(before, after) {
|
|
2724
2933
|
if (before.frontmatter.category !== "fact" && after.frontmatter.category !== "fact") return;
|
|
2725
2934
|
const beforeHash = this.factContentHashForRemoval(before);
|
|
@@ -3117,6 +3326,11 @@ ${sanitized.text}
|
|
|
3117
3326
|
invalidateAllMemoriesCache() {
|
|
3118
3327
|
_StorageManager.allMemoriesInFlight.delete(this.baseDir);
|
|
3119
3328
|
invalidateAllForDir(this.baseDir);
|
|
3329
|
+
if (this.tombstoneStore) {
|
|
3330
|
+
this.tombstoneStore.invalidate();
|
|
3331
|
+
this.tombstoneStore = null;
|
|
3332
|
+
this.tombstoneStoreLoadPromise = null;
|
|
3333
|
+
}
|
|
3120
3334
|
}
|
|
3121
3335
|
/**
|
|
3122
3336
|
* Invalidate the cold-scan cache for this storage root and bump the
|
|
@@ -5416,6 +5630,20 @@ ${oldMemory.content}
|
|
|
5416
5630
|
});
|
|
5417
5631
|
this.bumpMemoryStatusVersion();
|
|
5418
5632
|
log.debug(`superseded memory ${oldMemoryId} by ${newMemoryId}: ${reason}`);
|
|
5633
|
+
if (oldMemory.frontmatter.category === "fact") {
|
|
5634
|
+
for (const input of buildRetiredFactTombstoneInputs(
|
|
5635
|
+
{
|
|
5636
|
+
id: oldMemoryId,
|
|
5637
|
+
content: stripCitationForTemplate(oldMemory.content, this.citationTemplate),
|
|
5638
|
+
contentHash: oldMemory.frontmatter.contentHash,
|
|
5639
|
+
entityRef: oldMemory.frontmatter.entityRef,
|
|
5640
|
+
structuredAttributes: oldMemory.frontmatter.structuredAttributes
|
|
5641
|
+
},
|
|
5642
|
+
{ reason: "contradiction_resolution", createdBy: "contradiction_resolution", createdAt: now, supersessionKeysForFact }
|
|
5643
|
+
)) {
|
|
5644
|
+
await this.appendTombstone(input);
|
|
5645
|
+
}
|
|
5646
|
+
}
|
|
5419
5647
|
await this.writeMemory("correction", `Superseded: ${oldMemory.content}
|
|
5420
5648
|
|
|
5421
5649
|
Reason: ${reason}`, {
|
|
@@ -5612,4 +5840,4 @@ export {
|
|
|
5612
5840
|
serializeEntityFile,
|
|
5613
5841
|
StorageManager
|
|
5614
5842
|
};
|
|
5615
|
-
//# sourceMappingURL=chunk-
|
|
5843
|
+
//# sourceMappingURL=chunk-SFMRLXIV.js.map
|