@remnic/core 9.49.0 → 9.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstraction-nodes.d.ts +12 -1
- package/dist/abstraction-nodes.js +9 -2
- package/dist/access-admin-ops-surface.d.ts +10 -10
- package/dist/access-admin-ops-surface.js +48 -48
- package/dist/access-authorization-probe.d.ts +10 -10
- package/dist/access-authorization-probe.js +49 -49
- package/dist/access-boundary.d.ts +10 -10
- package/dist/access-boundary.js +48 -48
- package/dist/access-cli.js +132 -127
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +10 -10
- package/dist/access-extraction-force-flush.js +48 -48
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +10 -10
- package/dist/access-http-lifecycle-flush.d.ts +10 -10
- package/dist/access-http-offline-stream.d.ts +10 -10
- package/dist/access-http-query.js +48 -48
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +60 -60
- package/dist/access-identity-continuity-surface.d.ts +8 -8
- package/dist/access-identity-continuity-surface.js +48 -48
- package/dist/access-lcm-surface.d.ts +10 -10
- package/dist/access-lcm-surface.js +48 -48
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +55 -55
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight--H6HwN85.d.ts → access-namespace-preflight-DuDU301-.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +48 -48
- package/dist/access-observe-write-surface.d.ts +10 -10
- package/dist/access-observe-write-surface.js +48 -48
- package/dist/access-offline-manifest.d.ts +8 -8
- package/dist/access-offline-manifest.js +3 -3
- package/dist/access-operations-batch.js +51 -51
- package/dist/access-operations.d.ts +13 -13
- package/dist/access-operations.js +54 -54
- package/dist/access-recall-concurrency.d.ts +10 -10
- package/dist/access-recall-concurrency.js +48 -48
- package/dist/access-recall-response.d.ts +10 -10
- package/dist/access-recall-response.js +48 -48
- package/dist/access-recall-surface.d.ts +10 -10
- package/dist/access-recall-surface.js +48 -48
- package/dist/access-schema.d.ts +105 -105
- package/dist/access-schema.js +4 -4
- package/dist/{access-service-DvXOzCrM.d.ts → access-service--_3T_v23.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +10 -10
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +48 -48
- package/dist/access-surface-catalog.d.ts +10 -10
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +3 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-7O6RP2RT.js → auto-sync-QFQGOEO2.js} +4 -4
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +8 -8
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +12 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +4 -4
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{capsule-merge-6GFHWECG.js → capsule-merge-KXTRZ23Z.js} +4 -4
- package/dist/{catalog-Iwbk9h5E.d.ts → catalog-DjUmUIal.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +3 -3
- package/dist/causal-chain.js +3 -3
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +16 -16
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.d.ts +51 -2
- package/dist/causal-trajectory.js +8 -2
- package/dist/{chunk-EY64JLOM.js → chunk-24BKGKGO.js} +30 -19
- package/dist/chunk-24BKGKGO.js.map +1 -0
- package/dist/{chunk-ICP53SKG.js → chunk-2HIJHXB3.js} +2 -2
- package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-LZGCJSQR.js → chunk-3LD4N2TF.js} +151 -37
- package/dist/chunk-3LD4N2TF.js.map +1 -0
- package/dist/{chunk-5JRC6BYS.js → chunk-47J4EDGR.js} +11 -11
- package/dist/{chunk-2VHLLPTX.js → chunk-4EABKPZS.js} +4 -4
- package/dist/{chunk-RJV6Q2FT.js → chunk-4JWJMRPJ.js} +2 -2
- package/dist/{chunk-MXPB6PJQ.js → chunk-4S3ECH3U.js} +2 -2
- package/dist/{chunk-CGASUJVP.js → chunk-5V6IXHPI.js} +4 -4
- package/dist/{chunk-R5IGA2NH.js → chunk-5XCN4XBU.js} +4 -4
- package/dist/{chunk-2RPJ4NEE.js → chunk-64BHFFKZ.js} +2 -2
- package/dist/{chunk-FQC3DHH2.js → chunk-66SE3BNH.js} +2 -2
- package/dist/{chunk-TERNBNJB.js → chunk-6FC3IZ26.js} +2 -2
- package/dist/{chunk-K7VKAHFE.js → chunk-6XGEBQ3R.js} +4 -4
- package/dist/{chunk-JFLOOTXU.js → chunk-7BLWBSRL.js} +3 -3
- package/dist/{chunk-ABR2HEJO.js → chunk-7NDM2PNK.js} +3 -3
- package/dist/{chunk-JXZ7NLYH.js → chunk-7VWZ4LRW.js} +2 -2
- package/dist/{chunk-RN53QBM4.js → chunk-A4QMKFFO.js} +5 -1
- package/dist/chunk-A4QMKFFO.js.map +1 -0
- package/dist/chunk-ACPCA4NO.js +321 -0
- package/dist/chunk-ACPCA4NO.js.map +1 -0
- package/dist/chunk-AMTEYNYK.js +72 -0
- package/dist/chunk-AMTEYNYK.js.map +1 -0
- package/dist/{chunk-R6YJI3HE.js → chunk-AW4QUFQF.js} +1 -1
- package/dist/{chunk-P65YJEEL.js → chunk-AXFWMRKI.js} +2 -2
- package/dist/{chunk-WG5HSQ4P.js → chunk-BAKXNQ3C.js} +2 -2
- package/dist/{chunk-NM2WP3B7.js → chunk-BJYET5TX.js} +2 -2
- package/dist/{chunk-HLKPRWF4.js → chunk-DATDLJAO.js} +6 -6
- package/dist/chunk-DJUKBGAD.js +260 -0
- package/dist/chunk-DJUKBGAD.js.map +1 -0
- package/dist/{chunk-DX3XRGLH.js → chunk-DQTCGVFK.js} +2 -2
- package/dist/{chunk-IPBNC77A.js → chunk-E633OXMH.js} +11 -11
- package/dist/{chunk-J7T4MX7P.js → chunk-EEAMSNSG.js} +12 -1
- package/dist/chunk-EEAMSNSG.js.map +1 -0
- package/dist/{chunk-Z5UC3OKB.js → chunk-ELQCS47S.js} +7 -7
- package/dist/{chunk-FMXJ555A.js → chunk-EURCX6PS.js} +2 -2
- package/dist/{chunk-MZZR3J6M.js → chunk-FV7YQTN3.js} +2 -2
- package/dist/chunk-G73MCJKL.js +20 -0
- package/dist/chunk-G73MCJKL.js.map +1 -0
- package/dist/{chunk-3R6D33UF.js → chunk-GGBSF2X7.js} +2 -2
- package/dist/{chunk-SYUBB3WM.js → chunk-GKEYXXKX.js} +2 -2
- package/dist/{chunk-5AGR7SAI.js → chunk-GSEPRIZC.js} +3 -3
- package/dist/{chunk-UTVZKHJK.js → chunk-GUKBW4HL.js} +2 -2
- package/dist/chunk-GXSOUIA4.js +293 -0
- package/dist/chunk-GXSOUIA4.js.map +1 -0
- package/dist/{chunk-2F6NP3NT.js → chunk-HDQUQBPW.js} +2 -2
- package/dist/{chunk-6HMYUWXR.js → chunk-HTP6XRUI.js} +2 -2
- package/dist/{chunk-UYUYZ4WY.js → chunk-IARXXZU4.js} +2 -2
- package/dist/{chunk-MNB5RMAY.js → chunk-IIFFC3RL.js} +2 -2
- package/dist/{chunk-VDX2J7OX.js → chunk-IPLYGWQF.js} +6 -6
- package/dist/{chunk-NZBZ7IS2.js → chunk-JDCQK3C5.js} +2 -2
- package/dist/{chunk-C3KVFJH5.js → chunk-JI62YGPI.js} +2 -2
- package/dist/{chunk-LULR4IUW.js → chunk-KATEWTQJ.js} +2 -2
- package/dist/{chunk-BMCHFWGX.js → chunk-KMWYZTIE.js} +2 -2
- package/dist/{chunk-JGSKJHF7.js → chunk-KQS72GCR.js} +2 -2
- package/dist/{chunk-3S63QIFQ.js → chunk-LAQ33B5D.js} +1 -1
- package/dist/chunk-LAQ33B5D.js.map +1 -0
- package/dist/chunk-LNTUXKBT.js +224 -0
- package/dist/chunk-LNTUXKBT.js.map +1 -0
- package/dist/{chunk-2RIWJUSQ.js → chunk-LQKXVQZR.js} +12 -12
- package/dist/{chunk-LQL7ARIC.js → chunk-LTOAJXZB.js} +4 -4
- package/dist/{chunk-QKD65RGL.js → chunk-LYMNZZIM.js} +2 -2
- package/dist/{chunk-W4FBGYGK.js → chunk-M4MP34AQ.js} +189 -5
- package/dist/chunk-M4MP34AQ.js.map +1 -0
- package/dist/{chunk-3PY7VHV7.js → chunk-MCA2X4WH.js} +2 -2
- package/dist/{chunk-S5NZBKKQ.js → chunk-N3CXAYPJ.js} +3 -3
- package/dist/{chunk-WQIHRA5F.js → chunk-N3LL5NEU.js} +2 -2
- package/dist/{chunk-Z4U6U3M3.js → chunk-NKL25FCF.js} +2 -2
- package/dist/{chunk-LMDRGRJ2.js → chunk-NOB2T2FC.js} +2 -2
- package/dist/{chunk-P2OTGMTR.js → chunk-NSGU76YO.js} +2 -2
- package/dist/{chunk-L6DCVUCA.js → chunk-O76MWTVS.js} +2 -2
- package/dist/{chunk-WZFAPHIK.js → chunk-OIOZ6MOP.js} +3 -3
- package/dist/{chunk-DNHVPZOD.js → chunk-P26YHAQH.js} +201 -1
- package/dist/chunk-P26YHAQH.js.map +1 -0
- package/dist/{chunk-UMOO7IY7.js → chunk-P2KBDJJ6.js} +2 -2
- package/dist/{chunk-KVJRXN2E.js → chunk-P4QOYG52.js} +125 -13
- package/dist/chunk-P4QOYG52.js.map +1 -0
- package/dist/chunk-P77QX3ID.js +332 -0
- package/dist/chunk-P77QX3ID.js.map +1 -0
- package/dist/{chunk-SXWHN7GC.js → chunk-PDEKQWDV.js} +2 -2
- package/dist/{chunk-ENEA47UC.js → chunk-PLCHU56K.js} +3 -3
- package/dist/{chunk-IXPKESVP.js → chunk-PWIMF7LP.js} +37 -37
- package/dist/{chunk-RHTO4HTL.js → chunk-PWLB4TRK.js} +2 -2
- package/dist/{chunk-RVYVMQK4.js → chunk-QSYL5CXK.js} +3 -3
- package/dist/{chunk-B6KGGRUL.js → chunk-QWLW3VQH.js} +2 -2
- package/dist/{chunk-YQIVWS7Y.js → chunk-RBPH3GZV.js} +405 -101
- package/dist/chunk-RBPH3GZV.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-QCECHYZL.js → chunk-RVO6TCTU.js} +6 -6
- package/dist/{chunk-SHDZNSK4.js → chunk-S2SJEOTM.js} +2 -2
- package/dist/{chunk-ULWHRQEQ.js → chunk-S75UQ3T3.js} +3 -3
- package/dist/{chunk-LXOM6IQU.js → chunk-SEF4IOFE.js} +2 -2
- package/dist/{chunk-I3YHVVT4.js → chunk-SHYIMIX5.js} +2 -2
- package/dist/{chunk-IZANPXMV.js → chunk-T35UJI5R.js} +86 -82
- package/dist/chunk-T35UJI5R.js.map +1 -0
- package/dist/{chunk-G5OB4XZX.js → chunk-VANZKHTN.js} +4 -4
- package/dist/{chunk-I4TQST3L.js → chunk-VFS3MK5F.js} +2 -2
- package/dist/chunk-VUDMT5CP.js +86 -0
- package/dist/chunk-VUDMT5CP.js.map +1 -0
- package/dist/{chunk-CMQZNEIF.js → chunk-WFLBP5GC.js} +8 -1
- package/dist/chunk-WFLBP5GC.js.map +1 -0
- package/dist/{chunk-SMPVHGHG.js → chunk-WPZX7MEA.js} +3 -3
- package/dist/{chunk-ZRWB5D4H.js → chunk-WT6UL3UA.js} +2 -2
- package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-JHMAYABJ.js → chunk-XL3TATMJ.js} +4 -4
- package/dist/{chunk-MC6XO7T4.js → chunk-YLBE6PLR.js} +2 -2
- package/dist/{chunk-OLX2HJFW.js → chunk-YLHM5BQQ.js} +4 -4
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-GF22HWS2.js → chunk-Z54EM5YZ.js} +4 -4
- package/dist/{chunk-GVX3NAUU.js → chunk-ZDAYWJV6.js} +2 -2
- package/dist/{chunk-EYAIZBLM.js → chunk-ZJIFYUJI.js} +5 -5
- package/dist/{chunk-CNQQMB67.js → chunk-ZN4EYMKJ.js} +2 -2
- package/dist/{cli-PyAUaozE.d.ts → cli-BLNmNEMT.d.ts} +16 -14
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +96 -94
- package/dist/coding/pre-action-gate.d.ts +66 -0
- package/dist/coding/pre-action-gate.js +22 -0
- package/dist/commitment-ledger.js +2 -2
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +13 -13
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +3 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +12 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +12 -12
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +3 -3
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +15 -15
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +23 -23
- package/dist/cue-anchors.d.ts +19 -1
- package/dist/cue-anchors.js +10 -2
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +10 -0
- package/dist/dependency-propagation-config.js +10 -0
- package/dist/dependency-propagation-config.js.map +1 -0
- package/dist/deterministic-order.d.ts +4 -0
- package/dist/deterministic-order.js +10 -0
- package/dist/deterministic-order.js.map +1 -0
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +12 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/evals.js +2 -2
- package/dist/explicit-capture.d.ts +8 -8
- package/dist/explicit-capture.js +6 -6
- package/dist/external-wiki-access.d.ts +10 -10
- package/dist/external-wiki-access.js +49 -49
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +10 -10
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +14 -0
- package/dist/extraction-normalization.js +22 -0
- package/dist/extraction-normalization.js.map +1 -0
- package/dist/extraction-prompt.d.ts +4 -3
- package/dist/extraction-prompt.js +3 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +18 -1
- package/dist/extraction.js +21 -19
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-ZSHEFEI3.js → first-start-migration-626C5554.js} +5 -5
- package/dist/{forget-DNAJ66ZD.js → forget-GJ42LCBW.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-construction.d.ts +43 -0
- package/dist/harmonic-construction.js +26 -0
- package/dist/harmonic-construction.js.map +1 -0
- package/dist/harmonic-retrieval.d.ts +1 -0
- package/dist/harmonic-retrieval.js +10 -4
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +698 -696
- package/dist/index.js +207 -161
- package/dist/intent.d.ts +1 -1
- package/dist/json-store.d.ts +15 -1
- package/dist/json-store.js +11 -3
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +4 -4
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/archive-observations.js +2 -2
- package/dist/maintenance/atomic-file.d.ts +5 -0
- package/dist/maintenance/atomic-file.js +12 -0
- package/dist/maintenance/atomic-file.js.map +1 -0
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +12 -12
- package/dist/maintenance/migrate-observations.js +3 -3
- package/dist/maintenance/observation-ledger-utils.d.ts +1 -1
- package/dist/maintenance/observation-ledger-utils.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -13
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +14 -14
- package/dist/maintenance/rebuild-observations.js +3 -3
- package/dist/{maintenance-j7sfNQdK.d.ts → maintenance-DKbKZi3u.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +10 -10
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +22 -22
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +12 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/objective-state-writers.js +3 -3
- package/dist/objective-state.js +2 -2
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +2 -2
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +24 -24
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +33 -32
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +18 -18
- package/dist/{orchestrator-Haa9xVPV.d.ts → orchestrator-BRwD7ceU.d.ts} +7 -7
- package/dist/orchestrator.d.ts +8 -8
- package/dist/orchestrator.js +132 -127
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-1h2GpiHP.d.ts → pipeline-DC-1C9T8.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-UdwoF71D.d.ts → qmd-DdeCEZdb.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-state.js +2 -2
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/relevance.js +2 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/{resolution-3K27T4VO.js → resolution-MDPNOEG6.js} +4 -4
- package/dist/resolution-MDPNOEG6.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +8 -7
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/salvage-envelope.js +3 -3
- package/dist/schemas.d.ts +213 -116
- package/dist/schemas.js +1 -1
- package/dist/{scope-profiles-APjhSe-w.d.ts → scope-profiles-BXVq4Jv0.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +13 -13
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-CrySDbk3.d.ts → semantic-consolidation-CGYxfa8F.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +13 -13
- package/dist/semantic-rule-promotion.js +12 -12
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +12 -12
- package/dist/{service-Da_BI4S8.d.ts → service-CBDBQFCN.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +11 -11
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +16 -16
- package/dist/{storage-D1apCiCS.d.ts → storage-V--MQi7w.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +11 -11
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +13 -2
- package/dist/temporal-supersession.js +1 -1
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-OPTSBNRH.js → tier-stats-2JCZYEF7.js} +5 -5
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +3 -3
- package/dist/transfer/capsule-import.js +5 -5
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/trust-zones.js +2 -2
- package/dist/{types-D_Au9qJO.d.ts → types-D_a6Sqjz.d.ts} +25 -8
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-learner.js +3 -3
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/utility-runtime.js +4 -4
- package/dist/utility-telemetry.js +2 -2
- package/dist/verified-recall.js +12 -12
- package/dist/work-product-ledger.js +2 -2
- package/dist/write-envelope.d.ts +1 -1
- package/dist/write-envelope.js +2 -2
- package/package.json +32 -2
- package/src/abstraction-nodes.ts +182 -4
- package/src/causal-trajectory.ts +258 -3
- package/src/cli/harmonic-search.ts +23 -0
- package/src/cli/research-status-commands.ts +2 -1
- package/src/cli.ts +1 -24
- package/src/coding/pre-action-gate.test.ts +516 -0
- package/src/coding/pre-action-gate.ts +320 -0
- package/src/config.test.ts +85 -0
- package/src/config.ts +2 -0
- package/src/cue-anchors.test.ts +90 -0
- package/src/cue-anchors.ts +264 -11
- package/src/dependency-frontmatter.test.ts +83 -0
- package/src/dependency-propagation-config.ts +94 -0
- package/src/deterministic-order.ts +14 -0
- package/src/extraction-normalization.ts +71 -0
- package/src/extraction-prompt.ts +45 -11
- package/src/extraction.ts +48 -32
- package/src/faithfulness-graph-guard.test.ts +27 -0
- package/src/harmonic-construction.test.ts +1799 -0
- package/src/harmonic-construction.ts +367 -0
- package/src/harmonic-retrieval.ts +166 -25
- package/src/index.ts +4 -5
- package/src/json-store.ts +354 -12
- package/src/orchestration/consolidation-run.ts +192 -0
- package/src/orchestration/contradiction-linking-coordinator.ts +35 -1
- package/src/orchestration/dependency-propagation-triggers.test.ts +286 -0
- package/src/orchestration/dependency-propagation.test.ts +487 -0
- package/src/orchestration/dependency-propagation.ts +263 -0
- package/src/orchestration/dependency-revalidation.ts +173 -0
- package/src/orchestration/extraction-persist-deps.ts +93 -0
- package/src/orchestration/extraction-persist.ts +101 -94
- package/src/orchestration/harmonic-construction-persist.ts +86 -0
- package/src/orchestration/recall-internal.ts +1 -0
- package/src/orchestrator.ts +2 -1
- package/src/schemas.ts +15 -0
- package/src/storage.ts +14 -0
- package/src/temporal-supersession.ts +29 -1
- package/src/testing/orchestrator-lite.ts +27 -8
- package/src/testing/subjects/extraction-lifecycle.test.ts +91 -50
- package/src/types.ts +22 -7
- package/dist/chunk-3S63QIFQ.js.map +0 -1
- package/dist/chunk-CMQZNEIF.js.map +0 -1
- package/dist/chunk-DNHVPZOD.js.map +0 -1
- package/dist/chunk-EY64JLOM.js.map +0 -1
- package/dist/chunk-FZZ2QTJI.js +0 -111
- package/dist/chunk-FZZ2QTJI.js.map +0 -1
- package/dist/chunk-IZANPXMV.js.map +0 -1
- package/dist/chunk-J7T4MX7P.js.map +0 -1
- package/dist/chunk-KVJRXN2E.js.map +0 -1
- package/dist/chunk-LPSF4OQH.js +0 -47
- package/dist/chunk-LPSF4OQH.js.map +0 -1
- package/dist/chunk-LZGCJSQR.js.map +0 -1
- package/dist/chunk-OADWQ5CR.js +0 -115
- package/dist/chunk-OADWQ5CR.js.map +0 -1
- package/dist/chunk-RN53QBM4.js.map +0 -1
- package/dist/chunk-W4FBGYGK.js.map +0 -1
- package/dist/chunk-YQIVWS7Y.js.map +0 -1
- /package/dist/{auto-sync-7O6RP2RT.js.map → auto-sync-QFQGOEO2.js.map} +0 -0
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{capsule-merge-6GFHWECG.js.map → capsule-merge-KXTRZ23Z.js.map} +0 -0
- /package/dist/{chunk-ICP53SKG.js.map → chunk-2HIJHXB3.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-5JRC6BYS.js.map → chunk-47J4EDGR.js.map} +0 -0
- /package/dist/{chunk-2VHLLPTX.js.map → chunk-4EABKPZS.js.map} +0 -0
- /package/dist/{chunk-RJV6Q2FT.js.map → chunk-4JWJMRPJ.js.map} +0 -0
- /package/dist/{chunk-MXPB6PJQ.js.map → chunk-4S3ECH3U.js.map} +0 -0
- /package/dist/{chunk-CGASUJVP.js.map → chunk-5V6IXHPI.js.map} +0 -0
- /package/dist/{chunk-R5IGA2NH.js.map → chunk-5XCN4XBU.js.map} +0 -0
- /package/dist/{chunk-2RPJ4NEE.js.map → chunk-64BHFFKZ.js.map} +0 -0
- /package/dist/{chunk-FQC3DHH2.js.map → chunk-66SE3BNH.js.map} +0 -0
- /package/dist/{chunk-TERNBNJB.js.map → chunk-6FC3IZ26.js.map} +0 -0
- /package/dist/{chunk-K7VKAHFE.js.map → chunk-6XGEBQ3R.js.map} +0 -0
- /package/dist/{chunk-JFLOOTXU.js.map → chunk-7BLWBSRL.js.map} +0 -0
- /package/dist/{chunk-ABR2HEJO.js.map → chunk-7NDM2PNK.js.map} +0 -0
- /package/dist/{chunk-JXZ7NLYH.js.map → chunk-7VWZ4LRW.js.map} +0 -0
- /package/dist/{chunk-R6YJI3HE.js.map → chunk-AW4QUFQF.js.map} +0 -0
- /package/dist/{chunk-P65YJEEL.js.map → chunk-AXFWMRKI.js.map} +0 -0
- /package/dist/{chunk-WG5HSQ4P.js.map → chunk-BAKXNQ3C.js.map} +0 -0
- /package/dist/{chunk-NM2WP3B7.js.map → chunk-BJYET5TX.js.map} +0 -0
- /package/dist/{chunk-HLKPRWF4.js.map → chunk-DATDLJAO.js.map} +0 -0
- /package/dist/{chunk-DX3XRGLH.js.map → chunk-DQTCGVFK.js.map} +0 -0
- /package/dist/{chunk-IPBNC77A.js.map → chunk-E633OXMH.js.map} +0 -0
- /package/dist/{chunk-Z5UC3OKB.js.map → chunk-ELQCS47S.js.map} +0 -0
- /package/dist/{chunk-FMXJ555A.js.map → chunk-EURCX6PS.js.map} +0 -0
- /package/dist/{chunk-MZZR3J6M.js.map → chunk-FV7YQTN3.js.map} +0 -0
- /package/dist/{chunk-3R6D33UF.js.map → chunk-GGBSF2X7.js.map} +0 -0
- /package/dist/{chunk-SYUBB3WM.js.map → chunk-GKEYXXKX.js.map} +0 -0
- /package/dist/{chunk-5AGR7SAI.js.map → chunk-GSEPRIZC.js.map} +0 -0
- /package/dist/{chunk-UTVZKHJK.js.map → chunk-GUKBW4HL.js.map} +0 -0
- /package/dist/{chunk-2F6NP3NT.js.map → chunk-HDQUQBPW.js.map} +0 -0
- /package/dist/{chunk-6HMYUWXR.js.map → chunk-HTP6XRUI.js.map} +0 -0
- /package/dist/{chunk-UYUYZ4WY.js.map → chunk-IARXXZU4.js.map} +0 -0
- /package/dist/{chunk-MNB5RMAY.js.map → chunk-IIFFC3RL.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-IPLYGWQF.js.map} +0 -0
- /package/dist/{chunk-NZBZ7IS2.js.map → chunk-JDCQK3C5.js.map} +0 -0
- /package/dist/{chunk-C3KVFJH5.js.map → chunk-JI62YGPI.js.map} +0 -0
- /package/dist/{chunk-LULR4IUW.js.map → chunk-KATEWTQJ.js.map} +0 -0
- /package/dist/{chunk-BMCHFWGX.js.map → chunk-KMWYZTIE.js.map} +0 -0
- /package/dist/{chunk-JGSKJHF7.js.map → chunk-KQS72GCR.js.map} +0 -0
- /package/dist/{chunk-2RIWJUSQ.js.map → chunk-LQKXVQZR.js.map} +0 -0
- /package/dist/{chunk-LQL7ARIC.js.map → chunk-LTOAJXZB.js.map} +0 -0
- /package/dist/{chunk-QKD65RGL.js.map → chunk-LYMNZZIM.js.map} +0 -0
- /package/dist/{chunk-3PY7VHV7.js.map → chunk-MCA2X4WH.js.map} +0 -0
- /package/dist/{chunk-S5NZBKKQ.js.map → chunk-N3CXAYPJ.js.map} +0 -0
- /package/dist/{chunk-WQIHRA5F.js.map → chunk-N3LL5NEU.js.map} +0 -0
- /package/dist/{chunk-Z4U6U3M3.js.map → chunk-NKL25FCF.js.map} +0 -0
- /package/dist/{chunk-LMDRGRJ2.js.map → chunk-NOB2T2FC.js.map} +0 -0
- /package/dist/{chunk-P2OTGMTR.js.map → chunk-NSGU76YO.js.map} +0 -0
- /package/dist/{chunk-L6DCVUCA.js.map → chunk-O76MWTVS.js.map} +0 -0
- /package/dist/{chunk-WZFAPHIK.js.map → chunk-OIOZ6MOP.js.map} +0 -0
- /package/dist/{chunk-UMOO7IY7.js.map → chunk-P2KBDJJ6.js.map} +0 -0
- /package/dist/{chunk-SXWHN7GC.js.map → chunk-PDEKQWDV.js.map} +0 -0
- /package/dist/{chunk-ENEA47UC.js.map → chunk-PLCHU56K.js.map} +0 -0
- /package/dist/{chunk-IXPKESVP.js.map → chunk-PWIMF7LP.js.map} +0 -0
- /package/dist/{chunk-RHTO4HTL.js.map → chunk-PWLB4TRK.js.map} +0 -0
- /package/dist/{chunk-RVYVMQK4.js.map → chunk-QSYL5CXK.js.map} +0 -0
- /package/dist/{chunk-B6KGGRUL.js.map → chunk-QWLW3VQH.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-QCECHYZL.js.map → chunk-RVO6TCTU.js.map} +0 -0
- /package/dist/{chunk-SHDZNSK4.js.map → chunk-S2SJEOTM.js.map} +0 -0
- /package/dist/{chunk-ULWHRQEQ.js.map → chunk-S75UQ3T3.js.map} +0 -0
- /package/dist/{chunk-LXOM6IQU.js.map → chunk-SEF4IOFE.js.map} +0 -0
- /package/dist/{chunk-I3YHVVT4.js.map → chunk-SHYIMIX5.js.map} +0 -0
- /package/dist/{chunk-G5OB4XZX.js.map → chunk-VANZKHTN.js.map} +0 -0
- /package/dist/{chunk-I4TQST3L.js.map → chunk-VFS3MK5F.js.map} +0 -0
- /package/dist/{chunk-SMPVHGHG.js.map → chunk-WPZX7MEA.js.map} +0 -0
- /package/dist/{chunk-ZRWB5D4H.js.map → chunk-WT6UL3UA.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-JHMAYABJ.js.map → chunk-XL3TATMJ.js.map} +0 -0
- /package/dist/{chunk-MC6XO7T4.js.map → chunk-YLBE6PLR.js.map} +0 -0
- /package/dist/{chunk-OLX2HJFW.js.map → chunk-YLHM5BQQ.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-GF22HWS2.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-GVX3NAUU.js.map → chunk-ZDAYWJV6.js.map} +0 -0
- /package/dist/{chunk-EYAIZBLM.js.map → chunk-ZJIFYUJI.js.map} +0 -0
- /package/dist/{chunk-CNQQMB67.js.map → chunk-ZN4EYMKJ.js.map} +0 -0
- /package/dist/{resolution-3K27T4VO.js.map → coding/pre-action-gate.js.map} +0 -0
- /package/dist/{first-start-migration-ZSHEFEI3.js.map → first-start-migration-626C5554.js.map} +0 -0
- /package/dist/{forget-DNAJ66ZD.js.map → forget-GJ42LCBW.js.map} +0 -0
- /package/dist/{tier-stats-OPTSBNRH.js.map → tier-stats-2JCZYEF7.js.map} +0 -0
package/src/json-store.ts
CHANGED
|
@@ -1,19 +1,53 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { Dirent } from "node:fs";
|
|
3
|
+
import {
|
|
4
|
+
lstat,
|
|
5
|
+
mkdir,
|
|
6
|
+
open,
|
|
7
|
+
readFile,
|
|
8
|
+
readdir,
|
|
9
|
+
rename,
|
|
10
|
+
unlink,
|
|
11
|
+
utimes,
|
|
12
|
+
writeFile,
|
|
13
|
+
type FileHandle,
|
|
14
|
+
} from "node:fs/promises";
|
|
1
15
|
import path from "node:path";
|
|
2
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
3
16
|
|
|
4
|
-
|
|
17
|
+
function hasErrorCode(error: unknown, code: string): boolean {
|
|
18
|
+
return typeof error === "object" && error !== null && "code" in error && (error as { code?: unknown }).code === code;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function listJsonFilesStrictInner(dir: string, allowMissingDirectory: boolean): Promise<string[]> {
|
|
22
|
+
let entries: Dirent[];
|
|
5
23
|
try {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (allowMissingDirectory && hasErrorCode(error, "ENOENT")) return [];
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
const out: string[] = [];
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
const fullPath = path.join(dir, entry.name);
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
out.push(...(await listJsonFilesStrictInner(fullPath, false)));
|
|
34
|
+
} else if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
35
|
+
out.push(fullPath);
|
|
15
36
|
}
|
|
16
|
-
|
|
37
|
+
}
|
|
38
|
+
return out.sort();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function listJsonFilesStrict(
|
|
42
|
+
dir: string,
|
|
43
|
+
options: { allowMissingDirectory?: boolean } = {}
|
|
44
|
+
): Promise<string[]> {
|
|
45
|
+
return listJsonFilesStrictInner(dir, options.allowMissingDirectory === true);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function listJsonFiles(dir: string): Promise<string[]> {
|
|
49
|
+
try {
|
|
50
|
+
return await listJsonFilesStrict(dir);
|
|
17
51
|
} catch {
|
|
18
52
|
return [];
|
|
19
53
|
}
|
|
@@ -37,6 +71,314 @@ export async function listNamedFiles(dir: string, fileName: string): Promise<str
|
|
|
37
71
|
}
|
|
38
72
|
}
|
|
39
73
|
|
|
74
|
+
const jsonStoreMutationTails = new Map<string, Promise<void>>();
|
|
75
|
+
|
|
76
|
+
const JSON_STORE_LOCK_RETRY_MS = 25;
|
|
77
|
+
const JSON_STORE_LOCK_STALE_MS = 60_000;
|
|
78
|
+
const JSON_STORE_LOCK_TIMEOUT_MS = 10_000;
|
|
79
|
+
|
|
80
|
+
type JsonStoreMutationLockTestHooks = {
|
|
81
|
+
beforeLockOwnerWrite?: (lockPath: string, ownerToken: string) => Promise<void> | void;
|
|
82
|
+
beforeLockOwnershipConfirm?: (lockPath: string, ownerToken: string) => Promise<void> | void;
|
|
83
|
+
afterReclaimGuardWrite?: (reclaimPath: string, ownerToken: string) => Promise<void> | void;
|
|
84
|
+
retryMs?: number;
|
|
85
|
+
staleLockMs?: number;
|
|
86
|
+
timeoutMs?: number;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
let jsonStoreMutationLockTestHooks: JsonStoreMutationLockTestHooks | null = null;
|
|
90
|
+
|
|
91
|
+
export function setJsonStoreMutationLockTestHooks(hooks: JsonStoreMutationLockTestHooks | null): void {
|
|
92
|
+
jsonStoreMutationLockTestHooks = hooks;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function jsonStoreLockRetryMs(): number {
|
|
96
|
+
return jsonStoreMutationLockTestHooks?.retryMs ?? JSON_STORE_LOCK_RETRY_MS;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function jsonStoreLockStaleMs(): number {
|
|
100
|
+
return jsonStoreMutationLockTestHooks?.staleLockMs ?? JSON_STORE_LOCK_STALE_MS;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function jsonStoreLockTimeoutMs(): number {
|
|
104
|
+
return jsonStoreMutationLockTestHooks?.timeoutMs ?? JSON_STORE_LOCK_TIMEOUT_MS;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function closeAndRemoveJsonStoreReclaimGuard(reclaimPath: string, reclaimHandle: FileHandle): Promise<void> {
|
|
108
|
+
await reclaimHandle.close().catch(() => undefined);
|
|
109
|
+
await unlink(reclaimPath).catch((error) => {
|
|
110
|
+
if (!hasErrorCode(error, "ENOENT")) throw error;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function removeStaleJsonStoreReclaimGuard(reclaimPath: string): Promise<void> {
|
|
115
|
+
let initial: JsonStoreLockState;
|
|
116
|
+
try {
|
|
117
|
+
initial = await readJsonStoreLockState(reclaimPath);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (hasErrorCode(error, "ENOENT")) return;
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
|
|
123
|
+
|
|
124
|
+
let ownerPid: number | undefined;
|
|
125
|
+
try {
|
|
126
|
+
const metadata = JSON.parse(initial.content) as { pid?: unknown };
|
|
127
|
+
ownerPid = typeof metadata.pid === "number" && Number.isInteger(metadata.pid) ? metadata.pid : undefined;
|
|
128
|
+
} catch {
|
|
129
|
+
ownerPid = undefined;
|
|
130
|
+
}
|
|
131
|
+
if (ownerPid !== undefined && processIsRunning(ownerPid)) return;
|
|
132
|
+
|
|
133
|
+
let confirmed: JsonStoreLockState;
|
|
134
|
+
try {
|
|
135
|
+
confirmed = await readJsonStoreLockState(reclaimPath);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (hasErrorCode(error, "ENOENT")) return;
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
if (!sameJsonStoreLockState(initial, confirmed)) return;
|
|
141
|
+
await unlink(reclaimPath).catch((error) => {
|
|
142
|
+
if (!hasErrorCode(error, "ENOENT")) throw error;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function acquireJsonStoreReclaimGuard(reclaimPath: string): Promise<FileHandle | undefined> {
|
|
147
|
+
try {
|
|
148
|
+
return await open(reclaimPath, "wx", 0o600);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (!hasErrorCode(error, "EEXIST")) throw error;
|
|
151
|
+
await removeStaleJsonStoreReclaimGuard(reclaimPath);
|
|
152
|
+
try {
|
|
153
|
+
return await open(reclaimPath, "wx", 0o600);
|
|
154
|
+
} catch (retryError) {
|
|
155
|
+
if (hasErrorCode(retryError, "EEXIST")) return undefined;
|
|
156
|
+
throw retryError;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function waitForJsonStoreLock(): Promise<void> {
|
|
162
|
+
const { promise, resolve } = Promise.withResolvers<void>();
|
|
163
|
+
setTimeout(resolve, jsonStoreLockRetryMs());
|
|
164
|
+
return promise;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function processIsRunning(pid: number): boolean {
|
|
168
|
+
try {
|
|
169
|
+
process.kill(pid, 0);
|
|
170
|
+
return true;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
return !hasErrorCode(error, "ESRCH");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
type JsonStoreLockState = {
|
|
177
|
+
mtimeMs: number;
|
|
178
|
+
size: number;
|
|
179
|
+
ino: number | undefined;
|
|
180
|
+
content: string;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
async function readJsonStoreLockState(lockPath: string): Promise<JsonStoreLockState> {
|
|
184
|
+
const lockStat = await lstat(lockPath);
|
|
185
|
+
if (!lockStat.isFile()) {
|
|
186
|
+
throw new Error(`JSON store mutation lock is not a regular file: ${lockPath}`);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
mtimeMs: lockStat.mtimeMs,
|
|
190
|
+
size: lockStat.size,
|
|
191
|
+
ino: typeof lockStat.ino === "number" ? lockStat.ino : undefined,
|
|
192
|
+
content: await readFile(lockPath, "utf8"),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function sameJsonStoreLockState(left: JsonStoreLockState, right: JsonStoreLockState): boolean {
|
|
197
|
+
return (
|
|
198
|
+
left.mtimeMs === right.mtimeMs &&
|
|
199
|
+
left.size === right.size &&
|
|
200
|
+
left.ino === right.ino &&
|
|
201
|
+
left.content === right.content
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function removeJsonStoreMutationLockIfOwned(lockPath: string, token: string): Promise<void> {
|
|
206
|
+
try {
|
|
207
|
+
const state = await readJsonStoreLockState(lockPath);
|
|
208
|
+
const metadata = JSON.parse(state.content) as { token?: unknown };
|
|
209
|
+
if (metadata.token === token) await unlink(lockPath);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
if (!hasErrorCode(error, "ENOENT") && !(error instanceof SyntaxError)) throw error;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function removeStaleJsonStoreLock(lockPath: string): Promise<void> {
|
|
216
|
+
const reclaimPath = `${lockPath}.reclaim`;
|
|
217
|
+
const reclaimHandle = await acquireJsonStoreReclaimGuard(reclaimPath);
|
|
218
|
+
if (!reclaimHandle) return;
|
|
219
|
+
try {
|
|
220
|
+
await reclaimHandle.writeFile(JSON.stringify({ pid: process.pid }), "utf8");
|
|
221
|
+
await jsonStoreMutationLockTestHooks?.afterReclaimGuardWrite?.(reclaimPath, String(process.pid));
|
|
222
|
+
|
|
223
|
+
let initial: JsonStoreLockState;
|
|
224
|
+
try {
|
|
225
|
+
initial = await readJsonStoreLockState(lockPath);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (hasErrorCode(error, "ENOENT")) return;
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
|
|
231
|
+
let ownerPid: number | undefined;
|
|
232
|
+
try {
|
|
233
|
+
const metadata = JSON.parse(initial.content) as { pid?: unknown };
|
|
234
|
+
ownerPid = typeof metadata.pid === "number" && Number.isInteger(metadata.pid) ? metadata.pid : undefined;
|
|
235
|
+
} catch {
|
|
236
|
+
ownerPid = undefined;
|
|
237
|
+
}
|
|
238
|
+
if (ownerPid !== undefined && processIsRunning(ownerPid)) return;
|
|
239
|
+
|
|
240
|
+
let confirmed: JsonStoreLockState;
|
|
241
|
+
try {
|
|
242
|
+
confirmed = await readJsonStoreLockState(lockPath);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (hasErrorCode(error, "ENOENT")) return;
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
if (!sameJsonStoreLockState(initial, confirmed)) return;
|
|
248
|
+
await unlink(lockPath).catch((error) => {
|
|
249
|
+
if (!hasErrorCode(error, "ENOENT")) throw error;
|
|
250
|
+
});
|
|
251
|
+
} finally {
|
|
252
|
+
await closeAndRemoveJsonStoreReclaimGuard(reclaimPath, reclaimHandle);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function confirmJsonStoreMutationLockOwnership(
|
|
257
|
+
lockPath: string,
|
|
258
|
+
token: string,
|
|
259
|
+
deadline: number
|
|
260
|
+
): Promise<boolean> {
|
|
261
|
+
const reclaimPath = `${lockPath}.reclaim`;
|
|
262
|
+
while (true) {
|
|
263
|
+
const reclaimHandle = await acquireJsonStoreReclaimGuard(reclaimPath);
|
|
264
|
+
if (!reclaimHandle) {
|
|
265
|
+
if (Date.now() >= deadline) return false;
|
|
266
|
+
await waitForJsonStoreLock();
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
try {
|
|
271
|
+
const state = await readJsonStoreLockState(lockPath);
|
|
272
|
+
const metadata = JSON.parse(state.content) as { token?: unknown };
|
|
273
|
+
return metadata.token === token;
|
|
274
|
+
} catch (error) {
|
|
275
|
+
if (hasErrorCode(error, "ENOENT") || error instanceof SyntaxError) return false;
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
278
|
+
} finally {
|
|
279
|
+
await closeAndRemoveJsonStoreReclaimGuard(reclaimPath, reclaimHandle);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async function acquireJsonStoreMutationFileLock(key: string): Promise<() => Promise<void>> {
|
|
285
|
+
const lockPath = `${path.resolve(key)}.mutation.lock`;
|
|
286
|
+
await mkdir(path.dirname(lockPath), { recursive: true });
|
|
287
|
+
const token = randomUUID();
|
|
288
|
+
const deadline = Date.now() + jsonStoreLockTimeoutMs();
|
|
289
|
+
while (true) {
|
|
290
|
+
let handle: FileHandle;
|
|
291
|
+
try {
|
|
292
|
+
handle = await open(lockPath, "wx", 0o600);
|
|
293
|
+
} catch (error) {
|
|
294
|
+
if (!hasErrorCode(error, "EEXIST")) throw error;
|
|
295
|
+
await removeStaleJsonStoreLock(lockPath).catch((staleError) => {
|
|
296
|
+
if (!hasErrorCode(staleError, "ENOENT")) throw staleError;
|
|
297
|
+
});
|
|
298
|
+
if (Date.now() >= deadline) {
|
|
299
|
+
throw new Error(`Timed out acquiring JSON store mutation lock: ${lockPath}`);
|
|
300
|
+
}
|
|
301
|
+
await waitForJsonStoreLock();
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
await jsonStoreMutationLockTestHooks?.beforeLockOwnerWrite?.(lockPath, token);
|
|
306
|
+
await handle.writeFile(JSON.stringify({ pid: process.pid, token }), "utf8");
|
|
307
|
+
} finally {
|
|
308
|
+
await handle.close().catch(() => undefined);
|
|
309
|
+
}
|
|
310
|
+
await jsonStoreMutationLockTestHooks?.beforeLockOwnershipConfirm?.(lockPath, token);
|
|
311
|
+
|
|
312
|
+
if (!(await confirmJsonStoreMutationLockOwnership(lockPath, token, deadline))) {
|
|
313
|
+
await removeJsonStoreMutationLockIfOwned(lockPath, token);
|
|
314
|
+
if (Date.now() >= deadline) {
|
|
315
|
+
throw new Error(`Timed out acquiring JSON store mutation lock: ${lockPath}`);
|
|
316
|
+
}
|
|
317
|
+
await waitForJsonStoreLock();
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const heartbeat = setInterval(
|
|
322
|
+
() => {
|
|
323
|
+
void readFile(lockPath, "utf8")
|
|
324
|
+
.then((content) => {
|
|
325
|
+
const metadata = JSON.parse(content) as { token?: unknown };
|
|
326
|
+
if (metadata.token !== token) return;
|
|
327
|
+
const now = new Date();
|
|
328
|
+
return utimes(lockPath, now, now);
|
|
329
|
+
})
|
|
330
|
+
.catch(() => undefined);
|
|
331
|
+
},
|
|
332
|
+
Math.max(1, Math.floor(jsonStoreLockStaleMs() / 3))
|
|
333
|
+
);
|
|
334
|
+
heartbeat.unref();
|
|
335
|
+
return async () => {
|
|
336
|
+
clearInterval(heartbeat);
|
|
337
|
+
try {
|
|
338
|
+
const metadata = JSON.parse(await readFile(lockPath, "utf8")) as { token?: unknown };
|
|
339
|
+
if (metadata.token === token) await unlink(lockPath);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
if (!hasErrorCode(error, "ENOENT")) throw error;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export async function withJsonStoreMutationLock<T>(key: string, operation: () => Promise<T>): Promise<T> {
|
|
348
|
+
const normalizedKey = path.resolve(key);
|
|
349
|
+
const previous = jsonStoreMutationTails.get(normalizedKey) ?? Promise.resolve();
|
|
350
|
+
const { promise: current, resolve: release } = Promise.withResolvers<void>();
|
|
351
|
+
const tail = previous.catch(() => undefined).then(() => current);
|
|
352
|
+
jsonStoreMutationTails.set(normalizedKey, tail);
|
|
353
|
+
await previous.catch(() => undefined);
|
|
354
|
+
let releaseFileLock: (() => Promise<void>) | undefined;
|
|
355
|
+
try {
|
|
356
|
+
releaseFileLock = await acquireJsonStoreMutationFileLock(normalizedKey);
|
|
357
|
+
return await operation();
|
|
358
|
+
} finally {
|
|
359
|
+
try {
|
|
360
|
+
await releaseFileLock?.();
|
|
361
|
+
} finally {
|
|
362
|
+
release();
|
|
363
|
+
if (jsonStoreMutationTails.get(normalizedKey) === tail) {
|
|
364
|
+
jsonStoreMutationTails.delete(normalizedKey);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
40
370
|
export async function readJsonFile(filePath: string): Promise<unknown> {
|
|
41
371
|
return JSON.parse(await readFile(filePath, "utf8")) as unknown;
|
|
42
372
|
}
|
|
373
|
+
|
|
374
|
+
export async function writeJsonFileAtomic(filePath: string, value: unknown): Promise<void> {
|
|
375
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
376
|
+
const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
377
|
+
try {
|
|
378
|
+
await writeFile(tempPath, JSON.stringify(value, null, 2), "utf8");
|
|
379
|
+
await rename(tempPath, filePath);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
await unlink(tempPath).catch(() => undefined);
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
@@ -32,7 +32,9 @@ import { applyCommitmentLedgerLifecycle } from "../commitment-ledger.js";
|
|
|
32
32
|
import { recordDreamsPhaseRun } from "../maintenance/dreams-ledger.js";
|
|
33
33
|
import { deindexMemoriesBatchAsync } from "../temporal-index-batch.js";
|
|
34
34
|
import { isActiveMemoryStatus } from "../memory-lifecycle-ledger-utils.js";
|
|
35
|
+
import { propagateInvalidation } from "./dependency-propagation.js";
|
|
35
36
|
import {
|
|
37
|
+
resolveCapabilities,
|
|
36
38
|
resolveConsolidationCapabilities,
|
|
37
39
|
resolveCreationMemoryCapabilities,
|
|
38
40
|
resolveIndexingCapabilities,
|
|
@@ -42,6 +44,7 @@ import {
|
|
|
42
44
|
resolveRecallEnhancementCapabilities,
|
|
43
45
|
type MemoryLifecycleCapabilitySet,
|
|
44
46
|
} from "../capabilities.js";
|
|
47
|
+
import { pruneOrphanCueAnchors } from "../cue-anchors.js";
|
|
45
48
|
import type { LifecyclePolicyCoordinator } from "./lifecycle-policy-coordinator.js";
|
|
46
49
|
import type { CompressionGuidelineCoordinator } from "./compression-guideline-coordinator.js";
|
|
47
50
|
import type { SemanticConsolidationCoordinator } from "./semantic-consolidation-coordinator.js";
|
|
@@ -49,6 +52,7 @@ import type { EntitySynthesisCoordinator } from "./entity-synthesis-coordinator.
|
|
|
49
52
|
import type { RecallSectionCoordinator } from "./recall-section-coordinator.js";
|
|
50
53
|
import type { TierMigrationCoordinator } from "./tier-migration-coordinator.js";
|
|
51
54
|
import type { StorageManager } from "../index.js";
|
|
55
|
+
import type { NamespaceCatalog } from "../namespaces/catalog.js";
|
|
52
56
|
import type { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
53
57
|
import type { ExtractionEngine } from "../extraction.js";
|
|
54
58
|
import type { EmbeddingFallback } from "../embedding-fallback.js";
|
|
@@ -67,6 +71,7 @@ export interface ConsolidationRunCoordinatorDeps {
|
|
|
67
71
|
config: PluginConfig;
|
|
68
72
|
getStorage: () => StorageManager;
|
|
69
73
|
getStorageRouter: () => NamespaceStorageRouter;
|
|
74
|
+
getNamespaceCatalog?: () => NamespaceCatalog;
|
|
70
75
|
getExtraction: () => ExtractionEngine;
|
|
71
76
|
embeddingFallback: EmbeddingFallback;
|
|
72
77
|
tmtBuilder: TmtBuilder;
|
|
@@ -100,9 +105,142 @@ export interface ConsolidationRunCoordinatorDeps {
|
|
|
100
105
|
) => Promise<{ content: string } | null>;
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
const MAX_HARMONIC_NAMESPACE_STORES = 50;
|
|
109
|
+
const HARMONIC_CATALOG_CURSOR_FILE = "harmonic-catalog-cursor.json";
|
|
110
|
+
|
|
111
|
+
type HarmonicStore = {
|
|
112
|
+
memoryDir: string;
|
|
113
|
+
abstractionNodeStoreDir?: string;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
type HarmonicCatalogCursor = {
|
|
117
|
+
nextStorageDir?: string;
|
|
118
|
+
};
|
|
119
|
+
|
|
103
120
|
export class ConsolidationRunCoordinator {
|
|
104
121
|
constructor(private readonly deps: ConsolidationRunCoordinatorDeps) {}
|
|
105
122
|
|
|
123
|
+
private async readHarmonicCatalogCursor(defaultDir: string): Promise<string | undefined> {
|
|
124
|
+
const cursorPath = path.join(defaultDir, "state", HARMONIC_CATALOG_CURSOR_FILE);
|
|
125
|
+
try {
|
|
126
|
+
const raw = await readFile(cursorPath, "utf-8");
|
|
127
|
+
const parsed = JSON.parse(raw) as HarmonicCatalogCursor;
|
|
128
|
+
return typeof parsed.nextStorageDir === "string" && parsed.nextStorageDir.length > 0
|
|
129
|
+
? path.resolve(parsed.nextStorageDir)
|
|
130
|
+
: undefined;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
133
|
+
log.warn(
|
|
134
|
+
`harmonic namespace catalog cursor read failed open: ${
|
|
135
|
+
error instanceof Error ? error.message : String(error)
|
|
136
|
+
}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private async writeHarmonicCatalogCursor(
|
|
144
|
+
defaultDir: string,
|
|
145
|
+
nextStorageDir: string,
|
|
146
|
+
): Promise<void> {
|
|
147
|
+
const stateDir = path.join(defaultDir, "state");
|
|
148
|
+
await mkdir(stateDir, { recursive: true });
|
|
149
|
+
await writeFile(
|
|
150
|
+
path.join(stateDir, HARMONIC_CATALOG_CURSOR_FILE),
|
|
151
|
+
JSON.stringify({ nextStorageDir }, null, 2),
|
|
152
|
+
"utf-8",
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private async pruneHarmonicStores(storage: StorageManager): Promise<void> {
|
|
157
|
+
const config = this.deps.config;
|
|
158
|
+
if (
|
|
159
|
+
!resolveCapabilities(config).harmonicRetrieval ||
|
|
160
|
+
!resolveConsolidationCapabilities(config).abstractionAnchors
|
|
161
|
+
) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const stores = new Map<string, HarmonicStore>();
|
|
166
|
+
const defaultDir = path.resolve(storage.dir);
|
|
167
|
+
stores.set(defaultDir, {
|
|
168
|
+
memoryDir: storage.dir,
|
|
169
|
+
abstractionNodeStoreDir: config.abstractionNodeStoreDir,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
const catalog = this.deps.getNamespaceCatalog?.();
|
|
174
|
+
if (catalog?.enabled) {
|
|
175
|
+
const records = await catalog.listNamespaces({ discoveredBy: "write" });
|
|
176
|
+
const catalogStores = new Map<string, HarmonicStore>();
|
|
177
|
+
for (const record of records) {
|
|
178
|
+
const storageDir = path.resolve(record.storageDir);
|
|
179
|
+
if (!stores.has(storageDir) && !catalogStores.has(storageDir)) {
|
|
180
|
+
catalogStores.set(storageDir, { memoryDir: record.storageDir });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const candidates = [...catalogStores.entries()];
|
|
185
|
+
if (candidates.length > 0) {
|
|
186
|
+
const cursor = await this.readHarmonicCatalogCursor(defaultDir);
|
|
187
|
+
const cursorIndex = cursor
|
|
188
|
+
? candidates.findIndex(([storageDir]) => storageDir === cursor)
|
|
189
|
+
: -1;
|
|
190
|
+
const startIndex = cursorIndex >= 0 ? cursorIndex : 0;
|
|
191
|
+
const selectedCount = Math.min(
|
|
192
|
+
candidates.length,
|
|
193
|
+
MAX_HARMONIC_NAMESPACE_STORES - 1,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
for (let offset = 0; offset < selectedCount; offset += 1) {
|
|
197
|
+
const index = (startIndex + offset) % candidates.length;
|
|
198
|
+
const [storageDir, store] = candidates[index];
|
|
199
|
+
stores.set(storageDir, store);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const nextIndex = (startIndex + selectedCount) % candidates.length;
|
|
203
|
+
const nextStorageDir = candidates[nextIndex][0];
|
|
204
|
+
try {
|
|
205
|
+
await this.writeHarmonicCatalogCursor(defaultDir, nextStorageDir);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
log.warn(
|
|
208
|
+
`harmonic namespace catalog cursor write failed open: ${
|
|
209
|
+
error instanceof Error ? error.message : String(error)
|
|
210
|
+
}`,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (selectedCount < candidates.length) {
|
|
215
|
+
log.warn(
|
|
216
|
+
`harmonic namespace catalog truncated at ${MAX_HARMONIC_NAMESPACE_STORES} stores; ` +
|
|
217
|
+
`skipped ${candidates.length - selectedCount} store(s)`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
log.warn(
|
|
224
|
+
`harmonic namespace catalog read failed open: ${error instanceof Error ? error.message : String(error)}`,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
for (const store of stores.values()) {
|
|
229
|
+
try {
|
|
230
|
+
const removed = await pruneOrphanCueAnchors(store);
|
|
231
|
+
if (removed > 0) {
|
|
232
|
+
log.info(`harmonic anchor prune removed ${removed} orphan(s) from ${store.memoryDir}`);
|
|
233
|
+
}
|
|
234
|
+
} catch (error) {
|
|
235
|
+
log.warn(
|
|
236
|
+
`harmonic anchor prune failed open for ${store.memoryDir}: ${
|
|
237
|
+
error instanceof Error ? error.message : String(error)
|
|
238
|
+
}`,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
106
244
|
async run(): Promise<{
|
|
107
245
|
memoriesProcessed: number;
|
|
108
246
|
merged: number;
|
|
@@ -124,6 +262,7 @@ export class ConsolidationRunCoordinator {
|
|
|
124
262
|
if (this.deps.getAccessTrackingBuffer().size > 0) {
|
|
125
263
|
await this.deps.flushAccessTracking();
|
|
126
264
|
}
|
|
265
|
+
await this.pruneHarmonicStores(storage);
|
|
127
266
|
|
|
128
267
|
let allMemories = await storage.readAllMemories();
|
|
129
268
|
if (allMemories.length < 5) {
|
|
@@ -170,10 +309,36 @@ export class ConsolidationRunCoordinator {
|
|
|
170
309
|
const toInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
|
|
171
310
|
? (memoryLookup?.get(item.existingId) ?? null)
|
|
172
311
|
: null;
|
|
312
|
+
// Always capture the full pre-delete snapshot for propagation.
|
|
313
|
+
const propagationOld = allMemories.find(
|
|
314
|
+
(memory) => memory.frontmatter.id === item.existingId,
|
|
315
|
+
);
|
|
173
316
|
if (await storage.invalidateMemory(item.existingId)) {
|
|
174
317
|
invalidated += 1;
|
|
175
318
|
memoryItemMutated = true;
|
|
176
319
|
await this.deps.embeddingFallback.removeFromIndex(item.existingId);
|
|
320
|
+
if (propagationOld) {
|
|
321
|
+
try {
|
|
322
|
+
await propagateInvalidation(
|
|
323
|
+
{
|
|
324
|
+
storage,
|
|
325
|
+
extraction: this.deps.getExtraction(),
|
|
326
|
+
config,
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
oldMemory: propagationOld,
|
|
330
|
+
replacementId: null,
|
|
331
|
+
replacementContent: null,
|
|
332
|
+
cause: "consolidation_invalidate",
|
|
333
|
+
namespaceScope: config.defaultNamespace,
|
|
334
|
+
},
|
|
335
|
+
);
|
|
336
|
+
} catch (propagationErr) {
|
|
337
|
+
log.warn(
|
|
338
|
+
`consolidation dependency propagation failed for ${item.existingId}: ${propagationErr}`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
177
342
|
if (toInvalidate?.path && toInvalidate.frontmatter?.created) {
|
|
178
343
|
itemsDeindexBatch.push({
|
|
179
344
|
path: toInvalidate.path,
|
|
@@ -217,10 +382,37 @@ export class ConsolidationRunCoordinator {
|
|
|
217
382
|
const toMergeInvalidate = resolveIndexingCapabilities(config).queryAwareIndexing
|
|
218
383
|
? (memoryLookup?.get(item.mergeWith) ?? null)
|
|
219
384
|
: null;
|
|
385
|
+
// Capture the doomed memory before invalidation, independent of
|
|
386
|
+
// queryAwareIndexing and its optional lookup map.
|
|
387
|
+
const propagationOld = allMemories.find(
|
|
388
|
+
(memory) => memory.frontmatter.id === item.mergeWith,
|
|
389
|
+
);
|
|
220
390
|
if (await storage.invalidateMemory(item.mergeWith)) {
|
|
221
391
|
invalidated += 1;
|
|
222
392
|
merged += 1;
|
|
223
393
|
await this.deps.embeddingFallback.removeFromIndex(item.mergeWith);
|
|
394
|
+
if (propagationOld) {
|
|
395
|
+
try {
|
|
396
|
+
await propagateInvalidation(
|
|
397
|
+
{
|
|
398
|
+
storage,
|
|
399
|
+
extraction: this.deps.getExtraction(),
|
|
400
|
+
config,
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
oldMemory: propagationOld,
|
|
404
|
+
replacementId: item.existingId,
|
|
405
|
+
replacementContent: item.updatedContent,
|
|
406
|
+
cause: "consolidation_merge",
|
|
407
|
+
namespaceScope: config.defaultNamespace,
|
|
408
|
+
},
|
|
409
|
+
);
|
|
410
|
+
} catch (propagationErr) {
|
|
411
|
+
log.warn(
|
|
412
|
+
`consolidation dependency propagation failed for ${item.mergeWith}: ${propagationErr}`,
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
224
416
|
if (
|
|
225
417
|
toMergeInvalidate?.path &&
|
|
226
418
|
toMergeInvalidate.frontmatter?.created
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import type {
|
|
20
|
+
MemoryFile,
|
|
20
21
|
MemoryLink,
|
|
21
22
|
PluginConfig,
|
|
22
23
|
QmdSearchResult,
|
|
@@ -28,6 +29,7 @@ import type { ExtractionEngine } from "../extraction.js";
|
|
|
28
29
|
import { log } from "../logger.js";
|
|
29
30
|
import { resolveIndexingCapabilities } from "../capabilities.js";
|
|
30
31
|
import { deindexMemoryAsync } from "../temporal-index.js";
|
|
32
|
+
import { propagateInvalidation } from "./dependency-propagation.js";
|
|
31
33
|
|
|
32
34
|
/** Result type of {@link ContradictionLinkingCoordinator.checkForContradiction}. */
|
|
33
35
|
export interface ContradictionResult {
|
|
@@ -243,12 +245,44 @@ export class ContradictionLinkingCoordinator {
|
|
|
243
245
|
) {
|
|
244
246
|
return;
|
|
245
247
|
}
|
|
248
|
+
|
|
249
|
+
// Capture links before the primary supersession. The propagation hook is
|
|
250
|
+
// orchestration-owned, so its own supersessions cannot recurse.
|
|
251
|
+
let oldMemory: MemoryFile | null = null;
|
|
252
|
+
try {
|
|
253
|
+
oldMemory = await storage.getMemoryById(contradiction.supersededId);
|
|
254
|
+
} catch (err) {
|
|
255
|
+
log.warn(`contradiction propagation snapshot failed for ${contradiction.supersededId}: ${err}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
246
258
|
try {
|
|
247
|
-
await storage.supersedeMemory(
|
|
259
|
+
const superseded = await storage.supersedeMemory(
|
|
248
260
|
contradiction.supersededId,
|
|
249
261
|
newMemoryId,
|
|
250
262
|
contradiction.reason,
|
|
251
263
|
);
|
|
264
|
+
if (!superseded) return;
|
|
265
|
+
if (oldMemory) {
|
|
266
|
+
try {
|
|
267
|
+
await propagateInvalidation(
|
|
268
|
+
{
|
|
269
|
+
storage,
|
|
270
|
+
extraction: this.getExtraction(),
|
|
271
|
+
config,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
oldMemory,
|
|
275
|
+
replacementId: newMemoryId,
|
|
276
|
+
replacementContent: (await storage.getMemoryById(newMemoryId))?.content ?? null,
|
|
277
|
+
cause: "contradiction",
|
|
278
|
+
namespaceScope: this.namespaceFromPath(storage.dir),
|
|
279
|
+
},
|
|
280
|
+
);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
log.warn(`contradiction dependency propagation failed for ${contradiction.supersededId}: ${err}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
252
286
|
if (
|
|
253
287
|
resolveIndexingCapabilities(config).queryAwareIndexing &&
|
|
254
288
|
contradiction.supersededPath
|