@remnic/core 1.1.1 → 1.1.3
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/abort-error.js +1 -0
- package/dist/abstraction-nodes.js +1 -0
- package/dist/access-audit.js +1 -0
- package/dist/access-cli.js +76 -51
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +50 -5
- package/dist/access-http.js +38 -16
- package/dist/access-idempotency.js +1 -0
- package/dist/access-mcp.d.ts +10 -5
- package/dist/access-mcp.js +37 -14
- package/dist/access-schema.d.ts +133 -13
- package/dist/access-schema.js +20 -1
- package/dist/access-service-_AEUMVyX.d.ts +1981 -0
- package/dist/access-service.d.ts +11 -6
- package/dist/access-service.js +39 -14
- package/dist/active-memory-bridge.js +1 -0
- package/dist/active-recall.js +1 -0
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.js +1 -0
- package/dist/behavior-learner.js.map +1 -1
- package/dist/behavior-signals.js +1 -0
- package/dist/bootstrap.d.ts +6 -4
- package/dist/bootstrap.js +1 -0
- package/dist/boxes.js +1 -0
- package/dist/briefing.d.ts +9 -5
- package/dist/briefing.js +10 -6
- package/dist/buffer-surprise-report.js +1 -0
- package/dist/buffer-surprise.js +1 -0
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -0
- package/dist/calibration.d.ts +8 -1
- package/dist/calibration.js +10 -2
- package/dist/calibration.js.map +1 -1
- package/dist/capsule-cli.d.ts +137 -0
- package/dist/capsule-cli.js +34 -0
- package/dist/capsule-crypto-5CYAGVC5.js +18 -0
- package/dist/capsule-export-NZQPOTQ4.js +17 -0
- package/dist/capsule-export-NZQPOTQ4.js.map +1 -0
- package/dist/capsule-import-SDCUXLEV.js +16 -0
- package/dist/capsule-import-SDCUXLEV.js.map +1 -0
- package/dist/capsule-merge-DI7PNQ2H.js +189 -0
- package/dist/capsule-merge-DI7PNQ2H.js.map +1 -0
- package/dist/causal-behavior.js +1 -0
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +1 -0
- package/dist/causal-consolidation.js +12 -9
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -1
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.js +4 -1
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +2 -1
- package/dist/chunk-2LSZVONP.js +67 -0
- package/dist/chunk-2LSZVONP.js.map +1 -0
- package/dist/chunk-32KD5IHZ.js +245 -0
- package/dist/chunk-32KD5IHZ.js.map +1 -0
- package/dist/{chunk-VDX363PS.js → chunk-34F3PLWZ.js} +10 -3
- package/dist/chunk-34F3PLWZ.js.map +1 -0
- package/dist/chunk-3KIS4VGT.js +228 -0
- package/dist/chunk-3KIS4VGT.js.map +1 -0
- package/dist/chunk-3LCWFNVS.js +350 -0
- package/dist/chunk-3LCWFNVS.js.map +1 -0
- package/dist/chunk-43EKP2UK.js +26 -0
- package/dist/chunk-43EKP2UK.js.map +1 -0
- package/dist/chunk-457A4P3L.js +119 -0
- package/dist/chunk-457A4P3L.js.map +1 -0
- package/dist/{chunk-KUB6JU6H.js → chunk-47WOM4YW.js} +2 -2
- package/dist/{chunk-HK3FGIEW.js → chunk-4PLGJRBV.js} +656 -20
- package/dist/chunk-4PLGJRBV.js.map +1 -0
- package/dist/{chunk-BGJGXLZ7.js → chunk-55FXRRSJ.js} +11 -8
- package/dist/chunk-55FXRRSJ.js.map +1 -0
- package/dist/{chunk-ULYOGL6R.js → chunk-5HRY2WRF.js} +7 -3
- package/dist/chunk-5HRY2WRF.js.map +1 -0
- package/dist/chunk-6TBWYBJ3.js +236 -0
- package/dist/chunk-6TBWYBJ3.js.map +1 -0
- package/dist/chunk-74EMIVE4.js +329 -0
- package/dist/chunk-74EMIVE4.js.map +1 -0
- package/dist/chunk-74WWN7ZW.js +82 -0
- package/dist/chunk-74WWN7ZW.js.map +1 -0
- package/dist/{chunk-B5WXLVDY.js → chunk-7GCMLT7J.js} +245 -25
- package/dist/chunk-7GCMLT7J.js.map +1 -0
- package/dist/chunk-A6XUJE5D.js +126 -0
- package/dist/chunk-A6XUJE5D.js.map +1 -0
- package/dist/chunk-AJA46VX5.js +393 -0
- package/dist/chunk-AJA46VX5.js.map +1 -0
- package/dist/{chunk-DFTTJYSO.js → chunk-AKUCB2OG.js} +525 -24
- package/dist/chunk-AKUCB2OG.js.map +1 -0
- package/dist/chunk-ASIQZXYO.js +277 -0
- package/dist/chunk-ASIQZXYO.js.map +1 -0
- package/dist/{chunk-ZEM3OK2K.js → chunk-B2TL6GA2.js} +3 -3
- package/dist/chunk-BJMBJZ2Y.js +290 -0
- package/dist/chunk-BJMBJZ2Y.js.map +1 -0
- package/dist/chunk-BT7NVCML.js +79 -0
- package/dist/chunk-BT7NVCML.js.map +1 -0
- package/dist/chunk-CK5NTM2S.js +454 -0
- package/dist/chunk-CK5NTM2S.js.map +1 -0
- package/dist/{chunk-3GXCSUXR.js → chunk-CRU27Q4J.js} +2 -2
- package/dist/{chunk-F5VP6YCB.js → chunk-DCE6SQLA.js} +572 -155
- package/dist/chunk-DCE6SQLA.js.map +1 -0
- package/dist/{chunk-CUPFXL3J.js → chunk-DHRQHX36.js} +4 -4
- package/dist/chunk-DHRQHX36.js.map +1 -0
- package/dist/{chunk-GKFXUTJ2.js → chunk-DR7MCMPS.js} +981 -61
- package/dist/chunk-DR7MCMPS.js.map +1 -0
- package/dist/chunk-FP2373TW.js +149 -0
- package/dist/chunk-FP2373TW.js.map +1 -0
- package/dist/{chunk-RBBWYEFJ.js → chunk-G2WADRQ3.js} +1 -1
- package/dist/chunk-G7D6GZ5J.js +48 -0
- package/dist/chunk-G7D6GZ5J.js.map +1 -0
- package/dist/chunk-H7XKCNR6.js +60 -0
- package/dist/chunk-H7XKCNR6.js.map +1 -0
- package/dist/{chunk-VYM3VWOF.js → chunk-IM3JSE73.js} +966 -329
- package/dist/chunk-IM3JSE73.js.map +1 -0
- package/dist/chunk-IXEJRKCZ.js +18 -0
- package/dist/chunk-IXEJRKCZ.js.map +1 -0
- package/dist/chunk-IYY4MCPG.js +275 -0
- package/dist/chunk-IYY4MCPG.js.map +1 -0
- package/dist/{chunk-BK2EFTE2.js → chunk-JWSENLQI.js} +508 -28
- package/dist/chunk-JWSENLQI.js.map +1 -0
- package/dist/chunk-KNKUID7G.js +183 -0
- package/dist/chunk-KNKUID7G.js.map +1 -0
- package/dist/chunk-L2IO2QPY.js +2036 -0
- package/dist/chunk-L2IO2QPY.js.map +1 -0
- package/dist/{chunk-SPI27QT6.js → chunk-L5IIGA5V.js} +9 -4
- package/dist/chunk-L5IIGA5V.js.map +1 -0
- package/dist/{chunk-RGLL5SPU.js → chunk-LVYGDT5V.js} +56 -82
- package/dist/chunk-LVYGDT5V.js.map +1 -0
- package/dist/{chunk-ZAIM4TUE.js → chunk-LW2NMHDW.js} +46 -1
- package/dist/chunk-LW2NMHDW.js.map +1 -0
- package/dist/{chunk-3OGMS3PE.js → chunk-LZRYQK6L.js} +3 -2
- package/dist/chunk-LZRYQK6L.js.map +1 -0
- package/dist/chunk-MDYG7VI7.js +48 -0
- package/dist/chunk-MDYG7VI7.js.map +1 -0
- package/dist/chunk-MXC3AP5I.js +74 -0
- package/dist/chunk-MXC3AP5I.js.map +1 -0
- package/dist/{chunk-S3EEFKNY.js → chunk-N7X62G74.js} +26 -11
- package/dist/chunk-N7X62G74.js.map +1 -0
- package/dist/chunk-NN3TS5BM.js +147 -0
- package/dist/chunk-NN3TS5BM.js.map +1 -0
- package/dist/chunk-OA3L7BFR.js +183 -0
- package/dist/chunk-OA3L7BFR.js.map +1 -0
- package/dist/{chunk-LK6SGL53.js → chunk-OR64ZGRZ.js} +3 -2
- package/dist/chunk-OR64ZGRZ.js.map +1 -0
- package/dist/chunk-OZHRDTDX.js +240 -0
- package/dist/chunk-OZHRDTDX.js.map +1 -0
- package/dist/chunk-PCUKNJAZ.js +165 -0
- package/dist/chunk-PCUKNJAZ.js.map +1 -0
- package/dist/{chunk-6PFRXT4K.js → chunk-PFV5C235.js} +11 -6
- package/dist/chunk-PFV5C235.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/{chunk-XZ2TIKGC.js → chunk-Q7FJ5ZHM.js} +30 -10
- package/dist/chunk-Q7FJ5ZHM.js.map +1 -0
- package/dist/{chunk-7I7FKFZH.js → chunk-R2L7SUX2.js} +6 -6
- package/dist/{chunk-JL2PU6AI.js → chunk-R2XRID2N.js} +2 -2
- package/dist/{chunk-WCLICCGB.js → chunk-RILIVK4O.js} +91 -4
- package/dist/chunk-RILIVK4O.js.map +1 -0
- package/dist/{chunk-C2EFFULQ.js → chunk-RK2Y4XOM.js} +163 -20
- package/dist/chunk-RK2Y4XOM.js.map +1 -0
- package/dist/{chunk-TP4FZJIZ.js → chunk-RULE4VG5.js} +5 -1
- package/dist/chunk-RULE4VG5.js.map +1 -0
- package/dist/{chunk-PVPWZSSI.js → chunk-SMA4IMHV.js} +19 -3
- package/dist/chunk-SMA4IMHV.js.map +1 -0
- package/dist/{chunk-WVVA7F5A.js → chunk-SS253RXF.js} +30 -16
- package/dist/chunk-SS253RXF.js.map +1 -0
- package/dist/chunk-TUFG6VXY.js +875 -0
- package/dist/chunk-TUFG6VXY.js.map +1 -0
- package/dist/chunk-TYEOAFH3.js +251 -0
- package/dist/chunk-TYEOAFH3.js.map +1 -0
- package/dist/chunk-UKJAGEXH.js +260 -0
- package/dist/chunk-UKJAGEXH.js.map +1 -0
- package/dist/{chunk-KVBLZUKV.js → chunk-USFPPRAF.js} +93 -3
- package/dist/chunk-USFPPRAF.js.map +1 -0
- package/dist/{chunk-EPQJM2GC.js → chunk-VTJVUHRK.js} +22 -36
- package/dist/chunk-VTJVUHRK.js.map +1 -0
- package/dist/{chunk-O5ETUNBT.js → chunk-VTU2B4VF.js} +7 -3
- package/dist/chunk-VTU2B4VF.js.map +1 -0
- package/dist/chunk-WIICJPET.js +45 -0
- package/dist/chunk-WIICJPET.js.map +1 -0
- package/dist/{chunk-VBVG2M5G.js → chunk-WPGJYVUH.js} +6 -2
- package/dist/chunk-WPGJYVUH.js.map +1 -0
- package/dist/{chunk-YNQKWQT4.js → chunk-WSZIHQBK.js} +31 -11
- package/dist/{chunk-YNQKWQT4.js.map → chunk-WSZIHQBK.js.map} +1 -1
- package/dist/{chunk-NZLQTHS5.js → chunk-WW3QQF4H.js} +4 -1
- package/dist/chunk-WW3QQF4H.js.map +1 -0
- package/dist/{chunk-FVA6TGI3.js → chunk-Y3WQ4ZWK.js} +42 -2
- package/dist/chunk-Y3WQ4ZWK.js.map +1 -0
- package/dist/chunk-YNJHCGDT.js +309 -0
- package/dist/chunk-YNJHCGDT.js.map +1 -0
- package/dist/{chunk-ALXMCZEU.js → chunk-Z2E7VW55.js} +6 -3
- package/dist/chunk-Z2E7VW55.js.map +1 -0
- package/dist/{chunk-INXV5JBT.js → chunk-ZGXSCMQN.js} +1992 -410
- package/dist/chunk-ZGXSCMQN.js.map +1 -0
- package/dist/{chunk-W6SL7OFG.js → chunk-ZTSE2ZJ6.js} +12 -2
- package/dist/{chunk-W6SL7OFG.js.map → chunk-ZTSE2ZJ6.js.map} +1 -1
- package/dist/chunking.js +1 -0
- package/dist/cipher-GVE2GQ5H.js +28 -0
- package/dist/cipher-GVE2GQ5H.js.map +1 -0
- package/dist/citations.js +1 -0
- package/dist/{cli-BkeRaYfk.d.ts → cli-x2APT9a6.d.ts} +26 -7
- package/dist/cli.d.ts +11 -6
- package/dist/cli.js +68 -34
- package/dist/codex-thread-key.js +1 -0
- package/dist/commitment-ledger.js +1 -0
- package/dist/compression-optimizer.js +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.js +5 -2
- package/dist/connectors-cli-DFGtY2DB.d.ts +257 -0
- package/dist/connectors-cli.d.ts +2 -0
- package/dist/connectors-cli.js +22 -0
- package/dist/connectors-cli.js.map +1 -0
- package/dist/consolidation-operator.d.ts +65 -5
- package/dist/consolidation-operator.js +6 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-provenance-check.js +3 -2
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/consolidation-undo.js +1 -0
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/{contradiction-review-WIUBAR52.js → contradiction-review-5LTTVDQV.js} +2 -1
- package/dist/contradiction-review-5LTTVDQV.js.map +1 -0
- package/dist/{contradiction-scan-E3GJTI4F.js → contradiction-scan-3Z6YW7YA.js} +2 -1
- package/dist/{contradiction-scan-E3GJTI4F.js.map → contradiction-scan-3Z6YW7YA.js.map} +1 -1
- package/dist/cross-namespace-budget.js +1 -0
- package/dist/cue-anchors.js +1 -0
- package/dist/dashboard-runtime.js +1 -0
- package/dist/day-summary.js +1 -0
- package/dist/delinearize.js +1 -0
- package/dist/direct-answer-wiring.js +1 -0
- package/dist/direct-answer.js +1 -0
- package/dist/dreams-ledger-LR2NBAZE.js +286 -0
- package/dist/dreams-ledger-LR2NBAZE.js.map +1 -0
- package/dist/embedding-fallback.js +3 -1
- package/dist/{engine-F3GOXGE5.js → engine-ICC2DSQF.js} +10 -7
- package/dist/engine-ICC2DSQF.js.map +1 -0
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +9 -6
- package/dist/entity-schema.js +1 -0
- package/dist/evals.js +1 -0
- package/dist/evidence-pack.d.ts +16 -0
- package/dist/evidence-pack.js +8 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/explicit-capture.d.ts +6 -4
- package/dist/explicit-capture.js +1 -0
- package/dist/extraction-judge-telemetry.js +1 -0
- package/dist/extraction-judge-training.js +1 -0
- package/dist/extraction-judge.js +1 -0
- package/dist/extraction.js +9 -8
- package/dist/fallback-llm.js +3 -2
- package/dist/first-start-migration-4MHQEOSD.js +263 -0
- package/dist/first-start-migration-4MHQEOSD.js.map +1 -0
- package/dist/forget-PLR6J5DN.js +69 -0
- package/dist/forget-PLR6J5DN.js.map +1 -0
- package/dist/framework-CyHYDcri.d.ts +153 -0
- package/dist/fs-utils-IRVUFB6G.js +30 -0
- package/dist/fs-utils-IRVUFB6G.js.map +1 -0
- package/dist/graph-dashboard-diff.js +1 -0
- package/dist/graph-dashboard-key.js +1 -0
- package/dist/graph-dashboard-parser.js +1 -0
- package/dist/graph-edge-decay-PWB63GRE.js +207 -0
- package/dist/graph-edge-decay-PWB63GRE.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +81 -0
- package/dist/graph-edge-reinforcement.js +24 -0
- package/dist/graph-edge-reinforcement.js.map +1 -0
- package/dist/graph-events.d.ts +87 -0
- package/dist/graph-events.js +14 -0
- package/dist/graph-events.js.map +1 -0
- package/dist/graph-recall.js +1 -0
- package/dist/graph-retrieval.js +1 -0
- package/dist/graph-snapshot.d.ts +112 -0
- package/dist/graph-snapshot.js +19 -0
- package/dist/graph-snapshot.js.map +1 -0
- package/dist/graph.d.ts +105 -7
- package/dist/graph.js +20 -3
- package/dist/harmonic-retrieval.js +1 -0
- package/dist/himem.js +1 -0
- package/dist/hygiene.js +1 -0
- package/dist/identity-continuity.js +1 -0
- package/dist/importance.js +1 -0
- package/dist/index.d.ts +562 -13
- package/dist/index.js +365 -96
- package/dist/index.js.map +1 -1
- package/dist/intent.js +1 -0
- package/dist/json-extract.js +1 -0
- package/dist/json-store.js +1 -0
- package/dist/kdf-7S6RWKLZ.js +26 -0
- package/dist/kdf-7S6RWKLZ.js.map +1 -0
- package/dist/legacy-hook-compat.js +1 -0
- package/dist/legacy-hook-compat.js.map +1 -1
- package/dist/lifecycle.js +1 -0
- package/dist/live-connectors-runner.d.ts +48 -0
- package/dist/live-connectors-runner.js +17 -0
- package/dist/live-connectors-runner.js.map +1 -0
- package/dist/local-llm.js +3 -2
- package/dist/logger.js +1 -0
- package/dist/memory-action-policy.js +1 -0
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-cache.js +4 -1
- package/dist/memory-governance-KG52RITE.js +37 -0
- package/dist/memory-governance-KG52RITE.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.js +4 -1
- package/dist/memory-projection-format.js +1 -0
- package/dist/{memory-projection-store-DeSXPh1j.d.ts → memory-projection-store-D3vBHS4J.d.ts} +1 -0
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-projection-store.js +1 -0
- package/dist/memory-worth-bench.js +1 -0
- package/dist/memory-worth-bench.js.map +1 -1
- package/dist/memory-worth-filter.js +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/memory-worth-outcomes.js +1 -0
- package/dist/memory-worth.js +1 -0
- package/dist/metadata-FC3XPDRQ.js +21 -0
- package/dist/metadata-FC3XPDRQ.js.map +1 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js +8 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js.map +1 -0
- package/dist/model-registry.js +1 -0
- package/dist/models-json.js +1 -0
- package/dist/native-knowledge.js +1 -0
- package/dist/negative.js +1 -0
- package/dist/objective-state-writers.js +1 -0
- package/dist/objective-state-writers.js.map +1 -1
- package/dist/objective-state.js +1 -0
- package/dist/openai-chat-compat.js +1 -0
- package/dist/operator-toolkit.d.ts +46 -2
- package/dist/operator-toolkit.js +29 -17
- package/dist/opik-exporter.js +1 -0
- package/dist/opik-exporter.js.map +1 -1
- package/dist/{orchestrator-CmJ-NTdJ.d.ts → orchestrator-ChkesB8U.d.ts} +177 -13
- package/dist/orchestrator.d.ts +6 -4
- package/dist/orchestrator.js +58 -42
- package/dist/page-versioning.js +1 -0
- package/dist/path-RMTY5Y5A.js +9 -0
- package/dist/path-RMTY5Y5A.js.map +1 -0
- package/dist/patterns-cli.d.ts +160 -0
- package/dist/patterns-cli.js +29 -0
- package/dist/patterns-cli.js.map +1 -0
- package/dist/peers-6OSQ3NK6.js +44 -0
- package/dist/peers-6OSQ3NK6.js.map +1 -0
- package/dist/plugin-id.js +1 -0
- package/dist/policy-runtime.js +1 -0
- package/dist/{port-BADbLZU5.d.ts → port-hqGnoStS.d.ts} +6 -0
- package/dist/profiling.js +1 -0
- package/dist/purge-6ATBGT77.js +205 -0
- package/dist/purge-6ATBGT77.js.map +1 -0
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd-recall-cache.js +1 -0
- package/dist/qmd.d.ts +2 -1
- package/dist/qmd.js +4 -3
- package/dist/reasoning-trace-recall.js +1 -0
- package/dist/reasoning-trace-types.js +1 -0
- package/dist/recall-audit-anomaly.js +1 -0
- package/dist/recall-audit.js +1 -0
- package/dist/recall-disclosure-escalation.d.ts +84 -0
- package/dist/recall-disclosure-escalation.js +14 -0
- package/dist/recall-disclosure-escalation.js.map +1 -0
- package/dist/recall-explain-renderer.js +4 -1
- package/dist/recall-mmr.js +1 -0
- package/dist/recall-qos.js +1 -0
- package/dist/recall-query-policy.js +1 -0
- package/dist/recall-state.d.ts +7 -0
- package/dist/recall-state.js +2 -1
- package/dist/recall-tag-filter.d.ts +56 -0
- package/dist/recall-tag-filter.js +14 -0
- package/dist/recall-tag-filter.js.map +1 -0
- package/dist/recall-tokenization.js +1 -0
- package/dist/recall-xray-cli.d.ts +9 -2
- package/dist/recall-xray-cli.js +9 -4
- package/dist/recall-xray-renderer.js +4 -1
- package/dist/recall-xray.d.ts +116 -2
- package/dist/recall-xray.js +9 -3
- package/dist/reconstruct.js +1 -0
- package/dist/release-changelog.js +2 -0
- package/dist/release-changelog.js.map +1 -1
- package/dist/relevance.js +1 -0
- package/dist/rerank.js +1 -0
- package/dist/{resolution-QBTDHTG7.js → resolution-YGIBORXI.js} +2 -1
- package/dist/{resolution-QBTDHTG7.js.map → resolution-YGIBORXI.js.map} +1 -1
- package/dist/resolve-auth-token.d.ts +51 -0
- package/dist/resolve-auth-token.js +12 -0
- package/dist/resolve-auth-token.js.map +1 -0
- package/dist/resolve-provider-secret.d.ts +13 -1
- package/dist/resolve-provider-secret.js +6 -1
- package/dist/resume-bundles.js +5 -4
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-agents.js +1 -0
- package/dist/retrieval-tiers.js +1 -0
- package/dist/retrieval.js +1 -0
- package/dist/sanitize.js +1 -0
- package/dist/schemas.d.ts +15 -2
- package/dist/schemas.js +2 -1
- package/dist/sdk-compat.js +1 -0
- package/dist/sdk-compat.js.map +1 -1
- package/dist/secure-store-4R2GSO7S.js +156 -0
- package/dist/secure-store-4R2GSO7S.js.map +1 -0
- package/dist/semantic-chunking.js +1 -0
- package/dist/{semantic-consolidation-CxJU6MJk.d.ts → semantic-consolidation-ByBXb-sf.d.ts} +3 -3
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +12 -6
- package/dist/semantic-rule-promotion.d.ts +1 -1
- package/dist/semantic-rule-promotion.js +9 -6
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -6
- package/dist/session-integrity.js +1 -0
- package/dist/session-observer-bands.js +1 -0
- package/dist/session-observer-state.js +1 -0
- package/dist/session-toggles.js +2 -0
- package/dist/session-toggles.js.map +1 -1
- package/dist/signal.js +1 -0
- package/dist/skills-registry.js +2 -0
- package/dist/skills-registry.js.map +1 -1
- package/dist/source-attribution.js +1 -0
- package/dist/state-NCHQ4TRG.js +8 -0
- package/dist/state-NCHQ4TRG.js.map +1 -0
- package/dist/state-store-3EH7HYIN.js +16 -0
- package/dist/state-store-3EH7HYIN.js.map +1 -0
- package/dist/storage.d.ts +76 -2
- package/dist/storage.js +8 -5
- package/dist/store-contract.js +1 -0
- package/dist/summarizer.js +6 -5
- package/dist/summary-snapshot.js +1 -0
- package/dist/temporal-index.js +1 -0
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +2 -1
- package/dist/temporal-validity.d.ts +52 -0
- package/dist/temporal-validity.js +14 -0
- package/dist/temporal-validity.js.map +1 -0
- package/dist/threading.js +1 -0
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-migration.js +1 -0
- package/dist/tier-routing.js +1 -0
- package/dist/tier-stats-62ZVDFKS.js +152 -0
- package/dist/tier-stats-62ZVDFKS.js.map +1 -0
- package/dist/tmt.js +1 -0
- package/dist/tokens.js +3 -1
- package/dist/topics.js +1 -0
- package/dist/trace-C5ETWBEF.js +290 -0
- package/dist/trace-C5ETWBEF.js.map +1 -0
- package/dist/transcript.js +1 -0
- package/dist/trust-zones.js +1 -0
- package/dist/tui-RI7P6PBS.js +13 -0
- package/dist/tui-RI7P6PBS.js.map +1 -0
- package/dist/types-V3FJ26TF.js +30 -0
- package/dist/types-V3FJ26TF.js.map +1 -0
- package/dist/types.d.ts +634 -9
- package/dist/types.js +10 -3
- package/dist/utility-learner.js +1 -0
- package/dist/utility-runtime.js +1 -0
- package/dist/utility-telemetry.js +1 -0
- package/dist/verified-recall.js +9 -6
- package/dist/version-utils.js +1 -0
- package/dist/whitespace.js +1 -0
- package/dist/work-product-ledger.js +1 -0
- package/package.json +2 -1
- package/dist/access-service-Br8ZydTK.d.ts +0 -827
- package/dist/chunk-3OGMS3PE.js.map +0 -1
- package/dist/chunk-6PFRXT4K.js.map +0 -1
- package/dist/chunk-ALXMCZEU.js.map +0 -1
- package/dist/chunk-B5WXLVDY.js.map +0 -1
- package/dist/chunk-BGJGXLZ7.js.map +0 -1
- package/dist/chunk-BK2EFTE2.js.map +0 -1
- package/dist/chunk-C2EFFULQ.js.map +0 -1
- package/dist/chunk-CUPFXL3J.js.map +0 -1
- package/dist/chunk-DFTTJYSO.js.map +0 -1
- package/dist/chunk-EPQJM2GC.js.map +0 -1
- package/dist/chunk-F5VP6YCB.js.map +0 -1
- package/dist/chunk-FVA6TGI3.js.map +0 -1
- package/dist/chunk-GKFXUTJ2.js.map +0 -1
- package/dist/chunk-HK3FGIEW.js.map +0 -1
- package/dist/chunk-INXV5JBT.js.map +0 -1
- package/dist/chunk-KVBLZUKV.js.map +0 -1
- package/dist/chunk-LK6SGL53.js.map +0 -1
- package/dist/chunk-LTCGGW2D.js +0 -14
- package/dist/chunk-LTCGGW2D.js.map +0 -1
- package/dist/chunk-NZLQTHS5.js.map +0 -1
- package/dist/chunk-O5ETUNBT.js.map +0 -1
- package/dist/chunk-PVPWZSSI.js.map +0 -1
- package/dist/chunk-RGLL5SPU.js.map +0 -1
- package/dist/chunk-S3EEFKNY.js.map +0 -1
- package/dist/chunk-SPI27QT6.js.map +0 -1
- package/dist/chunk-TP4FZJIZ.js.map +0 -1
- package/dist/chunk-ULYOGL6R.js.map +0 -1
- package/dist/chunk-VBVG2M5G.js.map +0 -1
- package/dist/chunk-VDX363PS.js.map +0 -1
- package/dist/chunk-VYM3VWOF.js.map +0 -1
- package/dist/chunk-WCLICCGB.js.map +0 -1
- package/dist/chunk-WVVA7F5A.js.map +0 -1
- package/dist/chunk-X6GF3FX2.js +0 -26
- package/dist/chunk-X6GF3FX2.js.map +0 -1
- package/dist/chunk-XZ2TIKGC.js.map +0 -1
- package/dist/chunk-ZAIM4TUE.js.map +0 -1
- /package/dist/{contradiction-review-WIUBAR52.js.map → capsule-cli.js.map} +0 -0
- /package/dist/{engine-F3GOXGE5.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
- /package/dist/{chunk-KUB6JU6H.js.map → chunk-47WOM4YW.js.map} +0 -0
- /package/dist/{chunk-ZEM3OK2K.js.map → chunk-B2TL6GA2.js.map} +0 -0
- /package/dist/{chunk-3GXCSUXR.js.map → chunk-CRU27Q4J.js.map} +0 -0
- /package/dist/{chunk-RBBWYEFJ.js.map → chunk-G2WADRQ3.js.map} +0 -0
- /package/dist/{chunk-7I7FKFZH.js.map → chunk-R2L7SUX2.js.map} +0 -0
- /package/dist/{chunk-JL2PU6AI.js.map → chunk-R2XRID2N.js.map} +0 -0
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
SecureStoreLockedError,
|
|
3
|
+
isEncryptedFile,
|
|
4
|
+
readMaybeEncryptedFile,
|
|
5
|
+
writeMaybeEncryptedFile
|
|
6
|
+
} from "./chunk-YNJHCGDT.js";
|
|
5
7
|
import {
|
|
6
8
|
DEFAULT_CITATION_FORMAT,
|
|
7
9
|
hasCitation,
|
|
8
10
|
stripCitationForTemplate
|
|
9
11
|
} from "./chunk-4KAN3GZ3.js";
|
|
12
|
+
import {
|
|
13
|
+
SPECULATIVE_TTL_DAYS,
|
|
14
|
+
confidenceTier
|
|
15
|
+
} from "./chunk-43EKP2UK.js";
|
|
10
16
|
import {
|
|
11
17
|
getCachedEntities,
|
|
18
|
+
invalidateCachedEntities,
|
|
12
19
|
setCachedEntities
|
|
13
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-PFV5C235.js";
|
|
14
21
|
import {
|
|
15
22
|
inferMemoryStatus,
|
|
16
23
|
isArchivedMemoryPath,
|
|
17
24
|
sortMemoryLifecycleEvents,
|
|
18
25
|
toMemoryPathRel
|
|
19
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-RULE4VG5.js";
|
|
20
27
|
import {
|
|
21
28
|
normalizeProjectionPreview,
|
|
22
29
|
normalizeProjectionTags
|
|
@@ -50,7 +57,7 @@ import {
|
|
|
50
57
|
import {
|
|
51
58
|
isConsolidationOperator,
|
|
52
59
|
isValidDerivedFromEntry
|
|
53
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-G7D6GZ5J.js";
|
|
54
61
|
import {
|
|
55
62
|
createVersion
|
|
56
63
|
} from "./chunk-FAAFWE4G.js";
|
|
@@ -59,7 +66,7 @@ import {
|
|
|
59
66
|
} from "./chunk-2ODBA7MQ.js";
|
|
60
67
|
|
|
61
68
|
// src/storage.ts
|
|
62
|
-
import { access, readdir, readFile, stat, writeFile, mkdir, unlink,
|
|
69
|
+
import { access, readdir, readFile, stat, writeFile, mkdir, unlink, appendFile } from "fs/promises";
|
|
63
70
|
import { appendFileSync, mkdirSync, statSync } from "fs";
|
|
64
71
|
import { createHash } from "crypto";
|
|
65
72
|
import path from "path";
|
|
@@ -106,6 +113,88 @@ function assertMemoryWorthCounter(field, value) {
|
|
|
106
113
|
throw new Error(`${field} must be >= 0, got ${value}`);
|
|
107
114
|
}
|
|
108
115
|
}
|
|
116
|
+
function isErrnoCode(error, code) {
|
|
117
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
118
|
+
}
|
|
119
|
+
function trimTrailingSpacesAndTabs(value) {
|
|
120
|
+
let end = value.length;
|
|
121
|
+
while (end > 0 && (value[end - 1] === " " || value[end - 1] === " ")) {
|
|
122
|
+
end -= 1;
|
|
123
|
+
}
|
|
124
|
+
return end === value.length ? value : value.slice(0, end);
|
|
125
|
+
}
|
|
126
|
+
function trimLeadingSpacesAndTabs(value) {
|
|
127
|
+
let start = 0;
|
|
128
|
+
while (start < value.length && (value[start] === " " || value[start] === " ")) {
|
|
129
|
+
start += 1;
|
|
130
|
+
}
|
|
131
|
+
return start === 0 ? value : value.slice(start);
|
|
132
|
+
}
|
|
133
|
+
function stripDefaultCitationMarkersWithoutRegex(value) {
|
|
134
|
+
return stripCitationMarkersForHashRemoval(value, DEFAULT_CITATION_FORMAT);
|
|
135
|
+
}
|
|
136
|
+
function citationTemplateLiteralParts(template) {
|
|
137
|
+
const parts = [];
|
|
138
|
+
let cursor = 0;
|
|
139
|
+
while (cursor < template.length) {
|
|
140
|
+
const open = template.indexOf("{", cursor);
|
|
141
|
+
if (open === -1) {
|
|
142
|
+
parts.push(template.slice(cursor));
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
parts.push(template.slice(cursor, open));
|
|
146
|
+
const close = template.indexOf("}", open + 1);
|
|
147
|
+
if (close === -1) {
|
|
148
|
+
cursor = open + 1;
|
|
149
|
+
} else {
|
|
150
|
+
cursor = close + 1;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return parts.filter((part) => part.length > 0);
|
|
154
|
+
}
|
|
155
|
+
function stripCitationMarkersForHashRemoval(value, template) {
|
|
156
|
+
const parts = citationTemplateLiteralParts(template);
|
|
157
|
+
if (parts.length === 0) return value;
|
|
158
|
+
const first = parts[0];
|
|
159
|
+
const lowerValue = value.toLowerCase();
|
|
160
|
+
const lowerFirst = first.toLowerCase();
|
|
161
|
+
const lowerParts = parts.map((part) => part.toLowerCase());
|
|
162
|
+
if (!lowerValue.includes(lowerFirst)) return value;
|
|
163
|
+
let result = "";
|
|
164
|
+
let cursor = 0;
|
|
165
|
+
let removed = false;
|
|
166
|
+
while (cursor < value.length) {
|
|
167
|
+
const markerStart = lowerValue.indexOf(lowerFirst, cursor);
|
|
168
|
+
if (markerStart === -1) {
|
|
169
|
+
result += value.slice(cursor);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
const boundedEnd = first.startsWith("[") ? value.indexOf("]", markerStart + first.length) : -1;
|
|
173
|
+
if (first.startsWith("[") && boundedEnd === -1) {
|
|
174
|
+
result += value.slice(cursor);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
const searchLimit = boundedEnd === -1 ? value.length : boundedEnd + 1;
|
|
178
|
+
let markerEnd = markerStart + first.length;
|
|
179
|
+
let matched = true;
|
|
180
|
+
for (let i = 1; i < lowerParts.length; i += 1) {
|
|
181
|
+
const partIndex = lowerValue.indexOf(lowerParts[i], markerEnd);
|
|
182
|
+
if (partIndex === -1 || partIndex + parts[i].length > searchLimit) {
|
|
183
|
+
matched = false;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
markerEnd = partIndex + parts[i].length;
|
|
187
|
+
}
|
|
188
|
+
if (!matched) {
|
|
189
|
+
result += value.slice(cursor);
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
result += trimTrailingSpacesAndTabs(value.slice(cursor, markerStart));
|
|
193
|
+
cursor = markerEnd;
|
|
194
|
+
removed = true;
|
|
195
|
+
}
|
|
196
|
+
return removed ? trimLeadingSpacesAndTabs(result) : value;
|
|
197
|
+
}
|
|
109
198
|
function serializeFrontmatter(fm) {
|
|
110
199
|
const lines = [
|
|
111
200
|
"---",
|
|
@@ -128,6 +217,10 @@ function serializeFrontmatter(fm) {
|
|
|
128
217
|
if (fm.supersededBy) lines.push(`supersededBy: ${fm.supersededBy}`);
|
|
129
218
|
if (fm.supersededAt) lines.push(`supersededAt: ${fm.supersededAt}`);
|
|
130
219
|
if (fm.archivedAt) lines.push(`archivedAt: ${fm.archivedAt}`);
|
|
220
|
+
if (fm.valid_at) lines.push(`validAt: ${fm.valid_at}`);
|
|
221
|
+
if (fm.invalid_at) lines.push(`invalidAt: ${fm.invalid_at}`);
|
|
222
|
+
if (fm.forgottenAt) lines.push(`forgottenAt: ${fm.forgottenAt}`);
|
|
223
|
+
if (fm.forgottenReason) lines.push(`forgottenReason: ${JSON.stringify(fm.forgottenReason)}`);
|
|
131
224
|
if (fm.lifecycleState) lines.push(`lifecycleState: ${fm.lifecycleState}`);
|
|
132
225
|
if (fm.verificationState) lines.push(`verificationState: ${fm.verificationState}`);
|
|
133
226
|
if (fm.policyClass) lines.push(`policyClass: ${fm.policyClass}`);
|
|
@@ -205,11 +298,22 @@ function serializeFrontmatter(fm) {
|
|
|
205
298
|
if (fm.derived_via !== void 0) {
|
|
206
299
|
if (!isConsolidationOperator(fm.derived_via)) {
|
|
207
300
|
throw new Error(
|
|
208
|
-
`serializeFrontmatter: invalid derived_via ${JSON.stringify(fm.derived_via)} \u2014 expected one of "split" | "merge" | "update"`
|
|
301
|
+
`serializeFrontmatter: invalid derived_via ${JSON.stringify(fm.derived_via)} \u2014 expected one of "split" | "merge" | "update" | "pattern-reinforcement"`
|
|
209
302
|
);
|
|
210
303
|
}
|
|
211
304
|
lines.push(`derived_via: ${fm.derived_via}`);
|
|
212
305
|
}
|
|
306
|
+
if (fm.reinforcement_count !== void 0) {
|
|
307
|
+
if (!Number.isInteger(fm.reinforcement_count) || fm.reinforcement_count <= 0) {
|
|
308
|
+
throw new Error(
|
|
309
|
+
`serializeFrontmatter: reinforcement_count must be a positive integer (got ${JSON.stringify(fm.reinforcement_count)})`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
lines.push(`reinforcement_count: ${fm.reinforcement_count}`);
|
|
313
|
+
}
|
|
314
|
+
if (fm.last_reinforced_at) {
|
|
315
|
+
lines.push(`last_reinforced_at: ${fm.last_reinforced_at}`);
|
|
316
|
+
}
|
|
213
317
|
lines.push("---");
|
|
214
318
|
return lines.join("\n");
|
|
215
319
|
}
|
|
@@ -242,6 +346,20 @@ function parseLinkReasonValue(rawValue) {
|
|
|
242
346
|
return legacyValue;
|
|
243
347
|
}
|
|
244
348
|
}
|
|
349
|
+
function parseFrontmatterStringValue(rawValue) {
|
|
350
|
+
if (rawValue === void 0) return void 0;
|
|
351
|
+
const trimmed = rawValue.trim();
|
|
352
|
+
if (trimmed.length === 0) return void 0;
|
|
353
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
354
|
+
try {
|
|
355
|
+
const parsed = JSON.parse(trimmed);
|
|
356
|
+
return typeof parsed === "string" ? parsed : trimmed;
|
|
357
|
+
} catch {
|
|
358
|
+
return trimmed.slice(1, -1).replace(/\\"/g, '"');
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return trimmed;
|
|
362
|
+
}
|
|
245
363
|
function parseMemoryWorthCounterField(raw) {
|
|
246
364
|
if (raw === void 0) return void 0;
|
|
247
365
|
const trimmed = raw.trim();
|
|
@@ -250,6 +368,14 @@ function parseMemoryWorthCounterField(raw) {
|
|
|
250
368
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) return void 0;
|
|
251
369
|
return n;
|
|
252
370
|
}
|
|
371
|
+
function parseReinforcementCountField(raw) {
|
|
372
|
+
if (raw === void 0) return void 0;
|
|
373
|
+
const trimmed = raw.trim();
|
|
374
|
+
if (trimmed.length === 0) return void 0;
|
|
375
|
+
const n = Number(trimmed);
|
|
376
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) return void 0;
|
|
377
|
+
return n;
|
|
378
|
+
}
|
|
253
379
|
function parseFrontmatter(raw) {
|
|
254
380
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
255
381
|
if (!match) return null;
|
|
@@ -435,6 +561,11 @@ function parseFrontmatter(raw) {
|
|
|
435
561
|
supersededBy: fm.supersededBy || void 0,
|
|
436
562
|
supersededAt: fm.supersededAt || void 0,
|
|
437
563
|
archivedAt: fm.archivedAt || void 0,
|
|
564
|
+
// Issue #680 — explicit fact lifecycle round-trip.
|
|
565
|
+
valid_at: fm.validAt || void 0,
|
|
566
|
+
invalid_at: fm.invalidAt || void 0,
|
|
567
|
+
forgottenAt: fm.forgottenAt || void 0,
|
|
568
|
+
forgottenReason: parseFrontmatterStringValue(fm.forgottenReason),
|
|
438
569
|
lifecycleState: fm.lifecycleState || void 0,
|
|
439
570
|
verificationState: fm.verificationState || void 0,
|
|
440
571
|
policyClass: fm.policyClass || void 0,
|
|
@@ -469,7 +600,14 @@ function parseFrontmatter(raw) {
|
|
|
469
600
|
// Consolidation provenance (issue #561) — read-through only in this
|
|
470
601
|
// PR; no code produces these fields yet.
|
|
471
602
|
derived_from,
|
|
472
|
-
derived_via
|
|
603
|
+
derived_via,
|
|
604
|
+
// Pattern-reinforcement metadata (issue #687 PR 2/4). Parse
|
|
605
|
+
// permissively: invalid values (negative, non-integer, blank
|
|
606
|
+
// ISO-strings) are dropped to undefined so a corrupt frontmatter
|
|
607
|
+
// never poisons downstream scoring. Validation lives on the
|
|
608
|
+
// write path in serializeFrontmatter.
|
|
609
|
+
reinforcement_count: parseReinforcementCountField(fm.reinforcement_count),
|
|
610
|
+
last_reinforced_at: fm.last_reinforced_at || void 0
|
|
473
611
|
},
|
|
474
612
|
content
|
|
475
613
|
};
|
|
@@ -580,13 +718,19 @@ var ContentHashIndex = class _ContentHashIndex {
|
|
|
580
718
|
hashes = /* @__PURE__ */ new Set();
|
|
581
719
|
dirty = false;
|
|
582
720
|
filePath;
|
|
583
|
-
|
|
721
|
+
secureStoreKeyProvider;
|
|
722
|
+
secureStoreWriteKeyProvider;
|
|
723
|
+
memoryDir;
|
|
724
|
+
constructor(stateDir, secureStoreKeyProvider = () => null, secureStoreWriteKeyProvider = secureStoreKeyProvider, memoryDir = path.dirname(stateDir)) {
|
|
584
725
|
this.filePath = path.join(stateDir, "fact-hashes.txt");
|
|
726
|
+
this.secureStoreKeyProvider = secureStoreKeyProvider;
|
|
727
|
+
this.secureStoreWriteKeyProvider = secureStoreWriteKeyProvider;
|
|
728
|
+
this.memoryDir = memoryDir;
|
|
585
729
|
}
|
|
586
730
|
/** Load existing hashes from disk. Safe to call multiple times. */
|
|
587
731
|
async load() {
|
|
588
732
|
try {
|
|
589
|
-
const raw = await
|
|
733
|
+
const raw = await readMaybeEncryptedFile(this.filePath, this.secureStoreKeyProvider(), this.memoryDir);
|
|
590
734
|
for (const line of raw.split("\n")) {
|
|
591
735
|
const trimmed = line.trim();
|
|
592
736
|
if (trimmed.length > 0) {
|
|
@@ -594,7 +738,9 @@ var ContentHashIndex = class _ContentHashIndex {
|
|
|
594
738
|
}
|
|
595
739
|
}
|
|
596
740
|
log.debug(`content-hash index: loaded ${this.hashes.size} hashes`);
|
|
597
|
-
} catch {
|
|
741
|
+
} catch (err) {
|
|
742
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
743
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
598
744
|
log.debug("content-hash index: no existing index \u2014 starting fresh");
|
|
599
745
|
}
|
|
600
746
|
}
|
|
@@ -617,7 +763,13 @@ var ContentHashIndex = class _ContentHashIndex {
|
|
|
617
763
|
async save() {
|
|
618
764
|
if (!this.dirty) return;
|
|
619
765
|
await mkdir(path.dirname(this.filePath), { recursive: true });
|
|
620
|
-
await
|
|
766
|
+
await writeMaybeEncryptedFile(
|
|
767
|
+
this.filePath,
|
|
768
|
+
[...this.hashes].join("\n") + "\n",
|
|
769
|
+
this.secureStoreWriteKeyProvider(),
|
|
770
|
+
{},
|
|
771
|
+
this.memoryDir
|
|
772
|
+
);
|
|
621
773
|
this.dirty = false;
|
|
622
774
|
log.debug(`content-hash index: saved ${this.hashes.size} hashes`);
|
|
623
775
|
}
|
|
@@ -1480,6 +1632,8 @@ var StorageManager = class _StorageManager {
|
|
|
1480
1632
|
// 1 minute
|
|
1481
1633
|
static artifactWriteVersionByDir = /* @__PURE__ */ new Map();
|
|
1482
1634
|
static memoryStatusVersionByDir = /* @__PURE__ */ new Map();
|
|
1635
|
+
static secureStoreEntityCacheKeyIds = /* @__PURE__ */ new WeakMap();
|
|
1636
|
+
static nextSecureStoreEntityCacheKeyId = 1;
|
|
1483
1637
|
// In-process fallback for the cold-write sentinel (used when the disk file
|
|
1484
1638
|
// is not accessible). The canonical source of truth is state/cold-write.log.
|
|
1485
1639
|
static coldWriteVersionByDir = /* @__PURE__ */ new Map();
|
|
@@ -1527,6 +1681,7 @@ var StorageManager = class _StorageManager {
|
|
|
1527
1681
|
factHashIndexLoadPromise = null;
|
|
1528
1682
|
factHashIndexAuthoritative = null;
|
|
1529
1683
|
factHashIndexAuthoritativePromise = null;
|
|
1684
|
+
secureAppendChains = /* @__PURE__ */ new Map();
|
|
1530
1685
|
/** Optional: set by the orchestrator after construction to enable template-aware citation stripping during legacy hash rebuild. */
|
|
1531
1686
|
citationTemplate = DEFAULT_CITATION_FORMAT;
|
|
1532
1687
|
/** Page-versioning configuration. Set by the orchestrator after construction. */
|
|
@@ -1535,6 +1690,87 @@ var StorageManager = class _StorageManager {
|
|
|
1535
1690
|
setVersioningConfig(config) {
|
|
1536
1691
|
this._versioningConfig = config;
|
|
1537
1692
|
}
|
|
1693
|
+
/**
|
|
1694
|
+
* At-rest encryption key (issue #690 PR 3/4).
|
|
1695
|
+
*
|
|
1696
|
+
* When non-null, every memory file read is decrypted and every write
|
|
1697
|
+
* is encrypted using the secure-fs layer. When null, the storage
|
|
1698
|
+
* layer operates in plain-text mode (legacy/unencrypted store).
|
|
1699
|
+
*
|
|
1700
|
+
* Set by the orchestrator after init/unlock; cleared on lock.
|
|
1701
|
+
* The key buffer is NEVER logged or serialized.
|
|
1702
|
+
*/
|
|
1703
|
+
_secureStoreKey = null;
|
|
1704
|
+
/**
|
|
1705
|
+
* When true (and `_secureStoreKey` is non-null), new writes are
|
|
1706
|
+
* encrypted. Set to false to pause encryption of new writes while
|
|
1707
|
+
* still decrypting existing files.
|
|
1708
|
+
*/
|
|
1709
|
+
_secureStoreEncryptOnWrite = true;
|
|
1710
|
+
/**
|
|
1711
|
+
* When true, the secure-store is configured as required — writes
|
|
1712
|
+
* MUST be encrypted and a locked store MUST reject writes rather
|
|
1713
|
+
* than silently falling back to plaintext. Set by the orchestrator
|
|
1714
|
+
* from `config.secureStoreEnabled`.
|
|
1715
|
+
*/
|
|
1716
|
+
_secureStoreRequired = false;
|
|
1717
|
+
/**
|
|
1718
|
+
* Set or clear the at-rest encryption key.
|
|
1719
|
+
*
|
|
1720
|
+
* Pass a 32-byte Buffer to enable encryption; pass null to clear
|
|
1721
|
+
* (lock) the store. The caller is responsible for key lifecycle —
|
|
1722
|
+
* this method does not zero the buffer on replacement; the keyring
|
|
1723
|
+
* module (`keyring.ts`) owns zeroization.
|
|
1724
|
+
*/
|
|
1725
|
+
setSecureStoreKey(key, encryptOnWrite = true) {
|
|
1726
|
+
this._secureStoreKey = key;
|
|
1727
|
+
this._secureStoreEncryptOnWrite = encryptOnWrite;
|
|
1728
|
+
invalidateCachedEntities(this.baseDir);
|
|
1729
|
+
this.invalidateKnowledgeIndexCache();
|
|
1730
|
+
}
|
|
1731
|
+
getEntityCacheSecureStoreKey() {
|
|
1732
|
+
if (!this._secureStoreKey) return "secure-store:locked";
|
|
1733
|
+
let id = _StorageManager.secureStoreEntityCacheKeyIds.get(this._secureStoreKey);
|
|
1734
|
+
if (id === void 0) {
|
|
1735
|
+
id = _StorageManager.nextSecureStoreEntityCacheKeyId++;
|
|
1736
|
+
_StorageManager.secureStoreEntityCacheKeyIds.set(this._secureStoreKey, id);
|
|
1737
|
+
}
|
|
1738
|
+
return `secure-store:key:${id}`;
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Mark the secure-store as required for this storage instance.
|
|
1742
|
+
* When required and locked, writes throw SecureStoreLockedError
|
|
1743
|
+
* rather than silently writing plaintext.
|
|
1744
|
+
*/
|
|
1745
|
+
setSecureStoreRequired(required) {
|
|
1746
|
+
this._secureStoreRequired = required;
|
|
1747
|
+
}
|
|
1748
|
+
/** Return true iff the secure-store key is currently set (store is unlocked). */
|
|
1749
|
+
isSecureStoreUnlocked() {
|
|
1750
|
+
return this._secureStoreKey !== null;
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Resolve the effective write key.
|
|
1754
|
+
*
|
|
1755
|
+
* - If `_secureStoreEncryptOnWrite` is false: returns null (plain write).
|
|
1756
|
+
* - If `_secureStoreEncryptOnWrite` is true AND key is set: returns key.
|
|
1757
|
+
* - If `_secureStoreEncryptOnWrite` is true AND key is null AND
|
|
1758
|
+
* `_secureStoreRequired` is true: throws SecureStoreLockedError so the
|
|
1759
|
+
* write fails loudly rather than silently writing plaintext (P1 finding
|
|
1760
|
+
* from Cursor review of PR #767).
|
|
1761
|
+
* - If `_secureStoreEncryptOnWrite` is true AND key is null AND
|
|
1762
|
+
* `_secureStoreRequired` is false: returns null (unencrypted store).
|
|
1763
|
+
*/
|
|
1764
|
+
resolveWriteKey() {
|
|
1765
|
+
if (!this._secureStoreEncryptOnWrite) return null;
|
|
1766
|
+
if (this._secureStoreKey !== null) return this._secureStoreKey;
|
|
1767
|
+
if (this._secureStoreRequired) {
|
|
1768
|
+
throw new SecureStoreLockedError(
|
|
1769
|
+
"secure-store is locked \u2014 cannot write memory file. Run `remnic secure-store unlock` to decrypt, or restart the daemon after unlocking."
|
|
1770
|
+
);
|
|
1771
|
+
}
|
|
1772
|
+
return null;
|
|
1773
|
+
}
|
|
1538
1774
|
/**
|
|
1539
1775
|
* Snapshot the current content of a page before overwriting.
|
|
1540
1776
|
* No-op when versioning is disabled or the file does not yet exist.
|
|
@@ -1542,7 +1778,7 @@ var StorageManager = class _StorageManager {
|
|
|
1542
1778
|
async snapshotBeforeWrite(filePath, trigger) {
|
|
1543
1779
|
if (!this._versioningConfig || !this._versioningConfig.enabled) return;
|
|
1544
1780
|
try {
|
|
1545
|
-
const existing = await
|
|
1781
|
+
const existing = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
1546
1782
|
await createVersion(filePath, existing, trigger, this._versioningConfig, log, void 0, this.baseDir);
|
|
1547
1783
|
} catch {
|
|
1548
1784
|
}
|
|
@@ -1565,7 +1801,7 @@ var StorageManager = class _StorageManager {
|
|
|
1565
1801
|
if (!this._versioningConfig || !this._versioningConfig.enabled) return null;
|
|
1566
1802
|
let existing;
|
|
1567
1803
|
try {
|
|
1568
|
-
existing = await
|
|
1804
|
+
existing = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
1569
1805
|
} catch {
|
|
1570
1806
|
return null;
|
|
1571
1807
|
}
|
|
@@ -1651,6 +1887,57 @@ var StorageManager = class _StorageManager {
|
|
|
1651
1887
|
get entitiesDir() {
|
|
1652
1888
|
return path.join(this.baseDir, "entities");
|
|
1653
1889
|
}
|
|
1890
|
+
readStorageSecureFile(filePath) {
|
|
1891
|
+
return readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
1892
|
+
}
|
|
1893
|
+
writeStorageSecureFile(filePath, content) {
|
|
1894
|
+
return writeMaybeEncryptedFile(filePath, content, this.resolveWriteKey(), {}, this.baseDir);
|
|
1895
|
+
}
|
|
1896
|
+
createContentHashIndex() {
|
|
1897
|
+
return new ContentHashIndex(
|
|
1898
|
+
this.stateDir,
|
|
1899
|
+
() => this._secureStoreKey,
|
|
1900
|
+
() => this.resolveWriteKey(),
|
|
1901
|
+
this.baseDir
|
|
1902
|
+
);
|
|
1903
|
+
}
|
|
1904
|
+
async appendStorageSecureFile(filePath, content) {
|
|
1905
|
+
const previous = this.secureAppendChains.get(filePath) ?? Promise.resolve();
|
|
1906
|
+
const current = previous.catch(() => void 0).then(() => this.appendStorageSecureFileUnlocked(filePath, content));
|
|
1907
|
+
const next = current.catch(() => void 0);
|
|
1908
|
+
this.secureAppendChains.set(filePath, next);
|
|
1909
|
+
try {
|
|
1910
|
+
await current;
|
|
1911
|
+
} finally {
|
|
1912
|
+
if (this.secureAppendChains.get(filePath) === next) {
|
|
1913
|
+
this.secureAppendChains.delete(filePath);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
1918
|
+
const writeKey = this.resolveWriteKey();
|
|
1919
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
1920
|
+
if (writeKey === null) {
|
|
1921
|
+
try {
|
|
1922
|
+
if (isEncryptedFile(await readFile(filePath))) {
|
|
1923
|
+
const existing2 = await this.readStorageSecureFile(filePath);
|
|
1924
|
+
await writeMaybeEncryptedFile(filePath, `${existing2}${content}`, null, {}, this.baseDir);
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1927
|
+
} catch (err) {
|
|
1928
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
1929
|
+
}
|
|
1930
|
+
await appendFile(filePath, content, "utf-8");
|
|
1931
|
+
return;
|
|
1932
|
+
}
|
|
1933
|
+
let existing = "";
|
|
1934
|
+
try {
|
|
1935
|
+
existing = await this.readStorageSecureFile(filePath);
|
|
1936
|
+
} catch (err) {
|
|
1937
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
1938
|
+
}
|
|
1939
|
+
await writeMaybeEncryptedFile(filePath, `${existing}${content}`, writeKey, {}, this.baseDir);
|
|
1940
|
+
}
|
|
1654
1941
|
get stateDir() {
|
|
1655
1942
|
return path.join(this.baseDir, "state");
|
|
1656
1943
|
}
|
|
@@ -1665,7 +1952,7 @@ var StorageManager = class _StorageManager {
|
|
|
1665
1952
|
return this.factHashIndex;
|
|
1666
1953
|
}
|
|
1667
1954
|
if (!this.factHashIndexLoadPromise) {
|
|
1668
|
-
const index =
|
|
1955
|
+
const index = this.createContentHashIndex();
|
|
1669
1956
|
this.factHashIndexLoadPromise = index.load().then(() => {
|
|
1670
1957
|
this.factHashIndex = index;
|
|
1671
1958
|
return index;
|
|
@@ -1907,7 +2194,7 @@ ${sanitized.text}
|
|
|
1907
2194
|
filePath = path.join(this.factsDir, today, `${id}.md`);
|
|
1908
2195
|
}
|
|
1909
2196
|
await this.snapshotBeforeWrite(filePath, "write");
|
|
1910
|
-
await
|
|
2197
|
+
await writeMaybeEncryptedFile(filePath, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
1911
2198
|
this.invalidateAllMemoriesCache();
|
|
1912
2199
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.writeMemory", {
|
|
1913
2200
|
memoryId: id,
|
|
@@ -1943,6 +2230,50 @@ ${sanitized.text}
|
|
|
1943
2230
|
const sanitized = sanitizeMemoryContent(content);
|
|
1944
2231
|
return factHashIndex.has(sanitized.text);
|
|
1945
2232
|
}
|
|
2233
|
+
factContentHashForRemoval(memory) {
|
|
2234
|
+
if (memory.frontmatter.category !== "fact") return null;
|
|
2235
|
+
if (typeof memory.frontmatter.contentHash === "string" && memory.frontmatter.contentHash.length > 0) {
|
|
2236
|
+
return memory.frontmatter.contentHash;
|
|
2237
|
+
}
|
|
2238
|
+
const configuredHashSource = stripCitationMarkersForHashRemoval(memory.content, this.citationTemplate);
|
|
2239
|
+
const hashSource = configuredHashSource !== memory.content ? configuredHashSource : stripDefaultCitationMarkersWithoutRegex(memory.content);
|
|
2240
|
+
return ContentHashIndex.computeHash(sanitizeMemoryContent(hashSource).text);
|
|
2241
|
+
}
|
|
2242
|
+
async removeFactContentHashesForMemories(memories) {
|
|
2243
|
+
await this.ensureFactHashIndexAuthoritative();
|
|
2244
|
+
const factHashIndex = await this.getFactHashIndex();
|
|
2245
|
+
const removedIds = new Set(
|
|
2246
|
+
memories.map((memory) => memory.frontmatter.id).filter((id) => typeof id === "string" && id.length > 0)
|
|
2247
|
+
);
|
|
2248
|
+
const removedHashes = /* @__PURE__ */ new Map();
|
|
2249
|
+
for (const memory of memories) {
|
|
2250
|
+
const hash = this.factContentHashForRemoval(memory);
|
|
2251
|
+
if (hash) {
|
|
2252
|
+
removedHashes.set(memory, hash);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
if (removedHashes.size === 0) return;
|
|
2256
|
+
const remainingActiveHashes = /* @__PURE__ */ new Set();
|
|
2257
|
+
const remainingMemories = [
|
|
2258
|
+
...await this.readAllMemories(),
|
|
2259
|
+
...await this.readAllColdMemories()
|
|
2260
|
+
];
|
|
2261
|
+
for (const memory of remainingMemories) {
|
|
2262
|
+
if (memory.frontmatter.category !== "fact") continue;
|
|
2263
|
+
if (removedIds.has(memory.frontmatter.id)) continue;
|
|
2264
|
+
if (inferMemoryStatus(memory.frontmatter, memory.path) !== "active") continue;
|
|
2265
|
+
const hash = this.factContentHashForRemoval(memory);
|
|
2266
|
+
if (hash) {
|
|
2267
|
+
remainingActiveHashes.add(hash);
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
for (const hash of removedHashes.values()) {
|
|
2271
|
+
if (!remainingActiveHashes.has(hash)) {
|
|
2272
|
+
factHashIndex.removeByHash(hash);
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
await factHashIndex.save();
|
|
2276
|
+
}
|
|
1946
2277
|
async isFactContentHashAuthoritative() {
|
|
1947
2278
|
await this.ensureFactHashIndexAuthoritative();
|
|
1948
2279
|
return true;
|
|
@@ -1976,10 +2307,10 @@ ${sanitized.text}
|
|
|
1976
2307
|
return "";
|
|
1977
2308
|
}
|
|
1978
2309
|
const filePath = path.join(dir, `${id}.md`);
|
|
1979
|
-
await
|
|
2310
|
+
await writeMaybeEncryptedFile(filePath, `${serializeFrontmatter(fm)}
|
|
1980
2311
|
|
|
1981
2312
|
${sanitized.text}
|
|
1982
|
-
`,
|
|
2313
|
+
`, this.resolveWriteKey(), {}, this.baseDir);
|
|
1983
2314
|
const actor = typeof options.actor === "string" && options.actor.length > 0 ? options.actor : "storage.writeArtifact";
|
|
1984
2315
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.writeArtifact", {
|
|
1985
2316
|
memoryId: id,
|
|
@@ -2088,9 +2419,11 @@ ${sanitized.text}
|
|
|
2088
2419
|
aliases: []
|
|
2089
2420
|
};
|
|
2090
2421
|
try {
|
|
2091
|
-
const existing = await
|
|
2422
|
+
const existing = await this.readStorageSecureFile(filePath);
|
|
2092
2423
|
entity = parseEntityFile(existing, this.entitySchemas);
|
|
2093
|
-
} catch {
|
|
2424
|
+
} catch (err) {
|
|
2425
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
2426
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
2094
2427
|
}
|
|
2095
2428
|
const timestamp = options.timestamp?.trim() || (/* @__PURE__ */ new Date()).toISOString();
|
|
2096
2429
|
const source = options.source?.trim() || void 0;
|
|
@@ -2146,7 +2479,7 @@ ${sanitized.text}
|
|
|
2146
2479
|
entity.created = entity.created || timestamp;
|
|
2147
2480
|
entity.updated = (/* @__PURE__ */ new Date()).toISOString();
|
|
2148
2481
|
await this.snapshotBeforeWrite(filePath, "write");
|
|
2149
|
-
await
|
|
2482
|
+
await this.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.entitySchemas));
|
|
2150
2483
|
this.invalidateKnowledgeIndexCache();
|
|
2151
2484
|
this.bumpMemoryStatusVersion();
|
|
2152
2485
|
log.debug(`wrote entity ${normalized}`);
|
|
@@ -2154,15 +2487,19 @@ ${sanitized.text}
|
|
|
2154
2487
|
}
|
|
2155
2488
|
async readProfile() {
|
|
2156
2489
|
try {
|
|
2157
|
-
return await
|
|
2158
|
-
} catch {
|
|
2159
|
-
|
|
2490
|
+
return await readMaybeEncryptedFile(this.profilePath, this._secureStoreKey, this.baseDir);
|
|
2491
|
+
} catch (error) {
|
|
2492
|
+
if (error instanceof SecureStoreLockedError) {
|
|
2493
|
+
throw error;
|
|
2494
|
+
}
|
|
2495
|
+
if (isErrnoCode(error, "ENOENT")) return "";
|
|
2496
|
+
throw error;
|
|
2160
2497
|
}
|
|
2161
2498
|
}
|
|
2162
2499
|
async writeProfile(content) {
|
|
2163
2500
|
await this.ensureDirectories();
|
|
2164
2501
|
await this.snapshotBeforeWrite(this.profilePath, "consolidation");
|
|
2165
|
-
await
|
|
2502
|
+
await writeMaybeEncryptedFile(this.profilePath, content, this.resolveWriteKey(), {}, this.baseDir);
|
|
2166
2503
|
log.debug("updated profile.md");
|
|
2167
2504
|
}
|
|
2168
2505
|
/**
|
|
@@ -2245,6 +2582,24 @@ ${sanitized.text}
|
|
|
2245
2582
|
invalidateAllMemoriesCacheForDir() {
|
|
2246
2583
|
this.invalidateAllMemoriesCache();
|
|
2247
2584
|
}
|
|
2585
|
+
/** Invalidate only the cache layers affected by direct tier file deletes. */
|
|
2586
|
+
invalidateMemoryCachesForTiers(tiers) {
|
|
2587
|
+
let hotChanged = false;
|
|
2588
|
+
let coldChanged = false;
|
|
2589
|
+
for (const tier of tiers) {
|
|
2590
|
+
if (tier === "cold") {
|
|
2591
|
+
coldChanged = true;
|
|
2592
|
+
} else if (tier === "hot" || tier === "archive") {
|
|
2593
|
+
hotChanged = true;
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
if (hotChanged) {
|
|
2597
|
+
this.invalidateAllMemoriesCache();
|
|
2598
|
+
}
|
|
2599
|
+
if (coldChanged) {
|
|
2600
|
+
this.invalidateColdMemoriesCache();
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2248
2603
|
/** Clear ALL static caches. Use in tests that write files directly
|
|
2249
2604
|
* (bypassing StorageManager.writeMemory) to avoid stale reads. */
|
|
2250
2605
|
static clearAllStaticCaches() {
|
|
@@ -2336,7 +2691,7 @@ ${sanitized.text}
|
|
|
2336
2691
|
const results = await Promise.all(
|
|
2337
2692
|
batch.map(async (fullPath) => {
|
|
2338
2693
|
try {
|
|
2339
|
-
const raw = await
|
|
2694
|
+
const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);
|
|
2340
2695
|
const parsed = parseFrontmatter(raw);
|
|
2341
2696
|
if (!parsed) return null;
|
|
2342
2697
|
return {
|
|
@@ -2348,7 +2703,8 @@ ${sanitized.text}
|
|
|
2348
2703
|
),
|
|
2349
2704
|
content: parsed.content
|
|
2350
2705
|
};
|
|
2351
|
-
} catch {
|
|
2706
|
+
} catch (err) {
|
|
2707
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
2352
2708
|
return null;
|
|
2353
2709
|
}
|
|
2354
2710
|
})
|
|
@@ -2361,7 +2717,7 @@ ${sanitized.text}
|
|
|
2361
2717
|
}
|
|
2362
2718
|
async readWindowUpdatedMs(filePath) {
|
|
2363
2719
|
try {
|
|
2364
|
-
const raw = await
|
|
2720
|
+
const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
2365
2721
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
2366
2722
|
if (!match) return null;
|
|
2367
2723
|
const frontmatterBlock = match[1];
|
|
@@ -2545,7 +2901,7 @@ ${sanitized.text}
|
|
|
2545
2901
|
await readDir(fullPath);
|
|
2546
2902
|
} else if (entry.name.endsWith(".md")) {
|
|
2547
2903
|
try {
|
|
2548
|
-
const raw = await
|
|
2904
|
+
const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);
|
|
2549
2905
|
const parsed = parseFrontmatter(raw);
|
|
2550
2906
|
if (parsed) {
|
|
2551
2907
|
memories.push({
|
|
@@ -2558,7 +2914,8 @@ ${sanitized.text}
|
|
|
2558
2914
|
content: parsed.content
|
|
2559
2915
|
});
|
|
2560
2916
|
}
|
|
2561
|
-
} catch {
|
|
2917
|
+
} catch (err) {
|
|
2918
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
2562
2919
|
}
|
|
2563
2920
|
}
|
|
2564
2921
|
}
|
|
@@ -2571,7 +2928,7 @@ ${sanitized.text}
|
|
|
2571
2928
|
/** Read a single memory file by its absolute path. Returns null if unreadable. */
|
|
2572
2929
|
async readMemoryByPath(filePath) {
|
|
2573
2930
|
try {
|
|
2574
|
-
const raw = await
|
|
2931
|
+
const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
2575
2932
|
const parsed = parseFrontmatter(raw);
|
|
2576
2933
|
if (parsed) {
|
|
2577
2934
|
return {
|
|
@@ -2606,7 +2963,8 @@ ${sanitized.text}
|
|
|
2606
2963
|
};
|
|
2607
2964
|
}
|
|
2608
2965
|
return null;
|
|
2609
|
-
} catch {
|
|
2966
|
+
} catch (err) {
|
|
2967
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
2610
2968
|
return null;
|
|
2611
2969
|
}
|
|
2612
2970
|
}
|
|
@@ -2644,19 +3002,8 @@ ${sanitized.text}
|
|
|
2644
3002
|
|
|
2645
3003
|
${memory.content}
|
|
2646
3004
|
`;
|
|
2647
|
-
await
|
|
2648
|
-
|
|
2649
|
-
try {
|
|
2650
|
-
await writeFile(tempPath, fileContent, "utf-8");
|
|
2651
|
-
await rename(tempPath, targetPath);
|
|
2652
|
-
this.invalidateAllMemoriesCache();
|
|
2653
|
-
} catch (err) {
|
|
2654
|
-
try {
|
|
2655
|
-
await unlink(tempPath);
|
|
2656
|
-
} catch {
|
|
2657
|
-
}
|
|
2658
|
-
throw err;
|
|
2659
|
-
}
|
|
3005
|
+
await writeMaybeEncryptedFile(targetPath, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
3006
|
+
this.invalidateAllMemoriesCache();
|
|
2660
3007
|
}
|
|
2661
3008
|
async moveMemoryToPath(memory, targetPath) {
|
|
2662
3009
|
await this.writeMemoryFileAtomic(targetPath, memory);
|
|
@@ -2727,7 +3074,7 @@ ${memory.content}
|
|
|
2727
3074
|
${memory.content}
|
|
2728
3075
|
`;
|
|
2729
3076
|
const destPath = path.join(destDir, path.basename(memory.path));
|
|
2730
|
-
await
|
|
3077
|
+
await writeMaybeEncryptedFile(destPath, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
2731
3078
|
await unlink(memory.path);
|
|
2732
3079
|
this.invalidateAllMemoriesCache();
|
|
2733
3080
|
await this.appendGeneratedMemoryLifecycleEventFailOpen(
|
|
@@ -2763,8 +3110,10 @@ ${memory.content}
|
|
|
2763
3110
|
}
|
|
2764
3111
|
async readEntity(name) {
|
|
2765
3112
|
try {
|
|
2766
|
-
return await
|
|
2767
|
-
} catch {
|
|
3113
|
+
return await this.readStorageSecureFile(path.join(this.entitiesDir, `${name}.md`));
|
|
3114
|
+
} catch (err) {
|
|
3115
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3116
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
2768
3117
|
return "";
|
|
2769
3118
|
}
|
|
2770
3119
|
}
|
|
@@ -2848,7 +3197,7 @@ ${memory.content}
|
|
|
2848
3197
|
|
|
2849
3198
|
${sanitized.text}
|
|
2850
3199
|
`;
|
|
2851
|
-
await
|
|
3200
|
+
await writeMaybeEncryptedFile(memory.path, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
2852
3201
|
this.invalidateAllMemoriesCache();
|
|
2853
3202
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.updateMemory", {
|
|
2854
3203
|
memoryId: id,
|
|
@@ -2880,7 +3229,7 @@ ${sanitized.text}
|
|
|
2880
3229
|
|
|
2881
3230
|
${memory.content}
|
|
2882
3231
|
`;
|
|
2883
|
-
await
|
|
3232
|
+
await writeMaybeEncryptedFile(memory.path, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
2884
3233
|
this.invalidateAllMemoriesCache();
|
|
2885
3234
|
if (memory.path.includes(`${path.sep}cold${path.sep}`)) {
|
|
2886
3235
|
this.invalidateColdMemoriesCache();
|
|
@@ -2945,21 +3294,23 @@ ${memory.content}
|
|
|
2945
3294
|
async loadBuffer() {
|
|
2946
3295
|
const bufferPath = path.join(this.stateDir, "buffer.json");
|
|
2947
3296
|
try {
|
|
2948
|
-
const raw = await
|
|
3297
|
+
const raw = await this.readStorageSecureFile(bufferPath);
|
|
2949
3298
|
return JSON.parse(raw);
|
|
2950
|
-
} catch {
|
|
3299
|
+
} catch (err) {
|
|
3300
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3301
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
2951
3302
|
return { turns: [], lastExtractionAt: null, extractionCount: 0 };
|
|
2952
3303
|
}
|
|
2953
3304
|
}
|
|
2954
3305
|
async saveBuffer(state) {
|
|
2955
3306
|
await this.ensureDirectories();
|
|
2956
3307
|
const bufferPath = path.join(this.stateDir, "buffer.json");
|
|
2957
|
-
await
|
|
3308
|
+
await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));
|
|
2958
3309
|
}
|
|
2959
3310
|
async loadMeta() {
|
|
2960
3311
|
const metaPath = path.join(this.stateDir, "meta.json");
|
|
2961
3312
|
try {
|
|
2962
|
-
const raw = await
|
|
3313
|
+
const raw = await this.readStorageSecureFile(metaPath);
|
|
2963
3314
|
const parsed = JSON.parse(raw);
|
|
2964
3315
|
return {
|
|
2965
3316
|
extractionCount: typeof parsed.extractionCount === "number" ? parsed.extractionCount : 0,
|
|
@@ -2976,7 +3327,9 @@ ${memory.content}
|
|
|
2976
3327
|
observedAt: entry.observedAt
|
|
2977
3328
|
})) : []
|
|
2978
3329
|
};
|
|
2979
|
-
} catch {
|
|
3330
|
+
} catch (err) {
|
|
3331
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3332
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
2980
3333
|
return {
|
|
2981
3334
|
extractionCount: 0,
|
|
2982
3335
|
lastExtractionAt: null,
|
|
@@ -2990,7 +3343,7 @@ ${memory.content}
|
|
|
2990
3343
|
async saveMeta(state) {
|
|
2991
3344
|
await this.ensureDirectories();
|
|
2992
3345
|
const metaPath = path.join(this.stateDir, "meta.json");
|
|
2993
|
-
await
|
|
3346
|
+
await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
|
|
2994
3347
|
}
|
|
2995
3348
|
async appendMemoryActionEvents(events) {
|
|
2996
3349
|
if (events.length === 0) return 0;
|
|
@@ -3004,7 +3357,7 @@ ${memory.content}
|
|
|
3004
3357
|
return `${JSON.stringify(normalized)}
|
|
3005
3358
|
`;
|
|
3006
3359
|
}).join("");
|
|
3007
|
-
await
|
|
3360
|
+
await this.appendStorageSecureFile(this.memoryActionsPath, payload);
|
|
3008
3361
|
return events.length;
|
|
3009
3362
|
}
|
|
3010
3363
|
async appendMemoryLifecycleEvents(events) {
|
|
@@ -3019,7 +3372,7 @@ ${memory.content}
|
|
|
3019
3372
|
return `${JSON.stringify(normalized)}
|
|
3020
3373
|
`;
|
|
3021
3374
|
}).join("");
|
|
3022
|
-
await
|
|
3375
|
+
await this.appendStorageSecureFile(this.memoryLifecycleLedgerPath, payload);
|
|
3023
3376
|
return events.length;
|
|
3024
3377
|
}
|
|
3025
3378
|
/**
|
|
@@ -3044,7 +3397,7 @@ ${memory.content}
|
|
|
3044
3397
|
return `${JSON.stringify(normalized)}
|
|
3045
3398
|
`;
|
|
3046
3399
|
}).join("");
|
|
3047
|
-
await
|
|
3400
|
+
await this.appendStorageSecureFile(this.bufferSurpriseLedgerPath, payload);
|
|
3048
3401
|
return events.length;
|
|
3049
3402
|
}
|
|
3050
3403
|
/**
|
|
@@ -3081,8 +3434,9 @@ ${memory.content}
|
|
|
3081
3434
|
async readBufferSurpriseEvents(options = {}) {
|
|
3082
3435
|
let raw;
|
|
3083
3436
|
try {
|
|
3084
|
-
raw = await
|
|
3437
|
+
raw = await this.readStorageSecureFile(this.bufferSurpriseLedgerPath);
|
|
3085
3438
|
} catch (err) {
|
|
3439
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3086
3440
|
const code = err.code;
|
|
3087
3441
|
if (code === "ENOENT") return [];
|
|
3088
3442
|
throw err;
|
|
@@ -3117,7 +3471,7 @@ ${memory.content}
|
|
|
3117
3471
|
await this.ensureDirectories();
|
|
3118
3472
|
let existingKeys = /* @__PURE__ */ new Set();
|
|
3119
3473
|
try {
|
|
3120
|
-
const raw = await
|
|
3474
|
+
const raw = await this.readStorageSecureFile(this.behaviorSignalsPath);
|
|
3121
3475
|
const lines = raw.split("\n");
|
|
3122
3476
|
for (const line of lines) {
|
|
3123
3477
|
const row = line.trim();
|
|
@@ -3130,7 +3484,9 @@ ${memory.content}
|
|
|
3130
3484
|
} catch {
|
|
3131
3485
|
}
|
|
3132
3486
|
}
|
|
3133
|
-
} catch {
|
|
3487
|
+
} catch (err) {
|
|
3488
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3489
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3134
3490
|
existingKeys = /* @__PURE__ */ new Set();
|
|
3135
3491
|
}
|
|
3136
3492
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3147,7 +3503,7 @@ ${memory.content}
|
|
|
3147
3503
|
if (deduped.length === 0) return 0;
|
|
3148
3504
|
const payload = deduped.map((event) => `${JSON.stringify(event)}
|
|
3149
3505
|
`).join("");
|
|
3150
|
-
await
|
|
3506
|
+
await this.appendStorageSecureFile(this.behaviorSignalsPath, payload);
|
|
3151
3507
|
return deduped.length;
|
|
3152
3508
|
}
|
|
3153
3509
|
async appendReextractJobs(events) {
|
|
@@ -3156,9 +3512,11 @@ ${memory.content}
|
|
|
3156
3512
|
const filePath = path.join(this.stateDir, "reextract-jobs.jsonl");
|
|
3157
3513
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
3158
3514
|
try {
|
|
3159
|
-
await
|
|
3515
|
+
await this.appendStorageSecureFile(filePath, lines);
|
|
3160
3516
|
return events.length;
|
|
3161
|
-
} catch {
|
|
3517
|
+
} catch (err) {
|
|
3518
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3519
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3162
3520
|
return 0;
|
|
3163
3521
|
}
|
|
3164
3522
|
}
|
|
@@ -3166,7 +3524,7 @@ ${memory.content}
|
|
|
3166
3524
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
3167
3525
|
const filePath = path.join(this.stateDir, "reextract-jobs.jsonl");
|
|
3168
3526
|
try {
|
|
3169
|
-
const raw = await
|
|
3527
|
+
const raw = await this.readStorageSecureFile(filePath);
|
|
3170
3528
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
3171
3529
|
const parsed = [];
|
|
3172
3530
|
for (const line of lines) {
|
|
@@ -3186,7 +3544,9 @@ ${memory.content}
|
|
|
3186
3544
|
}
|
|
3187
3545
|
}
|
|
3188
3546
|
return parsed.slice(-safeLimit);
|
|
3189
|
-
} catch {
|
|
3547
|
+
} catch (err) {
|
|
3548
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3549
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3190
3550
|
return [];
|
|
3191
3551
|
}
|
|
3192
3552
|
}
|
|
@@ -3194,7 +3554,7 @@ ${memory.content}
|
|
|
3194
3554
|
const cappedLimit = Math.max(0, Math.floor(limit));
|
|
3195
3555
|
if (cappedLimit === 0) return [];
|
|
3196
3556
|
try {
|
|
3197
|
-
const raw = await
|
|
3557
|
+
const raw = await this.readStorageSecureFile(this.behaviorSignalsPath);
|
|
3198
3558
|
const out = [];
|
|
3199
3559
|
const lines = raw.split("\n");
|
|
3200
3560
|
for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {
|
|
@@ -3209,15 +3569,20 @@ ${memory.content}
|
|
|
3209
3569
|
}
|
|
3210
3570
|
}
|
|
3211
3571
|
return out.reverse();
|
|
3212
|
-
} catch {
|
|
3572
|
+
} catch (err) {
|
|
3573
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3574
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3213
3575
|
return [];
|
|
3214
3576
|
}
|
|
3215
3577
|
}
|
|
3216
3578
|
async readMemoryActionEvents(limit = 200) {
|
|
3579
|
+
return (await this.readMemoryActionEventRows(limit)).map((row) => row.event);
|
|
3580
|
+
}
|
|
3581
|
+
async readMemoryActionEventRows(limit = 200) {
|
|
3217
3582
|
const cappedLimit = Math.max(0, Math.floor(limit));
|
|
3218
3583
|
if (cappedLimit === 0) return [];
|
|
3219
3584
|
try {
|
|
3220
|
-
const raw = await
|
|
3585
|
+
const raw = await this.readStorageSecureFile(this.memoryActionsPath);
|
|
3221
3586
|
const out = [];
|
|
3222
3587
|
const lines = raw.split("\n");
|
|
3223
3588
|
for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {
|
|
@@ -3225,20 +3590,29 @@ ${memory.content}
|
|
|
3225
3590
|
if (!line) continue;
|
|
3226
3591
|
try {
|
|
3227
3592
|
const parsed = JSON.parse(line);
|
|
3228
|
-
|
|
3229
|
-
|
|
3593
|
+
const outcome = parsed.outcome === "applied" || parsed.outcome === "skipped" || parsed.outcome === "failed" ? parsed.outcome : null;
|
|
3594
|
+
if (typeof parsed.timestamp === "string" && typeof parsed.action === "string" && outcome !== null) {
|
|
3595
|
+
out.push({
|
|
3596
|
+
line: i + 1,
|
|
3597
|
+
event: {
|
|
3598
|
+
...parsed,
|
|
3599
|
+
outcome
|
|
3600
|
+
}
|
|
3601
|
+
});
|
|
3230
3602
|
}
|
|
3231
3603
|
} catch {
|
|
3232
3604
|
}
|
|
3233
3605
|
}
|
|
3234
3606
|
return out.reverse();
|
|
3235
|
-
} catch {
|
|
3607
|
+
} catch (err) {
|
|
3608
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3609
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3236
3610
|
return [];
|
|
3237
3611
|
}
|
|
3238
3612
|
}
|
|
3239
3613
|
async readAllMemoryLifecycleEvents() {
|
|
3240
3614
|
try {
|
|
3241
|
-
const raw = await
|
|
3615
|
+
const raw = await this.readStorageSecureFile(this.memoryLifecycleLedgerPath);
|
|
3242
3616
|
const out = [];
|
|
3243
3617
|
const lines = raw.split("\n");
|
|
3244
3618
|
for (const line of lines) {
|
|
@@ -3253,7 +3627,9 @@ ${memory.content}
|
|
|
3253
3627
|
}
|
|
3254
3628
|
}
|
|
3255
3629
|
return sortMemoryLifecycleEvents(out);
|
|
3256
|
-
} catch {
|
|
3630
|
+
} catch (err) {
|
|
3631
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3632
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3257
3633
|
return [];
|
|
3258
3634
|
}
|
|
3259
3635
|
}
|
|
@@ -3265,35 +3641,39 @@ ${memory.content}
|
|
|
3265
3641
|
}
|
|
3266
3642
|
async writeCompressionGuidelines(content) {
|
|
3267
3643
|
await this.ensureDirectories();
|
|
3268
|
-
await
|
|
3644
|
+
await this.writeStorageSecureFile(this.compressionGuidelinesPath, content);
|
|
3269
3645
|
}
|
|
3270
3646
|
async readCompressionGuidelines() {
|
|
3271
3647
|
try {
|
|
3272
|
-
return await
|
|
3273
|
-
} catch {
|
|
3648
|
+
return await this.readStorageSecureFile(this.compressionGuidelinesPath);
|
|
3649
|
+
} catch (err) {
|
|
3650
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3651
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3274
3652
|
return null;
|
|
3275
3653
|
}
|
|
3276
3654
|
}
|
|
3277
3655
|
async writeCompressionGuidelineDraft(content) {
|
|
3278
3656
|
await this.ensureDirectories();
|
|
3279
|
-
await
|
|
3657
|
+
await this.writeStorageSecureFile(this.compressionGuidelineDraftPath, content);
|
|
3280
3658
|
}
|
|
3281
3659
|
async readCompressionGuidelineDraft() {
|
|
3282
3660
|
try {
|
|
3283
|
-
return await
|
|
3284
|
-
} catch {
|
|
3661
|
+
return await this.readStorageSecureFile(this.compressionGuidelineDraftPath);
|
|
3662
|
+
} catch (err) {
|
|
3663
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3664
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3285
3665
|
return null;
|
|
3286
3666
|
}
|
|
3287
3667
|
}
|
|
3288
3668
|
async writeCompressionGuidelineOptimizerState(state) {
|
|
3289
3669
|
await this.ensureDirectories();
|
|
3290
|
-
await
|
|
3291
|
-
|
|
3670
|
+
await this.writeStorageSecureFile(this.compressionGuidelineStatePath, `${JSON.stringify(state, null, 2)}
|
|
3671
|
+
`);
|
|
3292
3672
|
}
|
|
3293
3673
|
async writeCompressionGuidelineDraftState(state) {
|
|
3294
3674
|
await this.ensureDirectories();
|
|
3295
|
-
await
|
|
3296
|
-
|
|
3675
|
+
await this.writeStorageSecureFile(this.compressionGuidelineDraftStatePath, `${JSON.stringify(state, null, 2)}
|
|
3676
|
+
`);
|
|
3297
3677
|
}
|
|
3298
3678
|
async readCompressionGuidelineOptimizerState() {
|
|
3299
3679
|
return this.readCompressionGuidelineStateFile(this.compressionGuidelineStatePath);
|
|
@@ -3341,7 +3721,7 @@ ${memory.content}
|
|
|
3341
3721
|
return typeof rule.action === "string" && typeof rule.delta === "number" && Number.isFinite(rule.delta) && (rule.direction === "increase" || rule.direction === "decrease" || rule.direction === "hold") && (rule.confidence === "low" || rule.confidence === "medium" || rule.confidence === "high") && Array.isArray(rule.notes) && rule.notes.every((note) => typeof note === "string");
|
|
3342
3722
|
};
|
|
3343
3723
|
try {
|
|
3344
|
-
const raw = await
|
|
3724
|
+
const raw = await this.readStorageSecureFile(filePath);
|
|
3345
3725
|
const parsed = JSON.parse(raw);
|
|
3346
3726
|
const sourceWindow = parsed?.sourceWindow;
|
|
3347
3727
|
const eventCounts = parsed?.eventCounts;
|
|
@@ -3371,18 +3751,21 @@ ${memory.content}
|
|
|
3371
3751
|
...actionSummaries ? { actionSummaries } : {},
|
|
3372
3752
|
...ruleUpdates ? { ruleUpdates } : {}
|
|
3373
3753
|
};
|
|
3374
|
-
} catch {
|
|
3754
|
+
} catch (err) {
|
|
3755
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3756
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3375
3757
|
return null;
|
|
3376
3758
|
}
|
|
3377
3759
|
}
|
|
3378
3760
|
async writeIdentityAnchor(content) {
|
|
3379
3761
|
await this.ensureDirectories();
|
|
3380
|
-
await
|
|
3762
|
+
await this.writeStorageSecureFile(this.identityAnchorPath, content);
|
|
3381
3763
|
}
|
|
3382
3764
|
async readIdentityAnchor() {
|
|
3383
3765
|
try {
|
|
3384
|
-
return await
|
|
3385
|
-
} catch {
|
|
3766
|
+
return await this.readStorageSecureFile(this.identityAnchorPath);
|
|
3767
|
+
} catch (err) {
|
|
3768
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3386
3769
|
return null;
|
|
3387
3770
|
}
|
|
3388
3771
|
}
|
|
@@ -3394,7 +3777,7 @@ ${memory.content}
|
|
|
3394
3777
|
const id = this.generateId("incident");
|
|
3395
3778
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
3396
3779
|
const filePath = path.join(this.identityIncidentsDir, `${date}-${id}.md`);
|
|
3397
|
-
await
|
|
3780
|
+
await this.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
3398
3781
|
return { ...incident, filePath };
|
|
3399
3782
|
}
|
|
3400
3783
|
async readContinuityIncidents(limit = 200, state = "all") {
|
|
@@ -3408,16 +3791,19 @@ ${memory.content}
|
|
|
3408
3791
|
if (incidents.length >= cappedLimit) break;
|
|
3409
3792
|
const filePath = path.join(this.identityIncidentsDir, file);
|
|
3410
3793
|
try {
|
|
3411
|
-
const raw = await
|
|
3794
|
+
const raw = await this.readStorageSecureFile(filePath);
|
|
3412
3795
|
const parsed = parseContinuityIncident(raw);
|
|
3413
3796
|
if (!parsed) continue;
|
|
3414
3797
|
if (state !== "all" && parsed.state !== state) continue;
|
|
3415
3798
|
incidents.push({ ...parsed, filePath });
|
|
3416
|
-
} catch {
|
|
3799
|
+
} catch (err) {
|
|
3800
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3417
3801
|
}
|
|
3418
3802
|
}
|
|
3419
3803
|
return incidents;
|
|
3420
|
-
} catch {
|
|
3804
|
+
} catch (err) {
|
|
3805
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3806
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3421
3807
|
return [];
|
|
3422
3808
|
}
|
|
3423
3809
|
}
|
|
@@ -3427,7 +3813,7 @@ ${memory.content}
|
|
|
3427
3813
|
if (!target || !directFilePath) return null;
|
|
3428
3814
|
if (target.state === "closed") return target;
|
|
3429
3815
|
const closed = closeContinuityIncidentRecord(target, closure, (/* @__PURE__ */ new Date()).toISOString());
|
|
3430
|
-
await
|
|
3816
|
+
await this.writeStorageSecureFile(directFilePath, serializeContinuityIncident(closed));
|
|
3431
3817
|
return { ...closed, filePath: directFilePath };
|
|
3432
3818
|
}
|
|
3433
3819
|
async writeIdentityAudit(period, key, content) {
|
|
@@ -3435,26 +3821,29 @@ ${memory.content}
|
|
|
3435
3821
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
3436
3822
|
const dir = period === "weekly" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;
|
|
3437
3823
|
const filePath = path.join(dir, `${safeKey}.md`);
|
|
3438
|
-
await
|
|
3824
|
+
await this.writeStorageSecureFile(filePath, content);
|
|
3439
3825
|
return filePath;
|
|
3440
3826
|
}
|
|
3441
3827
|
async readIdentityAudit(period, key) {
|
|
3442
3828
|
try {
|
|
3443
3829
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
3444
3830
|
const dir = period === "weekly" ? this.identityAuditsWeeklyDir : this.identityAuditsMonthlyDir;
|
|
3445
|
-
return await
|
|
3446
|
-
} catch {
|
|
3831
|
+
return await this.readStorageSecureFile(path.join(dir, `${safeKey}.md`));
|
|
3832
|
+
} catch (err) {
|
|
3833
|
+
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
3834
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3447
3835
|
return null;
|
|
3448
3836
|
}
|
|
3449
3837
|
}
|
|
3450
3838
|
async writeIdentityImprovementLoops(content) {
|
|
3451
3839
|
await this.ensureDirectories();
|
|
3452
|
-
await
|
|
3840
|
+
await this.writeStorageSecureFile(this.identityImprovementLoopsPath, content);
|
|
3453
3841
|
}
|
|
3454
3842
|
async readIdentityImprovementLoops() {
|
|
3455
3843
|
try {
|
|
3456
|
-
return await
|
|
3457
|
-
} catch {
|
|
3844
|
+
return await this.readStorageSecureFile(this.identityImprovementLoopsPath);
|
|
3845
|
+
} catch (err) {
|
|
3846
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3458
3847
|
return null;
|
|
3459
3848
|
}
|
|
3460
3849
|
}
|
|
@@ -3491,10 +3880,11 @@ ${memory.content}
|
|
|
3491
3880
|
}
|
|
3492
3881
|
async readContinuityIncidentFile(filePath) {
|
|
3493
3882
|
try {
|
|
3494
|
-
const raw = await
|
|
3883
|
+
const raw = await this.readStorageSecureFile(filePath);
|
|
3495
3884
|
const parsed = parseContinuityIncident(raw);
|
|
3496
3885
|
return parsed ? { ...parsed, filePath } : null;
|
|
3497
|
-
} catch {
|
|
3886
|
+
} catch (err) {
|
|
3887
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
3498
3888
|
return null;
|
|
3499
3889
|
}
|
|
3500
3890
|
}
|
|
@@ -3562,7 +3952,7 @@ ${question}
|
|
|
3562
3952
|
for (const file of files) {
|
|
3563
3953
|
if (!file.endsWith(".md")) continue;
|
|
3564
3954
|
const filePath = path.join(this.questionsDir, file);
|
|
3565
|
-
const raw = await
|
|
3955
|
+
const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
3566
3956
|
const parsed = this.parseQuestionFile(raw, filePath);
|
|
3567
3957
|
if (parsed) {
|
|
3568
3958
|
questions.push(parsed);
|
|
@@ -3693,20 +4083,22 @@ ${reflection}
|
|
|
3693
4083
|
}
|
|
3694
4084
|
async readIdentityReflections() {
|
|
3695
4085
|
try {
|
|
3696
|
-
return await
|
|
3697
|
-
} catch {
|
|
4086
|
+
return await this.readStorageSecureFile(this.identityReflectionsPath);
|
|
4087
|
+
} catch (err) {
|
|
4088
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3698
4089
|
return null;
|
|
3699
4090
|
}
|
|
3700
4091
|
}
|
|
3701
4092
|
async writeIdentityReflections(content) {
|
|
3702
4093
|
await mkdir(this.identityDir, { recursive: true });
|
|
3703
|
-
await
|
|
4094
|
+
await this.writeStorageSecureFile(this.identityReflectionsPath, content);
|
|
3704
4095
|
}
|
|
3705
4096
|
async appendIdentityReflection(reflection) {
|
|
3706
4097
|
let existing = "";
|
|
3707
4098
|
try {
|
|
3708
|
-
existing = await
|
|
3709
|
-
} catch {
|
|
4099
|
+
existing = await this.readStorageSecureFile(this.identityReflectionsPath);
|
|
4100
|
+
} catch (err) {
|
|
4101
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3710
4102
|
}
|
|
3711
4103
|
if (existing.length > _StorageManager.IDENTITY_MAX_BYTES) {
|
|
3712
4104
|
log.debug(
|
|
@@ -3731,7 +4123,7 @@ ${reflection}
|
|
|
3731
4123
|
${reflection}
|
|
3732
4124
|
`;
|
|
3733
4125
|
await mkdir(this.identityDir, { recursive: true });
|
|
3734
|
-
await
|
|
4126
|
+
await this.writeStorageSecureFile(this.identityReflectionsPath, `${existing.trimEnd()}${section}`);
|
|
3735
4127
|
log.debug(`appended namespace-local reflection to ${this.identityReflectionsPath}`);
|
|
3736
4128
|
}
|
|
3737
4129
|
// ---------------------------------------------------------------------------
|
|
@@ -3745,9 +4137,11 @@ ${reflection}
|
|
|
3745
4137
|
const filePath = path.join(this.entitiesDir, `${name}.md`);
|
|
3746
4138
|
let entity;
|
|
3747
4139
|
try {
|
|
3748
|
-
const content = await
|
|
4140
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
3749
4141
|
entity = parseEntityFile(content, this.entitySchemas);
|
|
3750
|
-
} catch {
|
|
4142
|
+
} catch (err) {
|
|
4143
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4144
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3751
4145
|
log.debug(`addEntityRelationship: entity file ${name}.md not found`);
|
|
3752
4146
|
return;
|
|
3753
4147
|
}
|
|
@@ -3757,7 +4151,7 @@ ${reflection}
|
|
|
3757
4151
|
if (exists) return;
|
|
3758
4152
|
entity.relationships.push(rel);
|
|
3759
4153
|
entity.updated = (/* @__PURE__ */ new Date()).toISOString();
|
|
3760
|
-
await
|
|
4154
|
+
await this.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.entitySchemas));
|
|
3761
4155
|
this.invalidateKnowledgeIndexCache();
|
|
3762
4156
|
}
|
|
3763
4157
|
/**
|
|
@@ -3768,9 +4162,11 @@ ${reflection}
|
|
|
3768
4162
|
const filePath = path.join(this.entitiesDir, `${name}.md`);
|
|
3769
4163
|
let entity;
|
|
3770
4164
|
try {
|
|
3771
|
-
const content = await
|
|
4165
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
3772
4166
|
entity = parseEntityFile(content, this.entitySchemas);
|
|
3773
|
-
} catch {
|
|
4167
|
+
} catch (err) {
|
|
4168
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4169
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3774
4170
|
log.debug(`addEntityActivity: entity file ${name}.md not found`);
|
|
3775
4171
|
return;
|
|
3776
4172
|
}
|
|
@@ -3779,7 +4175,7 @@ ${reflection}
|
|
|
3779
4175
|
entity.activity = entity.activity.slice(0, maxEntries);
|
|
3780
4176
|
}
|
|
3781
4177
|
entity.updated = (/* @__PURE__ */ new Date()).toISOString();
|
|
3782
|
-
await
|
|
4178
|
+
await this.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.entitySchemas));
|
|
3783
4179
|
this.invalidateKnowledgeIndexCache();
|
|
3784
4180
|
}
|
|
3785
4181
|
/**
|
|
@@ -3789,16 +4185,18 @@ ${reflection}
|
|
|
3789
4185
|
const filePath = path.join(this.entitiesDir, `${name}.md`);
|
|
3790
4186
|
let entity;
|
|
3791
4187
|
try {
|
|
3792
|
-
const content = await
|
|
4188
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
3793
4189
|
entity = parseEntityFile(content, this.entitySchemas);
|
|
3794
|
-
} catch {
|
|
4190
|
+
} catch (err) {
|
|
4191
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4192
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3795
4193
|
log.debug(`addEntityAlias: entity file ${name}.md not found`);
|
|
3796
4194
|
return;
|
|
3797
4195
|
}
|
|
3798
4196
|
if (entity.aliases.includes(alias)) return;
|
|
3799
4197
|
entity.aliases.push(alias);
|
|
3800
4198
|
entity.updated = (/* @__PURE__ */ new Date()).toISOString();
|
|
3801
|
-
await
|
|
4199
|
+
await this.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.entitySchemas));
|
|
3802
4200
|
this.invalidateKnowledgeIndexCache();
|
|
3803
4201
|
}
|
|
3804
4202
|
/**
|
|
@@ -3808,9 +4206,11 @@ ${reflection}
|
|
|
3808
4206
|
const filePath = path.join(this.entitiesDir, `${name}.md`);
|
|
3809
4207
|
let entity;
|
|
3810
4208
|
try {
|
|
3811
|
-
const content = await
|
|
4209
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
3812
4210
|
entity = parseEntityFile(content, this.entitySchemas);
|
|
3813
|
-
} catch {
|
|
4211
|
+
} catch (err) {
|
|
4212
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4213
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3814
4214
|
log.debug(`updateEntitySynthesis: entity file ${name}.md not found`);
|
|
3815
4215
|
return;
|
|
3816
4216
|
}
|
|
@@ -3827,7 +4227,7 @@ ${reflection}
|
|
|
3827
4227
|
entity.synthesisStructuredFactDigest = synthesisStructuredFactDigest;
|
|
3828
4228
|
entity.synthesisVersion = Math.max(0, entity.synthesisVersion ?? 0) + (options.incrementVersion === false ? 0 : 1);
|
|
3829
4229
|
entity.updated = entityUpdatedAt;
|
|
3830
|
-
await
|
|
4230
|
+
await this.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.entitySchemas));
|
|
3831
4231
|
await this.removeEntitySynthesisQueueEntries([
|
|
3832
4232
|
.../* @__PURE__ */ new Set([name, normalizeEntityName(entity.name, entity.type)])
|
|
3833
4233
|
]);
|
|
@@ -3842,9 +4242,11 @@ ${reflection}
|
|
|
3842
4242
|
let synthesisTimelineCount;
|
|
3843
4243
|
try {
|
|
3844
4244
|
const filePath = path.join(this.entitiesDir, `${name}.md`);
|
|
3845
|
-
const content = await
|
|
4245
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
3846
4246
|
synthesisTimelineCount = parseEntityFile(content, this.entitySchemas).timeline.length;
|
|
3847
|
-
} catch {
|
|
4247
|
+
} catch (err) {
|
|
4248
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4249
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3848
4250
|
synthesisTimelineCount = void 0;
|
|
3849
4251
|
}
|
|
3850
4252
|
await this.updateEntitySynthesis(name, summary, {
|
|
@@ -3855,10 +4257,12 @@ ${reflection}
|
|
|
3855
4257
|
}
|
|
3856
4258
|
async readEntitySynthesisQueue() {
|
|
3857
4259
|
try {
|
|
3858
|
-
const raw = await
|
|
4260
|
+
const raw = await this.readStorageSecureFile(this.entitySynthesisQueuePath);
|
|
3859
4261
|
const parsed = JSON.parse(raw);
|
|
3860
4262
|
return Array.isArray(parsed.entityNames) ? parsed.entityNames.filter((value) => typeof value === "string") : [];
|
|
3861
|
-
} catch {
|
|
4263
|
+
} catch (err) {
|
|
4264
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4265
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
3862
4266
|
return [];
|
|
3863
4267
|
}
|
|
3864
4268
|
}
|
|
@@ -3880,7 +4284,7 @@ ${reflection}
|
|
|
3880
4284
|
return compareEntityTimestamps(rightTs, leftTs);
|
|
3881
4285
|
}).map(({ entityName }) => entityName);
|
|
3882
4286
|
await mkdir(this.stateDir, { recursive: true });
|
|
3883
|
-
await
|
|
4287
|
+
await this.writeStorageSecureFile(
|
|
3884
4288
|
this.entitySynthesisQueuePath,
|
|
3885
4289
|
JSON.stringify(
|
|
3886
4290
|
{
|
|
@@ -3889,8 +4293,7 @@ ${reflection}
|
|
|
3889
4293
|
},
|
|
3890
4294
|
null,
|
|
3891
4295
|
2
|
|
3892
|
-
) + "\n"
|
|
3893
|
-
"utf-8"
|
|
4296
|
+
) + "\n"
|
|
3894
4297
|
);
|
|
3895
4298
|
return staleEntityNames;
|
|
3896
4299
|
}
|
|
@@ -3901,7 +4304,7 @@ ${reflection}
|
|
|
3901
4304
|
const removals = new Set(entityNames);
|
|
3902
4305
|
const nextQueue = queue.filter((name) => !removals.has(name));
|
|
3903
4306
|
await mkdir(this.stateDir, { recursive: true });
|
|
3904
|
-
await
|
|
4307
|
+
await this.writeStorageSecureFile(
|
|
3905
4308
|
this.entitySynthesisQueuePath,
|
|
3906
4309
|
JSON.stringify(
|
|
3907
4310
|
{
|
|
@@ -3910,8 +4313,7 @@ ${reflection}
|
|
|
3910
4313
|
},
|
|
3911
4314
|
null,
|
|
3912
4315
|
2
|
|
3913
|
-
) + "\n"
|
|
3914
|
-
"utf-8"
|
|
4316
|
+
) + "\n"
|
|
3915
4317
|
);
|
|
3916
4318
|
}
|
|
3917
4319
|
async migrateEntityFilesToCompiledTruthTimeline() {
|
|
@@ -3922,7 +4324,7 @@ ${reflection}
|
|
|
3922
4324
|
if (!raw) continue;
|
|
3923
4325
|
const serialized = serializeEntityFile(parseEntityFile(raw, this.entitySchemas), this.entitySchemas);
|
|
3924
4326
|
if (raw.trimEnd() === serialized.trimEnd()) continue;
|
|
3925
|
-
await
|
|
4327
|
+
await this.writeStorageSecureFile(path.join(this.entitiesDir, `${entityName}.md`), serialized);
|
|
3926
4328
|
migrated += 1;
|
|
3927
4329
|
}
|
|
3928
4330
|
if (migrated > 0) {
|
|
@@ -3944,7 +4346,8 @@ ${reflection}
|
|
|
3944
4346
|
async readAllEntityFiles() {
|
|
3945
4347
|
const currentVersion = this.getMemoryStatusVersion();
|
|
3946
4348
|
const schemaCacheKey = buildEntitySchemaCacheKey(this.entitySchemas);
|
|
3947
|
-
const
|
|
4349
|
+
const cacheKey = `${this.getEntityCacheSecureStoreKey()}\0${schemaCacheKey}`;
|
|
4350
|
+
const cached = getCachedEntities(this.baseDir, currentVersion, cacheKey);
|
|
3948
4351
|
if (cached) return cached;
|
|
3949
4352
|
try {
|
|
3950
4353
|
const entries = await readdir(this.entitiesDir);
|
|
@@ -3955,17 +4358,24 @@ ${reflection}
|
|
|
3955
4358
|
for (let i = 0; i < mdFiles.length; i += BATCH_SIZE) {
|
|
3956
4359
|
const batch = mdFiles.slice(i, i + BATCH_SIZE);
|
|
3957
4360
|
const results = await Promise.all(
|
|
3958
|
-
batch.map(
|
|
3959
|
-
|
|
3960
|
-
|
|
4361
|
+
batch.map(async (entry) => {
|
|
4362
|
+
try {
|
|
4363
|
+
return await this.readStorageSecureFile(path.join(this.entitiesDir, entry));
|
|
4364
|
+
} catch (err) {
|
|
4365
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4366
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
4367
|
+
return null;
|
|
4368
|
+
}
|
|
4369
|
+
})
|
|
3961
4370
|
);
|
|
3962
4371
|
for (const content of results) {
|
|
3963
4372
|
if (content !== null) entities.push(parseEntityFile(content, this.entitySchemas));
|
|
3964
4373
|
}
|
|
3965
4374
|
}
|
|
3966
|
-
setCachedEntities(this.baseDir, entities, currentVersion,
|
|
4375
|
+
setCachedEntities(this.baseDir, entities, currentVersion, cacheKey);
|
|
3967
4376
|
return entities;
|
|
3968
|
-
} catch {
|
|
4377
|
+
} catch (err) {
|
|
4378
|
+
if (err instanceof SecureStoreLockedError || !isErrnoCode(err, "ENOENT")) throw err;
|
|
3969
4379
|
return [];
|
|
3970
4380
|
}
|
|
3971
4381
|
}
|
|
@@ -4098,7 +4508,7 @@ ${rows.join("\n")}
|
|
|
4098
4508
|
for (const file of files) {
|
|
4099
4509
|
const filePath = path.join(this.entitiesDir, file);
|
|
4100
4510
|
try {
|
|
4101
|
-
const content = await
|
|
4511
|
+
const content = await this.readStorageSecureFile(filePath);
|
|
4102
4512
|
const parsed = parseEntityFile(content, this.entitySchemas);
|
|
4103
4513
|
if (!mergedEntity.type || mergedEntity.type === "other") {
|
|
4104
4514
|
mergedEntity.type = parsed.type;
|
|
@@ -4175,7 +4585,9 @@ ${rows.join("\n")}
|
|
|
4175
4585
|
title: section.title,
|
|
4176
4586
|
lines: [...section.lines]
|
|
4177
4587
|
})));
|
|
4178
|
-
} catch {
|
|
4588
|
+
} catch (err) {
|
|
4589
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4590
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
4179
4591
|
}
|
|
4180
4592
|
}
|
|
4181
4593
|
const timelineKeys = /* @__PURE__ */ new Set();
|
|
@@ -4226,7 +4638,7 @@ ${rows.join("\n")}
|
|
|
4226
4638
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
4227
4639
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
4228
4640
|
const canonicalPath = path.join(this.entitiesDir, `${canonical}.md`);
|
|
4229
|
-
await
|
|
4641
|
+
await this.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.entitySchemas));
|
|
4230
4642
|
for (const file of files) {
|
|
4231
4643
|
const filePath = path.join(this.entitiesDir, file);
|
|
4232
4644
|
if (filePath !== canonicalPath) {
|
|
@@ -4239,7 +4651,8 @@ ${rows.join("\n")}
|
|
|
4239
4651
|
}
|
|
4240
4652
|
}
|
|
4241
4653
|
}
|
|
4242
|
-
} catch {
|
|
4654
|
+
} catch (err) {
|
|
4655
|
+
if (err instanceof SecureStoreLockedError || !isErrnoCode(err, "ENOENT")) throw err;
|
|
4243
4656
|
}
|
|
4244
4657
|
return merged;
|
|
4245
4658
|
}
|
|
@@ -4293,7 +4706,7 @@ ${rows.join("\n")}
|
|
|
4293
4706
|
${memory.content}
|
|
4294
4707
|
`;
|
|
4295
4708
|
try {
|
|
4296
|
-
await
|
|
4709
|
+
await this.writeStorageSecureFile(memory.path, fileContent);
|
|
4297
4710
|
updated++;
|
|
4298
4711
|
} catch (err) {
|
|
4299
4712
|
log.debug(`failed to update access tracking for ${entry.memoryId}: ${err}`);
|
|
@@ -4434,7 +4847,7 @@ ${sanitized.text}
|
|
|
4434
4847
|
} else {
|
|
4435
4848
|
filePath = path.join(this.factsDir, today, `${id}.md`);
|
|
4436
4849
|
}
|
|
4437
|
-
await
|
|
4850
|
+
await this.writeStorageSecureFile(filePath, fileContent);
|
|
4438
4851
|
log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);
|
|
4439
4852
|
return id;
|
|
4440
4853
|
}
|
|
@@ -4470,7 +4883,7 @@ ${sanitized.text}
|
|
|
4470
4883
|
${oldMemory.content}
|
|
4471
4884
|
`;
|
|
4472
4885
|
try {
|
|
4473
|
-
await
|
|
4886
|
+
await writeMaybeEncryptedFile(oldMemory.path, fileContent, this.resolveWriteKey(), {}, this.baseDir);
|
|
4474
4887
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.supersedeMemory", {
|
|
4475
4888
|
memoryId: oldMemoryId,
|
|
4476
4889
|
eventType: "superseded",
|
|
@@ -4509,7 +4922,7 @@ Reason: ${reason}`, {
|
|
|
4509
4922
|
async writeSummary(summary) {
|
|
4510
4923
|
await mkdir(this.summariesDir, { recursive: true });
|
|
4511
4924
|
const filePath = path.join(this.summariesDir, `${summary.id}.json`);
|
|
4512
|
-
await
|
|
4925
|
+
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
4513
4926
|
log.debug(`wrote summary ${summary.id}`);
|
|
4514
4927
|
}
|
|
4515
4928
|
/**
|
|
@@ -4522,11 +4935,13 @@ Reason: ${reason}`, {
|
|
|
4522
4935
|
for (const file of files) {
|
|
4523
4936
|
if (!file.endsWith(".json")) continue;
|
|
4524
4937
|
const filePath = path.join(this.summariesDir, file);
|
|
4525
|
-
const raw = await
|
|
4938
|
+
const raw = await this.readStorageSecureFile(filePath);
|
|
4526
4939
|
summaries.push(JSON.parse(raw));
|
|
4527
4940
|
}
|
|
4528
4941
|
return summaries;
|
|
4529
|
-
} catch {
|
|
4942
|
+
} catch (err) {
|
|
4943
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
4944
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
4530
4945
|
return [];
|
|
4531
4946
|
}
|
|
4532
4947
|
}
|
|
@@ -4552,7 +4967,7 @@ Reason: ${reason}`, {
|
|
|
4552
4967
|
${memory.content}
|
|
4553
4968
|
`;
|
|
4554
4969
|
try {
|
|
4555
|
-
await
|
|
4970
|
+
await this.writeStorageSecureFile(memory.path, fileContent);
|
|
4556
4971
|
await this.appendGeneratedMemoryLifecycleEventFailOpen("storage.archiveMemories", {
|
|
4557
4972
|
memoryId: id,
|
|
4558
4973
|
eventType: "archived",
|
|
@@ -4582,7 +4997,7 @@ ${memory.content}
|
|
|
4582
4997
|
async saveTopics(topics) {
|
|
4583
4998
|
const metaPath = path.join(this.stateDir, "topics.json");
|
|
4584
4999
|
await mkdir(this.stateDir, { recursive: true });
|
|
4585
|
-
await
|
|
5000
|
+
await this.writeStorageSecureFile(metaPath, JSON.stringify({ topics, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
4586
5001
|
log.debug(`saved ${topics.length} topic scores`);
|
|
4587
5002
|
}
|
|
4588
5003
|
/**
|
|
@@ -4591,9 +5006,11 @@ ${memory.content}
|
|
|
4591
5006
|
async loadTopics() {
|
|
4592
5007
|
const metaPath = path.join(this.stateDir, "topics.json");
|
|
4593
5008
|
try {
|
|
4594
|
-
const raw = await
|
|
5009
|
+
const raw = await this.readStorageSecureFile(metaPath);
|
|
4595
5010
|
return JSON.parse(raw);
|
|
4596
|
-
} catch {
|
|
5011
|
+
} catch (err) {
|
|
5012
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
5013
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
4597
5014
|
return { topics: [], updatedAt: null };
|
|
4598
5015
|
}
|
|
4599
5016
|
}
|
|
@@ -4675,4 +5092,4 @@ export {
|
|
|
4675
5092
|
serializeEntityFile,
|
|
4676
5093
|
StorageManager
|
|
4677
5094
|
};
|
|
4678
|
-
//# sourceMappingURL=chunk-
|
|
5095
|
+
//# sourceMappingURL=chunk-DCE6SQLA.js.map
|