@remnic/core 10.0.94 → 10.0.96
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.map +1 -1
- package/dist/abstraction-nodes.js +7 -1
- package/dist/access-admin-ops-surface.js +91 -90
- package/dist/access-audit.js +2 -2
- package/dist/access-cli.js +91 -90
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +91 -90
- package/dist/access-http-briefing.js +91 -90
- package/dist/access-http-query.js +91 -90
- package/dist/access-http.js +91 -90
- package/dist/access-identity-continuity-surface.js +91 -90
- package/dist/access-lcm-surface.js +91 -90
- package/dist/access-mcp.js +91 -90
- package/dist/access-observe-write-surface.js +91 -90
- package/dist/access-operations-batch.js +91 -90
- package/dist/access-operations.js +91 -90
- package/dist/access-recall-concurrency.js +91 -90
- package/dist/access-recall-response.js +91 -90
- package/dist/access-recall-surface.js +91 -90
- package/dist/access-schema.d.ts +5 -5
- package/dist/access-service.js +91 -90
- package/dist/active-recall.js +16 -16
- package/dist/briefing.js +15 -15
- package/dist/buffer.js +7 -7
- package/dist/calibration.js +2 -2
- package/dist/{capsule-merge-6IDAYTKG.js → capsule-merge-ILR35DIB.js} +10 -10
- package/dist/causal-consolidation.js +16 -16
- package/dist/{chunk-QHARXWTC.js → chunk-2LCX6TAD.js} +2 -2
- package/dist/{chunk-UN4RVUG2.js → chunk-2R3ACFYN.js} +3 -3
- package/dist/{chunk-RQFXZYTF.js → chunk-33C4BK7I.js} +4 -4
- package/dist/{chunk-UBEKET2V.js → chunk-3R63SXC5.js} +4 -4
- package/dist/{chunk-LNGELD2M.js → chunk-3VWU3KF3.js} +2 -2
- package/dist/{chunk-FWRXW7CZ.js → chunk-4CXK3GT3.js} +29 -29
- package/dist/{chunk-DNY63QWJ.js → chunk-4HK7DYOL.js} +2 -2
- package/dist/{chunk-LLPMMMWG.js → chunk-4IJFJQPD.js} +2 -2
- package/dist/{chunk-GBJUTX44.js → chunk-4WKR4P7H.js} +2 -2
- package/dist/{chunk-ILY5SSOM.js → chunk-53ZVHXVZ.js} +6 -6
- package/dist/{chunk-FQAQ63QA.js → chunk-5AJIGWY4.js} +2 -2
- package/dist/{chunk-CIWMTNHW.js → chunk-5NFF2TSD.js} +2 -2
- package/dist/{chunk-D5XG2KPS.js → chunk-7E7J7QXB.js} +2 -2
- package/dist/{chunk-2WCLTWV2.js → chunk-7NVK6AGC.js} +2 -2
- package/dist/{chunk-PC5DRBGD.js → chunk-AP4BFWSW.js} +2 -2
- package/dist/{chunk-CL4JU3DF.js → chunk-B7L4ZYFY.js} +3 -3
- package/dist/{chunk-LQ5SS4OP.js → chunk-D6IGZYTN.js} +3 -3
- package/dist/{chunk-XJ2S5UBF.js → chunk-DWWX3FU3.js} +3 -3
- package/dist/{chunk-IL3RHBWM.js → chunk-EJ23D4JG.js} +3 -3
- package/dist/{chunk-F4QFU5IZ.js → chunk-EZ7XJJ5L.js} +2 -2
- package/dist/{chunk-FZZMLGWQ.js → chunk-F4BUSX3D.js} +2 -2
- package/dist/{chunk-LXATZLSC.js → chunk-FL3O34XF.js} +12 -5
- package/dist/chunk-FL3O34XF.js.map +1 -0
- package/dist/{chunk-DPPLNZ3A.js → chunk-FM4P7HSW.js} +4 -4
- package/dist/{chunk-QDESY76F.js → chunk-FQACH7MC.js} +2 -2
- package/dist/{chunk-XPXHQI6N.js → chunk-FVMEZ57K.js} +2 -2
- package/dist/{chunk-F2XNSIPP.js → chunk-G2CGIFRP.js} +10 -3
- package/dist/chunk-G2CGIFRP.js.map +1 -0
- package/dist/{chunk-ZDV5YWID.js → chunk-GLDIMGOS.js} +6 -6
- package/dist/{chunk-YIXJSW5M.js → chunk-HA5DASDG.js} +3 -3
- package/dist/{chunk-S3S72HRM.js → chunk-HCCRWSP7.js} +2 -2
- package/dist/{chunk-NMGHGTVR.js → chunk-HRMOKGQM.js} +6 -6
- package/dist/{chunk-OUVYYKYU.js → chunk-IBKGQ6EY.js} +2 -2
- package/dist/{chunk-RNG7S3FY.js → chunk-ICHLN5L6.js} +6 -6
- package/dist/chunk-ITAUMNQU.js +40 -0
- package/dist/chunk-ITAUMNQU.js.map +1 -0
- package/dist/{chunk-R23JWJD3.js → chunk-J426U7XK.js} +9 -9
- package/dist/{chunk-QMFAMOT2.js → chunk-JH5AV542.js} +2 -2
- package/dist/{chunk-WGGRZYSQ.js → chunk-KE3JWIZK.js} +8 -8
- package/dist/{chunk-SQ3GEIEL.js → chunk-KUQLUYIR.js} +5 -5
- package/dist/{chunk-RKABLU5M.js → chunk-KVHGCISP.js} +9 -9
- package/dist/{chunk-RUTN5MMC.js → chunk-LRLQ2PRP.js} +5 -5
- package/dist/{chunk-X5HGU2EM.js → chunk-NT772J7I.js} +2 -2
- package/dist/{chunk-BPK32FRM.js → chunk-NTDHSV7N.js} +61 -6
- package/dist/chunk-NTDHSV7N.js.map +1 -0
- package/dist/{chunk-4EZWSDFL.js → chunk-NX4XDDFQ.js} +3 -3
- package/dist/{chunk-IAYUTGF2.js → chunk-O3GZPLVY.js} +4 -4
- package/dist/{chunk-IGOW4TJE.js → chunk-O3JG4PD3.js} +2 -2
- package/dist/{chunk-UHMHJX5G.js → chunk-OIG4ZFMB.js} +4 -4
- package/dist/{chunk-IQ55QGY5.js → chunk-R4JYSBZE.js} +2 -2
- package/dist/{chunk-Z3FTSHT5.js → chunk-RUQE5C32.js} +2 -2
- package/dist/{chunk-ESLOLCD4.js → chunk-RUWKIPWJ.js} +2 -2
- package/dist/{chunk-W54Z2MOP.js → chunk-RXSGBO7Y.js} +2 -2
- package/dist/{chunk-D5S6RL32.js → chunk-TFMLRVMW.js} +166 -145
- package/dist/{chunk-D5S6RL32.js.map → chunk-TFMLRVMW.js.map} +1 -1
- package/dist/{chunk-BOK6BN5M.js → chunk-THV6PZ7V.js} +2 -2
- package/dist/{chunk-J7BIFOYP.js → chunk-U6TC6Z5B.js} +2 -2
- package/dist/{chunk-X2BVB74H.js → chunk-UZQXJDOE.js} +2 -2
- package/dist/{chunk-SUTEBYGI.js → chunk-V7T45MI6.js} +2 -2
- package/dist/{chunk-A4F7OIC5.js → chunk-WVIWDMFB.js} +2 -2
- package/dist/{chunk-BN2EBCLB.js → chunk-XPCUKWLE.js} +2 -2
- package/dist/{chunk-OJXK5C6Z.js → chunk-ZG4GNPRE.js} +7 -7
- package/dist/{chunk-TYRWSE4B.js → chunk-ZUMHQEW4.js} +2 -2
- package/dist/{chunk-DAOMWGO2.js → chunk-ZX5N5D6M.js} +4 -4
- package/dist/cli.js +91 -90
- package/dist/coding/export-okf-codegraph.js +14 -14
- package/dist/compounding/engine.js +16 -16
- package/dist/config.js +16 -16
- package/dist/connectors/codex-materialize-runner.js +15 -15
- package/dist/connectors/index.js +15 -15
- package/dist/consolidation-provenance-check.js +8 -8
- package/dist/consolidation-undo.js +6 -6
- package/dist/contradiction/index.js +6 -6
- package/dist/convergence-refresh.js +17 -17
- package/dist/corpus-watermark.js +17 -17
- package/dist/cue-anchors.d.ts.map +1 -1
- package/dist/cue-anchors.js +8 -2
- package/dist/{entity-canonical-id-migration-JJSTZF73.js → entity-canonical-id-migration-IG77BOGD.js} +5 -5
- package/dist/entity-mention-index-cache.js +2 -2
- package/dist/entity-retrieval.js +16 -16
- package/dist/explicit-capture.js +91 -90
- package/dist/extraction.js +21 -21
- package/dist/harmonic-construction.js +9 -3
- package/dist/harmonic-graph-version.d.ts +14 -0
- package/dist/harmonic-graph-version.d.ts.map +1 -0
- package/dist/harmonic-graph-version.js +17 -0
- package/dist/harmonic-retrieval.d.ts +19 -14
- package/dist/harmonic-retrieval.d.ts.map +1 -1
- package/dist/harmonic-retrieval.js +22 -17
- package/dist/index.js +105 -104
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.js +8 -8
- package/dist/local-llm.js +2 -2
- package/dist/location/index.js +16 -16
- package/dist/maintenance/memory-governance.js +15 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +15 -15
- package/dist/maintenance/rebuild-memory-projection-runner.js +17 -17
- package/dist/maintenance/rebuild-memory-projection.js +16 -16
- package/dist/memory-browse.js +7 -7
- package/dist/namespaces/migrate.js +16 -16
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.js +15 -15
- package/dist/operator-doctor-corpus.js +18 -18
- package/dist/operator-toolkit.js +24 -24
- package/dist/orchestration/backlog-scheduler.js +92 -91
- package/dist/orchestration/backlog-scheduler.js.map +1 -1
- package/dist/orchestration/buffer-drain-runner.js +92 -91
- package/dist/orchestration/extraction-persist-failure.d.ts +25 -1
- package/dist/orchestration/extraction-persist-failure.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist.d.ts +3 -6
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/maintenance.js +25 -25
- package/dist/orchestrator.js +93 -92
- package/dist/page-versioning.js +6 -6
- package/dist/qmd.js +4 -4
- package/dist/recall-navigation.js +91 -90
- package/dist/recall-state-view-admission.js +7 -7
- package/dist/recall-why-service.js +7 -7
- package/dist/{resolution-OVVIF7ZY.js → resolution-G4SLHSEU.js} +7 -7
- package/dist/resolution-G4SLHSEU.js.map +1 -0
- package/dist/resume-bundles.js +17 -17
- package/dist/schemas.d.ts +9 -9
- package/dist/search/factory.js +5 -5
- package/dist/search/index.js +5 -5
- package/dist/semantic-consolidation.js +16 -16
- package/dist/semantic-rule-promotion.js +15 -15
- package/dist/semantic-rule-verifier.js +15 -15
- package/dist/source-agent-qualifier.js +18 -18
- package/dist/standup/build.js +15 -15
- package/dist/storage.js +14 -14
- package/dist/summarizer.js +3 -3
- package/dist/support-passport/index.js +3 -3
- package/dist/transfer/capsule-import.js +8 -8
- package/dist/transfer/export-okf.js +15 -15
- package/dist/verified-recall.js +15 -15
- package/dist/who-knows-cli.js +16 -16
- package/dist/who-knows.js +15 -15
- package/package.json +2 -2
- package/src/abstraction-nodes.ts +7 -2
- package/src/cue-anchors.ts +8 -3
- package/src/harmonic-graph-cache.test.ts +244 -0
- package/src/harmonic-graph-version.ts +46 -0
- package/src/harmonic-retrieval.ts +92 -2
- package/src/orchestration/extraction-persist-failure.test.ts +90 -0
- package/src/orchestration/extraction-persist-failure.ts +39 -1
- package/src/orchestration/extraction-persist.ts +29 -21
- package/src/orchestration/recall-internal.ts +1 -1
- package/src/orchestrator-persist-branch-failure.test.ts +271 -0
- package/dist/chunk-BPK32FRM.js.map +0 -1
- package/dist/chunk-F2XNSIPP.js.map +0 -1
- package/dist/chunk-LXATZLSC.js.map +0 -1
- /package/dist/{capsule-merge-6IDAYTKG.js.map → capsule-merge-ILR35DIB.js.map} +0 -0
- /package/dist/{chunk-QHARXWTC.js.map → chunk-2LCX6TAD.js.map} +0 -0
- /package/dist/{chunk-UN4RVUG2.js.map → chunk-2R3ACFYN.js.map} +0 -0
- /package/dist/{chunk-RQFXZYTF.js.map → chunk-33C4BK7I.js.map} +0 -0
- /package/dist/{chunk-UBEKET2V.js.map → chunk-3R63SXC5.js.map} +0 -0
- /package/dist/{chunk-LNGELD2M.js.map → chunk-3VWU3KF3.js.map} +0 -0
- /package/dist/{chunk-FWRXW7CZ.js.map → chunk-4CXK3GT3.js.map} +0 -0
- /package/dist/{chunk-DNY63QWJ.js.map → chunk-4HK7DYOL.js.map} +0 -0
- /package/dist/{chunk-LLPMMMWG.js.map → chunk-4IJFJQPD.js.map} +0 -0
- /package/dist/{chunk-GBJUTX44.js.map → chunk-4WKR4P7H.js.map} +0 -0
- /package/dist/{chunk-ILY5SSOM.js.map → chunk-53ZVHXVZ.js.map} +0 -0
- /package/dist/{chunk-FQAQ63QA.js.map → chunk-5AJIGWY4.js.map} +0 -0
- /package/dist/{chunk-CIWMTNHW.js.map → chunk-5NFF2TSD.js.map} +0 -0
- /package/dist/{chunk-D5XG2KPS.js.map → chunk-7E7J7QXB.js.map} +0 -0
- /package/dist/{chunk-2WCLTWV2.js.map → chunk-7NVK6AGC.js.map} +0 -0
- /package/dist/{chunk-PC5DRBGD.js.map → chunk-AP4BFWSW.js.map} +0 -0
- /package/dist/{chunk-CL4JU3DF.js.map → chunk-B7L4ZYFY.js.map} +0 -0
- /package/dist/{chunk-LQ5SS4OP.js.map → chunk-D6IGZYTN.js.map} +0 -0
- /package/dist/{chunk-XJ2S5UBF.js.map → chunk-DWWX3FU3.js.map} +0 -0
- /package/dist/{chunk-IL3RHBWM.js.map → chunk-EJ23D4JG.js.map} +0 -0
- /package/dist/{chunk-F4QFU5IZ.js.map → chunk-EZ7XJJ5L.js.map} +0 -0
- /package/dist/{chunk-FZZMLGWQ.js.map → chunk-F4BUSX3D.js.map} +0 -0
- /package/dist/{chunk-DPPLNZ3A.js.map → chunk-FM4P7HSW.js.map} +0 -0
- /package/dist/{chunk-QDESY76F.js.map → chunk-FQACH7MC.js.map} +0 -0
- /package/dist/{chunk-XPXHQI6N.js.map → chunk-FVMEZ57K.js.map} +0 -0
- /package/dist/{chunk-ZDV5YWID.js.map → chunk-GLDIMGOS.js.map} +0 -0
- /package/dist/{chunk-YIXJSW5M.js.map → chunk-HA5DASDG.js.map} +0 -0
- /package/dist/{chunk-S3S72HRM.js.map → chunk-HCCRWSP7.js.map} +0 -0
- /package/dist/{chunk-NMGHGTVR.js.map → chunk-HRMOKGQM.js.map} +0 -0
- /package/dist/{chunk-OUVYYKYU.js.map → chunk-IBKGQ6EY.js.map} +0 -0
- /package/dist/{chunk-RNG7S3FY.js.map → chunk-ICHLN5L6.js.map} +0 -0
- /package/dist/{chunk-R23JWJD3.js.map → chunk-J426U7XK.js.map} +0 -0
- /package/dist/{chunk-QMFAMOT2.js.map → chunk-JH5AV542.js.map} +0 -0
- /package/dist/{chunk-WGGRZYSQ.js.map → chunk-KE3JWIZK.js.map} +0 -0
- /package/dist/{chunk-SQ3GEIEL.js.map → chunk-KUQLUYIR.js.map} +0 -0
- /package/dist/{chunk-RKABLU5M.js.map → chunk-KVHGCISP.js.map} +0 -0
- /package/dist/{chunk-RUTN5MMC.js.map → chunk-LRLQ2PRP.js.map} +0 -0
- /package/dist/{chunk-X5HGU2EM.js.map → chunk-NT772J7I.js.map} +0 -0
- /package/dist/{chunk-4EZWSDFL.js.map → chunk-NX4XDDFQ.js.map} +0 -0
- /package/dist/{chunk-IAYUTGF2.js.map → chunk-O3GZPLVY.js.map} +0 -0
- /package/dist/{chunk-IGOW4TJE.js.map → chunk-O3JG4PD3.js.map} +0 -0
- /package/dist/{chunk-UHMHJX5G.js.map → chunk-OIG4ZFMB.js.map} +0 -0
- /package/dist/{chunk-IQ55QGY5.js.map → chunk-R4JYSBZE.js.map} +0 -0
- /package/dist/{chunk-Z3FTSHT5.js.map → chunk-RUQE5C32.js.map} +0 -0
- /package/dist/{chunk-ESLOLCD4.js.map → chunk-RUWKIPWJ.js.map} +0 -0
- /package/dist/{chunk-W54Z2MOP.js.map → chunk-RXSGBO7Y.js.map} +0 -0
- /package/dist/{chunk-BOK6BN5M.js.map → chunk-THV6PZ7V.js.map} +0 -0
- /package/dist/{chunk-J7BIFOYP.js.map → chunk-U6TC6Z5B.js.map} +0 -0
- /package/dist/{chunk-X2BVB74H.js.map → chunk-UZQXJDOE.js.map} +0 -0
- /package/dist/{chunk-SUTEBYGI.js.map → chunk-V7T45MI6.js.map} +0 -0
- /package/dist/{chunk-A4F7OIC5.js.map → chunk-WVIWDMFB.js.map} +0 -0
- /package/dist/{chunk-BN2EBCLB.js.map → chunk-XPCUKWLE.js.map} +0 -0
- /package/dist/{chunk-OJXK5C6Z.js.map → chunk-ZG4GNPRE.js.map} +0 -0
- /package/dist/{chunk-TYRWSE4B.js.map → chunk-ZUMHQEW4.js.map} +0 -0
- /package/dist/{chunk-DAOMWGO2.js.map → chunk-ZX5N5D6M.js.map} +0 -0
- /package/dist/{entity-canonical-id-migration-JJSTZF73.js.map → entity-canonical-id-migration-IG77BOGD.js.map} +0 -0
- /package/dist/{resolution-OVVIF7ZY.js.map → harmonic-graph-version.js.map} +0 -0
|
@@ -4,20 +4,20 @@ import {
|
|
|
4
4
|
exportOkfBundle,
|
|
5
5
|
firstHeading,
|
|
6
6
|
parseIncludeStatus
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-V7T45MI6.js";
|
|
8
8
|
import {
|
|
9
9
|
OKF_EXPORT_VERSION
|
|
10
10
|
} from "../chunk-I7TR2OCU.js";
|
|
11
11
|
import "../chunk-D24OXEPB.js";
|
|
12
12
|
import "../chunk-3UXOZBHV.js";
|
|
13
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-4CXK3GT3.js";
|
|
14
14
|
import "../chunk-QGVCFVX6.js";
|
|
15
15
|
import "../chunk-UHVXE24Y.js";
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-RFUL2ZIQ.js";
|
|
16
|
+
import "../chunk-O3JG4PD3.js";
|
|
18
17
|
import "../chunk-G6OFEGUR.js";
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
18
|
+
import "../chunk-RFUL2ZIQ.js";
|
|
19
|
+
import "../chunk-WVIWDMFB.js";
|
|
20
|
+
import "../chunk-FVMEZ57K.js";
|
|
21
21
|
import "../chunk-DOJBV6WR.js";
|
|
22
22
|
import "../chunk-PFUXPTBT.js";
|
|
23
23
|
import "../chunk-CYEPCZN5.js";
|
|
@@ -49,25 +49,20 @@ import "../chunk-3WU7XOFN.js";
|
|
|
49
49
|
import "../chunk-P4GUQSK3.js";
|
|
50
50
|
import "../chunk-4LZ7SVKM.js";
|
|
51
51
|
import "../chunk-YHTG64XV.js";
|
|
52
|
-
import "../chunk-
|
|
53
|
-
import "../chunk-
|
|
52
|
+
import "../chunk-KUQLUYIR.js";
|
|
53
|
+
import "../chunk-O3GZPLVY.js";
|
|
54
54
|
import "../chunk-5WITETWU.js";
|
|
55
|
-
import "../chunk-M5GVCJSJ.js";
|
|
56
|
-
import "../chunk-RBOJCG4T.js";
|
|
57
55
|
import "../chunk-6CIAGZ6X.js";
|
|
58
|
-
import "../chunk-7CT3AI52.js";
|
|
59
56
|
import "../chunk-G7D6GZ5J.js";
|
|
60
57
|
import "../chunk-7VLBZKNB.js";
|
|
61
58
|
import "../chunk-Y33KJ556.js";
|
|
62
|
-
import "../chunk-
|
|
59
|
+
import "../chunk-J426U7XK.js";
|
|
63
60
|
import "../chunk-NWA6IXR3.js";
|
|
61
|
+
import "../chunk-AF2XMJKD.js";
|
|
64
62
|
import "../chunk-OR42ZI54.js";
|
|
65
63
|
import "../chunk-IUM3VSHI.js";
|
|
66
64
|
import "../chunk-EZ47HOJ6.js";
|
|
67
|
-
import "../chunk-AF2XMJKD.js";
|
|
68
65
|
import "../chunk-23G5P7TA.js";
|
|
69
|
-
import "../chunk-C64XATK7.js";
|
|
70
|
-
import "../chunk-42JKGUFJ.js";
|
|
71
66
|
import "../chunk-MMRTPH3J.js";
|
|
72
67
|
import "../chunk-I55KAVET.js";
|
|
73
68
|
import "../chunk-L2EXJQJP.js";
|
|
@@ -111,6 +106,11 @@ import "../chunk-P7FMDTKL.js";
|
|
|
111
106
|
import "../chunk-X4OZMANG.js";
|
|
112
107
|
import "../chunk-ZEFVK7XC.js";
|
|
113
108
|
import "../chunk-R2MBW2S4.js";
|
|
109
|
+
import "../chunk-M5GVCJSJ.js";
|
|
110
|
+
import "../chunk-RBOJCG4T.js";
|
|
111
|
+
import "../chunk-7CT3AI52.js";
|
|
112
|
+
import "../chunk-C64XATK7.js";
|
|
113
|
+
import "../chunk-42JKGUFJ.js";
|
|
114
114
|
import "../chunk-QUIRIG2P.js";
|
|
115
115
|
import "../chunk-6KH5NLQS.js";
|
|
116
116
|
import "../chunk-P2QRMMVQ.js";
|
package/dist/verified-recall.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compareVerifiedEpisodeResults,
|
|
3
3
|
searchVerifiedEpisodes
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-53ZVHXVZ.js";
|
|
5
5
|
import "./chunk-B7RWBZXW.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-4CXK3GT3.js";
|
|
7
7
|
import "./chunk-QGVCFVX6.js";
|
|
8
8
|
import "./chunk-UHVXE24Y.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-RFUL2ZIQ.js";
|
|
9
|
+
import "./chunk-O3JG4PD3.js";
|
|
11
10
|
import "./chunk-G6OFEGUR.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-RFUL2ZIQ.js";
|
|
12
|
+
import "./chunk-WVIWDMFB.js";
|
|
13
|
+
import "./chunk-FVMEZ57K.js";
|
|
14
14
|
import "./chunk-DOJBV6WR.js";
|
|
15
15
|
import "./chunk-PFUXPTBT.js";
|
|
16
16
|
import "./chunk-CYEPCZN5.js";
|
|
@@ -42,25 +42,20 @@ import "./chunk-3WU7XOFN.js";
|
|
|
42
42
|
import "./chunk-P4GUQSK3.js";
|
|
43
43
|
import "./chunk-4LZ7SVKM.js";
|
|
44
44
|
import "./chunk-YHTG64XV.js";
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-KUQLUYIR.js";
|
|
46
|
+
import "./chunk-O3GZPLVY.js";
|
|
47
47
|
import "./chunk-5WITETWU.js";
|
|
48
|
-
import "./chunk-M5GVCJSJ.js";
|
|
49
|
-
import "./chunk-RBOJCG4T.js";
|
|
50
48
|
import "./chunk-6CIAGZ6X.js";
|
|
51
|
-
import "./chunk-7CT3AI52.js";
|
|
52
49
|
import "./chunk-G7D6GZ5J.js";
|
|
53
50
|
import "./chunk-7VLBZKNB.js";
|
|
54
51
|
import "./chunk-Y33KJ556.js";
|
|
55
|
-
import "./chunk-
|
|
52
|
+
import "./chunk-J426U7XK.js";
|
|
56
53
|
import "./chunk-NWA6IXR3.js";
|
|
54
|
+
import "./chunk-AF2XMJKD.js";
|
|
57
55
|
import "./chunk-OR42ZI54.js";
|
|
58
56
|
import "./chunk-IUM3VSHI.js";
|
|
59
57
|
import "./chunk-EZ47HOJ6.js";
|
|
60
|
-
import "./chunk-AF2XMJKD.js";
|
|
61
58
|
import "./chunk-23G5P7TA.js";
|
|
62
|
-
import "./chunk-C64XATK7.js";
|
|
63
|
-
import "./chunk-42JKGUFJ.js";
|
|
64
59
|
import "./chunk-MMRTPH3J.js";
|
|
65
60
|
import "./chunk-I55KAVET.js";
|
|
66
61
|
import "./chunk-L2EXJQJP.js";
|
|
@@ -104,6 +99,11 @@ import "./chunk-P7FMDTKL.js";
|
|
|
104
99
|
import "./chunk-X4OZMANG.js";
|
|
105
100
|
import "./chunk-ZEFVK7XC.js";
|
|
106
101
|
import "./chunk-R2MBW2S4.js";
|
|
102
|
+
import "./chunk-M5GVCJSJ.js";
|
|
103
|
+
import "./chunk-RBOJCG4T.js";
|
|
104
|
+
import "./chunk-7CT3AI52.js";
|
|
105
|
+
import "./chunk-C64XATK7.js";
|
|
106
|
+
import "./chunk-42JKGUFJ.js";
|
|
107
107
|
import "./chunk-QUIRIG2P.js";
|
|
108
108
|
import "./chunk-6KH5NLQS.js";
|
|
109
109
|
import "./chunk-P2QRMMVQ.js";
|
package/dist/who-knows-cli.js
CHANGED
|
@@ -4,16 +4,16 @@ import {
|
|
|
4
4
|
renderWhoKnows,
|
|
5
5
|
renderWhoKnowsJson,
|
|
6
6
|
renderWhoKnowsText
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-U6TC6Z5B.js";
|
|
8
|
+
import "./chunk-R4JYSBZE.js";
|
|
9
|
+
import "./chunk-4CXK3GT3.js";
|
|
10
10
|
import "./chunk-QGVCFVX6.js";
|
|
11
11
|
import "./chunk-UHVXE24Y.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-RFUL2ZIQ.js";
|
|
12
|
+
import "./chunk-O3JG4PD3.js";
|
|
14
13
|
import "./chunk-G6OFEGUR.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-RFUL2ZIQ.js";
|
|
15
|
+
import "./chunk-WVIWDMFB.js";
|
|
16
|
+
import "./chunk-FVMEZ57K.js";
|
|
17
17
|
import "./chunk-DOJBV6WR.js";
|
|
18
18
|
import "./chunk-PFUXPTBT.js";
|
|
19
19
|
import "./chunk-CYEPCZN5.js";
|
|
@@ -45,25 +45,20 @@ import "./chunk-3WU7XOFN.js";
|
|
|
45
45
|
import "./chunk-P4GUQSK3.js";
|
|
46
46
|
import "./chunk-4LZ7SVKM.js";
|
|
47
47
|
import "./chunk-YHTG64XV.js";
|
|
48
|
-
import "./chunk-
|
|
49
|
-
import "./chunk-
|
|
48
|
+
import "./chunk-KUQLUYIR.js";
|
|
49
|
+
import "./chunk-O3GZPLVY.js";
|
|
50
50
|
import "./chunk-5WITETWU.js";
|
|
51
|
-
import "./chunk-M5GVCJSJ.js";
|
|
52
|
-
import "./chunk-RBOJCG4T.js";
|
|
53
51
|
import "./chunk-6CIAGZ6X.js";
|
|
54
|
-
import "./chunk-7CT3AI52.js";
|
|
55
52
|
import "./chunk-G7D6GZ5J.js";
|
|
56
53
|
import "./chunk-7VLBZKNB.js";
|
|
57
54
|
import "./chunk-Y33KJ556.js";
|
|
58
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-J426U7XK.js";
|
|
59
56
|
import "./chunk-NWA6IXR3.js";
|
|
57
|
+
import "./chunk-AF2XMJKD.js";
|
|
60
58
|
import "./chunk-OR42ZI54.js";
|
|
61
59
|
import "./chunk-IUM3VSHI.js";
|
|
62
60
|
import "./chunk-EZ47HOJ6.js";
|
|
63
|
-
import "./chunk-AF2XMJKD.js";
|
|
64
61
|
import "./chunk-23G5P7TA.js";
|
|
65
|
-
import "./chunk-C64XATK7.js";
|
|
66
|
-
import "./chunk-42JKGUFJ.js";
|
|
67
62
|
import "./chunk-MMRTPH3J.js";
|
|
68
63
|
import "./chunk-I55KAVET.js";
|
|
69
64
|
import "./chunk-L2EXJQJP.js";
|
|
@@ -107,6 +102,11 @@ import "./chunk-P7FMDTKL.js";
|
|
|
107
102
|
import "./chunk-X4OZMANG.js";
|
|
108
103
|
import "./chunk-ZEFVK7XC.js";
|
|
109
104
|
import "./chunk-R2MBW2S4.js";
|
|
105
|
+
import "./chunk-M5GVCJSJ.js";
|
|
106
|
+
import "./chunk-RBOJCG4T.js";
|
|
107
|
+
import "./chunk-7CT3AI52.js";
|
|
108
|
+
import "./chunk-C64XATK7.js";
|
|
109
|
+
import "./chunk-42JKGUFJ.js";
|
|
110
110
|
import "./chunk-QUIRIG2P.js";
|
|
111
111
|
import "./chunk-6KH5NLQS.js";
|
|
112
112
|
import "./chunk-P2QRMMVQ.js";
|
package/dist/who-knows.js
CHANGED
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
loadWhoKnowsEntities,
|
|
10
10
|
tokenizeTopic,
|
|
11
11
|
validateWhoKnowsInput
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-R4JYSBZE.js";
|
|
13
|
+
import "./chunk-4CXK3GT3.js";
|
|
14
14
|
import "./chunk-QGVCFVX6.js";
|
|
15
15
|
import "./chunk-UHVXE24Y.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-RFUL2ZIQ.js";
|
|
16
|
+
import "./chunk-O3JG4PD3.js";
|
|
18
17
|
import "./chunk-G6OFEGUR.js";
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-RFUL2ZIQ.js";
|
|
19
|
+
import "./chunk-WVIWDMFB.js";
|
|
20
|
+
import "./chunk-FVMEZ57K.js";
|
|
21
21
|
import "./chunk-DOJBV6WR.js";
|
|
22
22
|
import "./chunk-PFUXPTBT.js";
|
|
23
23
|
import "./chunk-CYEPCZN5.js";
|
|
@@ -49,25 +49,20 @@ import "./chunk-3WU7XOFN.js";
|
|
|
49
49
|
import "./chunk-P4GUQSK3.js";
|
|
50
50
|
import "./chunk-4LZ7SVKM.js";
|
|
51
51
|
import "./chunk-YHTG64XV.js";
|
|
52
|
-
import "./chunk-
|
|
53
|
-
import "./chunk-
|
|
52
|
+
import "./chunk-KUQLUYIR.js";
|
|
53
|
+
import "./chunk-O3GZPLVY.js";
|
|
54
54
|
import "./chunk-5WITETWU.js";
|
|
55
|
-
import "./chunk-M5GVCJSJ.js";
|
|
56
|
-
import "./chunk-RBOJCG4T.js";
|
|
57
55
|
import "./chunk-6CIAGZ6X.js";
|
|
58
|
-
import "./chunk-7CT3AI52.js";
|
|
59
56
|
import "./chunk-G7D6GZ5J.js";
|
|
60
57
|
import "./chunk-7VLBZKNB.js";
|
|
61
58
|
import "./chunk-Y33KJ556.js";
|
|
62
|
-
import "./chunk-
|
|
59
|
+
import "./chunk-J426U7XK.js";
|
|
63
60
|
import "./chunk-NWA6IXR3.js";
|
|
61
|
+
import "./chunk-AF2XMJKD.js";
|
|
64
62
|
import "./chunk-OR42ZI54.js";
|
|
65
63
|
import "./chunk-IUM3VSHI.js";
|
|
66
64
|
import "./chunk-EZ47HOJ6.js";
|
|
67
|
-
import "./chunk-AF2XMJKD.js";
|
|
68
65
|
import "./chunk-23G5P7TA.js";
|
|
69
|
-
import "./chunk-C64XATK7.js";
|
|
70
|
-
import "./chunk-42JKGUFJ.js";
|
|
71
66
|
import "./chunk-MMRTPH3J.js";
|
|
72
67
|
import "./chunk-I55KAVET.js";
|
|
73
68
|
import "./chunk-L2EXJQJP.js";
|
|
@@ -111,6 +106,11 @@ import "./chunk-P7FMDTKL.js";
|
|
|
111
106
|
import "./chunk-X4OZMANG.js";
|
|
112
107
|
import "./chunk-ZEFVK7XC.js";
|
|
113
108
|
import "./chunk-R2MBW2S4.js";
|
|
109
|
+
import "./chunk-M5GVCJSJ.js";
|
|
110
|
+
import "./chunk-RBOJCG4T.js";
|
|
111
|
+
import "./chunk-7CT3AI52.js";
|
|
112
|
+
import "./chunk-C64XATK7.js";
|
|
113
|
+
import "./chunk-42JKGUFJ.js";
|
|
114
114
|
import "./chunk-QUIRIG2P.js";
|
|
115
115
|
import "./chunk-6KH5NLQS.js";
|
|
116
116
|
import "./chunk-P2QRMMVQ.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.96",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3386,7 +3386,7 @@
|
|
|
3386
3386
|
"core"
|
|
3387
3387
|
],
|
|
3388
3388
|
"peerDependencies": {
|
|
3389
|
-
"@remnic/coding-graph": "^10.0.
|
|
3389
|
+
"@remnic/coding-graph": "^10.0.96"
|
|
3390
3390
|
},
|
|
3391
3391
|
"peerDependenciesMeta": {
|
|
3392
3392
|
"@remnic/coding-graph": {
|
package/src/abstraction-nodes.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdir, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { listJsonFilesStrict, readJsonFile, withJsonStoreMutationLock, writeJsonFileAtomic } from "./json-store.js";
|
|
4
|
+
import { bumpHarmonicGraphVersion } from "./harmonic-graph-version.js";
|
|
4
5
|
import { compareDeterministicStrings, mergeSortedUniqueStrings } from "./deterministic-order.js";
|
|
5
6
|
import { isNotFoundError } from "./utils/errno.js";
|
|
6
7
|
import {
|
|
@@ -107,7 +108,11 @@ export async function recordAbstractionNode(options: {
|
|
|
107
108
|
const nodesDir = path.join(rootDir, "nodes", day);
|
|
108
109
|
const filePath = path.join(nodesDir, `${validated.nodeId}.json`);
|
|
109
110
|
await mkdir(nodesDir, { recursive: true });
|
|
110
|
-
|
|
111
|
+
try {
|
|
112
|
+
await writeFile(filePath, JSON.stringify(validated, null, 2), "utf8");
|
|
113
|
+
} finally {
|
|
114
|
+
bumpHarmonicGraphVersion(rootDir);
|
|
115
|
+
}
|
|
111
116
|
return filePath;
|
|
112
117
|
}
|
|
113
118
|
|
|
@@ -269,7 +274,7 @@ export async function upsertAbstractionNodes(options: {
|
|
|
269
274
|
filePaths.push(filePath);
|
|
270
275
|
}
|
|
271
276
|
return filePaths;
|
|
272
|
-
});
|
|
277
|
+
}).finally(() => bumpHarmonicGraphVersion(rootDir));
|
|
273
278
|
}
|
|
274
279
|
|
|
275
280
|
export async function upsertAbstractionNode(options: {
|
package/src/cue-anchors.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdir, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { resolveAbstractionNodeStoreDir, validateAbstractionNode, type AbstractionNode } from "./abstraction-nodes.js";
|
|
4
|
+
import { bumpHarmonicGraphVersion } from "./harmonic-graph-version.js";
|
|
4
5
|
import { listJsonFilesStrict, readJsonFile, withJsonStoreMutationLock, writeJsonFileAtomic } from "./json-store.js";
|
|
5
6
|
import { compareDeterministicStrings, mergeSortedUniqueStrings } from "./deterministic-order.js";
|
|
6
7
|
import { isNotFoundError } from "./utils/errno.js";
|
|
@@ -163,7 +164,11 @@ export async function recordCueAnchor(options: {
|
|
|
163
164
|
const anchorDir = path.join(rootDir, bounded.anchorType);
|
|
164
165
|
const filePath = path.join(anchorDir, `${bounded.anchorId}.json`);
|
|
165
166
|
await mkdir(anchorDir, { recursive: true });
|
|
166
|
-
|
|
167
|
+
try {
|
|
168
|
+
await writeFile(filePath, JSON.stringify(bounded, null, 2), "utf8");
|
|
169
|
+
} finally {
|
|
170
|
+
bumpHarmonicGraphVersion(abstractionNodeStoreDir);
|
|
171
|
+
}
|
|
167
172
|
return filePath;
|
|
168
173
|
}
|
|
169
174
|
|
|
@@ -247,7 +252,7 @@ export async function upsertCueAnchors(options: {
|
|
|
247
252
|
filePaths.push(filePath);
|
|
248
253
|
}
|
|
249
254
|
return filePaths;
|
|
250
|
-
});
|
|
255
|
+
}).finally(() => bumpHarmonicGraphVersion(abstractionNodeStoreDir));
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
function compareIncomingCueAnchors(left: CueAnchor, right: CueAnchor): number {
|
|
@@ -351,7 +356,7 @@ export async function pruneOrphanCueAnchors(options: {
|
|
|
351
356
|
}
|
|
352
357
|
}
|
|
353
358
|
return removed;
|
|
354
|
-
});
|
|
359
|
+
}).finally(() => bumpHarmonicGraphVersion(abstractionNodeStoreDir));
|
|
355
360
|
}
|
|
356
361
|
|
|
357
362
|
export async function getCueAnchorStoreStatus(options: {
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { recordAbstractionNode, upsertAbstractionNodes, type AbstractionNode } from "./abstraction-nodes.js";
|
|
7
|
+
import { pruneOrphanCueAnchors, recordCueAnchor, upsertCueAnchors, type CueAnchor } from "./cue-anchors.js";
|
|
8
|
+
import {
|
|
9
|
+
clearHarmonicGraphCache,
|
|
10
|
+
harmonicGraphCacheStats,
|
|
11
|
+
readProjectedHarmonicGraph,
|
|
12
|
+
searchHarmonicRetrieval,
|
|
13
|
+
} from "./harmonic-retrieval.js";
|
|
14
|
+
import { bumpMemoryCorpusVersionForDir } from "./memory-corpus-version.js";
|
|
15
|
+
import { StorageManager } from "./storage.js";
|
|
16
|
+
|
|
17
|
+
function node(nodeId: string, title: string, sourceMemoryIds: string[]): AbstractionNode {
|
|
18
|
+
return {
|
|
19
|
+
schemaVersion: 1,
|
|
20
|
+
nodeId,
|
|
21
|
+
recordedAt: new Date().toISOString(),
|
|
22
|
+
sessionKey: "agent:test",
|
|
23
|
+
kind: "topic",
|
|
24
|
+
abstractionLevel: "meso",
|
|
25
|
+
title,
|
|
26
|
+
summary: title,
|
|
27
|
+
sourceMemoryIds,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function withDir(run: (memoryDir: string, storage: StorageManager) => Promise<void>) {
|
|
32
|
+
const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-harmonic-cache-"));
|
|
33
|
+
clearHarmonicGraphCache();
|
|
34
|
+
try {
|
|
35
|
+
const storage = new StorageManager(memoryDir);
|
|
36
|
+
await storage.ensureDirectories();
|
|
37
|
+
await run(memoryDir, storage);
|
|
38
|
+
} finally {
|
|
39
|
+
clearHarmonicGraphCache();
|
|
40
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const read = (memoryDir: string, extra: { nowMs?: number } = {}) =>
|
|
45
|
+
readProjectedHarmonicGraph({ memoryDir, anchorsEnabled: true, useCache: true, ...extra });
|
|
46
|
+
|
|
47
|
+
test("a second cached read does no file reads", async () => {
|
|
48
|
+
await withDir(async (memoryDir, storage) => {
|
|
49
|
+
const first = await storage.writeMemory("fact", "cache source one", { source: "test" });
|
|
50
|
+
const nodeFile = await recordAbstractionNode({ memoryDir, node: node("n1", "cache source one", [first.id]) });
|
|
51
|
+
const before = { ...harmonicGraphCacheStats };
|
|
52
|
+
const a = await read(memoryDir);
|
|
53
|
+
assert.equal(a.nodes.length, 1);
|
|
54
|
+
assert.equal(harmonicGraphCacheStats.misses, before.misses + 1);
|
|
55
|
+
// Remove every file the projection reads. A real read would now return nothing.
|
|
56
|
+
await rm(nodeFile, { force: true });
|
|
57
|
+
await rm((await storage.getMemoryById(first.id))!.path, { force: true });
|
|
58
|
+
const b = await read(memoryDir);
|
|
59
|
+
assert.equal(harmonicGraphCacheStats.hits, before.hits + 1);
|
|
60
|
+
assert.equal(b, a);
|
|
61
|
+
assert.equal(b.nodes.length, 1);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("a recall after a new memory is saved sees it", async () => {
|
|
66
|
+
await withDir(async (memoryDir, storage) => {
|
|
67
|
+
const first = await storage.writeMemory("fact", "alpha harmonic", { source: "test" });
|
|
68
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "alpha harmonic", [first.id]) });
|
|
69
|
+
const hits = () => harmonicGraphCacheStats.hits;
|
|
70
|
+
const query = { memoryDir, query: "bravo cache", maxResults: 3, anchorsEnabled: true, useGraphCache: true };
|
|
71
|
+
assert.equal((await searchHarmonicRetrieval(query)).length, 0);
|
|
72
|
+
const h = hits();
|
|
73
|
+
assert.equal((await searchHarmonicRetrieval(query)).length, 0);
|
|
74
|
+
assert.equal(hits(), h + 1);
|
|
75
|
+
|
|
76
|
+
const second = await storage.writeMemory("fact", "bravo cache", { source: "test" });
|
|
77
|
+
await recordAbstractionNode({ memoryDir, node: node("n2", "bravo cache", [second.id]) });
|
|
78
|
+
const results = await searchHarmonicRetrieval(query);
|
|
79
|
+
assert.deepEqual(results.map((result) => result.node.nodeId), ["n2"]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("an out-of-band corpus bump invalidates, so a source that leaves the active set drops out", async () => {
|
|
84
|
+
await withDir(async (memoryDir, storage) => {
|
|
85
|
+
const memory = await storage.writeMemory("fact", "gamma status fact", { source: "test" });
|
|
86
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "gamma status fact", [memory.id]) });
|
|
87
|
+
assert.equal((await read(memoryDir)).nodes.length, 1);
|
|
88
|
+
const memoryPath = (await storage.getMemoryById(memory.id))!.path;
|
|
89
|
+
await writeFile(
|
|
90
|
+
memoryPath,
|
|
91
|
+
(await readFile(memoryPath, "utf8")).replace("category: fact", "category: fact\nstatus: quarantined"),
|
|
92
|
+
);
|
|
93
|
+
// The documented out-of-band bump: the same call review and governance writers make.
|
|
94
|
+
bumpMemoryCorpusVersionForDir(memoryDir);
|
|
95
|
+
assert.equal((await read(memoryDir)).nodes.length, 0);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("an explicit nowMs bypasses the cache", async () => {
|
|
100
|
+
await withDir(async (memoryDir, storage) => {
|
|
101
|
+
const memory = await storage.writeMemory("fact", "delta bypass fact", { source: "test" });
|
|
102
|
+
const nodeFile = await recordAbstractionNode({ memoryDir, node: node("n1", "delta bypass fact", [memory.id]) });
|
|
103
|
+
assert.equal((await read(memoryDir)).nodes.length, 1);
|
|
104
|
+
await rm(nodeFile, { force: true });
|
|
105
|
+
assert.equal((await read(memoryDir, { nowMs: Date.now() })).nodes.length, 0);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("cached arrays are frozen", async () => {
|
|
110
|
+
await withDir(async (memoryDir, storage) => {
|
|
111
|
+
const memory = await storage.writeMemory("fact", "epsilon frozen fact", { source: "test" });
|
|
112
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "epsilon frozen fact", [memory.id]) });
|
|
113
|
+
const graph = await read(memoryDir);
|
|
114
|
+
assert.throws(() => graph.nodes.push(node("x", "x", [])), TypeError);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("cached node records are deep frozen, so a caller cannot change later reads", async () => {
|
|
119
|
+
await withDir(async (memoryDir, storage) => {
|
|
120
|
+
const memory = await storage.writeMemory("fact", "zeta deep frozen fact", { source: "test" });
|
|
121
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "zeta deep frozen fact", [memory.id]) });
|
|
122
|
+
const graph = await read(memoryDir);
|
|
123
|
+
const cached = graph.nodes[0]!;
|
|
124
|
+
assert.throws(() => { cached.title = "changed"; }, TypeError);
|
|
125
|
+
assert.throws(() => cached.sourceMemoryIds?.push("x"), TypeError);
|
|
126
|
+
assert.equal((await read(memoryDir)).nodes[0]!.title, "zeta deep frozen fact");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("an aborted signal rejects even when the graph is cached", async () => {
|
|
131
|
+
await withDir(async (memoryDir, storage) => {
|
|
132
|
+
const memory = await storage.writeMemory("fact", "eta abort fact", { source: "test" });
|
|
133
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "eta abort fact", [memory.id]) });
|
|
134
|
+
await read(memoryDir);
|
|
135
|
+
const controller = new AbortController();
|
|
136
|
+
controller.abort();
|
|
137
|
+
await assert.rejects(
|
|
138
|
+
readProjectedHarmonicGraph({ memoryDir, anchorsEnabled: true, useCache: true, abortSignal: controller.signal }),
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
function anchor(anchorId: string, nodeRef: string, memoryId: string): CueAnchor {
|
|
144
|
+
return {
|
|
145
|
+
schemaVersion: 1,
|
|
146
|
+
anchorId,
|
|
147
|
+
anchorType: "entity",
|
|
148
|
+
anchorValue: anchorId,
|
|
149
|
+
normalizedCue: anchorId,
|
|
150
|
+
recordedAt: new Date().toISOString(),
|
|
151
|
+
sessionKey: "agent:test",
|
|
152
|
+
nodeRefs: [nodeRef],
|
|
153
|
+
sourceMemoryIdsByNodeRef: { [nodeRef]: [memoryId] },
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Each case seeds node n1 (source m1) and, for the anchor cases, anchor a1, fills the cache, then runs ONE
|
|
158
|
+
// store write with no memory write after it. The next read must miss and show the new count; with the
|
|
159
|
+
// graph version bump removed these fail because the corpus sentinels never move.
|
|
160
|
+
async function seedForWrite(memoryDir: string, storage: StorageManager) {
|
|
161
|
+
const m1 = await storage.writeMemory("fact", "seed one", { source: "test" });
|
|
162
|
+
const m2 = await storage.writeMemory("fact", "seed two", { source: "test" });
|
|
163
|
+
await recordAbstractionNode({ memoryDir, node: node("n1", "seed one", [m1.id]) });
|
|
164
|
+
await recordAbstractionNode({ memoryDir, node: node("n2", "seed two", [m2.id]) });
|
|
165
|
+
await recordCueAnchor({ memoryDir, anchor: anchor("a1", "n1", m1.id) });
|
|
166
|
+
return { m1, m2 };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function counts(memoryDir: string) {
|
|
170
|
+
const graph = await read(memoryDir);
|
|
171
|
+
return { nodes: graph.nodes.length, anchors: graph.anchors.length };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const storeWrites: Array<{
|
|
175
|
+
name: string;
|
|
176
|
+
write: (memoryDir: string, ids: { m1: string; m2: string }) => Promise<void>;
|
|
177
|
+
expected: { nodes: number; anchors: number };
|
|
178
|
+
}> = [
|
|
179
|
+
{
|
|
180
|
+
name: "recordAbstractionNode",
|
|
181
|
+
write: async (memoryDir, ids) => { await recordAbstractionNode({ memoryDir, node: node("n3", "seed three", [ids.m1]) }); },
|
|
182
|
+
expected: { nodes: 3, anchors: 1 },
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "upsertAbstractionNodes",
|
|
186
|
+
write: async (memoryDir, ids) => { await upsertAbstractionNodes({ memoryDir, nodes: [node("n3", "seed three", [ids.m1])] }); },
|
|
187
|
+
expected: { nodes: 3, anchors: 1 },
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "recordCueAnchor",
|
|
191
|
+
write: async (memoryDir, ids) => { await recordCueAnchor({ memoryDir, anchor: anchor("a2", "n2", ids.m2) }); },
|
|
192
|
+
expected: { nodes: 2, anchors: 2 },
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "upsertCueAnchors",
|
|
196
|
+
write: async (memoryDir, ids) => { await upsertCueAnchors({ memoryDir, anchors: [anchor("a2", "n2", ids.m2)] }); },
|
|
197
|
+
expected: { nodes: 2, anchors: 2 },
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
for (const { name, write, expected } of storeWrites) {
|
|
202
|
+
test(`${name} alone invalidates the cached graph`, async () => {
|
|
203
|
+
await withDir(async (memoryDir, storage) => {
|
|
204
|
+
const { m1, m2 } = await seedForWrite(memoryDir, storage);
|
|
205
|
+
assert.deepEqual(await counts(memoryDir), { nodes: 2, anchors: 1 });
|
|
206
|
+
const hitsBefore = harmonicGraphCacheStats.hits;
|
|
207
|
+
assert.deepEqual(await counts(memoryDir), { nodes: 2, anchors: 1 });
|
|
208
|
+
assert.equal(harmonicGraphCacheStats.hits, hitsBefore + 1);
|
|
209
|
+
|
|
210
|
+
await write(memoryDir, { m1: m1.id, m2: m2.id });
|
|
211
|
+
const missesBefore = harmonicGraphCacheStats.misses;
|
|
212
|
+
assert.deepEqual(await counts(memoryDir), expected);
|
|
213
|
+
assert.equal(harmonicGraphCacheStats.misses, missesBefore + 1);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
test("pruneOrphanCueAnchors alone invalidates the cached graph", async () => {
|
|
219
|
+
await withDir(async (memoryDir, storage) => {
|
|
220
|
+
const { m2 } = await seedForWrite(memoryDir, storage);
|
|
221
|
+
await recordCueAnchor({ memoryDir, anchor: anchor("a2", "n2", m2.id) });
|
|
222
|
+
assert.deepEqual(await counts(memoryDir), { nodes: 2, anchors: 2 });
|
|
223
|
+
// n2's file goes away behind the cache's back, which makes a2 an orphan. Only the prune below bumps.
|
|
224
|
+
await rm(path.join(memoryDir, "state", "abstraction-nodes", "nodes", new Date().toISOString().slice(0, 10), "n2.json"), { force: true });
|
|
225
|
+
assert.deepEqual(await counts(memoryDir), { nodes: 2, anchors: 2 });
|
|
226
|
+
assert.equal(await pruneOrphanCueAnchors({ memoryDir }), 1);
|
|
227
|
+
assert.deepEqual(await counts(memoryDir), { nodes: 1, anchors: 1 });
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test("an entry older than the TTL is rebuilt", async (t) => {
|
|
232
|
+
await withDir(async (memoryDir, storage) => {
|
|
233
|
+
const memory = await storage.writeMemory("fact", "zeta ttl fact", { source: "test" });
|
|
234
|
+
const nodeFile = await recordAbstractionNode({ memoryDir, node: node("n1", "zeta ttl fact", [memory.id]) });
|
|
235
|
+
const start = Date.now();
|
|
236
|
+
const clock = t.mock.method(Date, "now", () => start);
|
|
237
|
+
assert.equal((await read(memoryDir)).nodes.length, 1);
|
|
238
|
+
await rm(nodeFile, { force: true });
|
|
239
|
+
clock.mock.mockImplementation(() => start + 29_000);
|
|
240
|
+
assert.equal((await read(memoryDir)).nodes.length, 1, "still cached inside the TTL");
|
|
241
|
+
clock.mock.mockImplementation(() => start + 31_000);
|
|
242
|
+
assert.equal((await read(memoryDir)).nodes.length, 0, "rebuilt past the TTL");
|
|
243
|
+
});
|
|
244
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync, statSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { MEMORY_CORPUS_VERSION_SENTINEL } from "./memory-corpus-version.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Append-only sentinel in the abstraction node store root. The byte size is the
|
|
7
|
+
* version of the node and cue anchor stores, the same scheme the memory corpus
|
|
8
|
+
* sentinel uses, so a bump in one process is seen by every other process.
|
|
9
|
+
*/
|
|
10
|
+
export const HARMONIC_GRAPH_VERSION_SENTINEL = ".harmonic-graph-version.log";
|
|
11
|
+
|
|
12
|
+
// Names must match StorageManager.versionFilePath("memory-status" | "cold-write").
|
|
13
|
+
const MEMORY_STATUS_VERSION_SENTINEL = ".memory-status-version.log";
|
|
14
|
+
const COLD_WRITE_VERSION_SENTINEL = ".cold-write-version.log";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Record that a node or cue anchor was written. Fail-open: a failed bump must not
|
|
18
|
+
* fail the write; the harmonic graph cache TTL bounds the stale window.
|
|
19
|
+
*/
|
|
20
|
+
export function bumpHarmonicGraphVersion(abstractionNodeStoreDir: string): void {
|
|
21
|
+
try {
|
|
22
|
+
mkdirSync(abstractionNodeStoreDir, { recursive: true });
|
|
23
|
+
appendFileSync(path.join(abstractionNodeStoreDir, HARMONIC_GRAPH_VERSION_SENTINEL), "x");
|
|
24
|
+
} catch {
|
|
25
|
+
/* fail-open */
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function sentinelSize(filePath: string): number {
|
|
30
|
+
try {
|
|
31
|
+
return statSync(filePath).size;
|
|
32
|
+
} catch {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Four stats; changes whenever a memory, a node or a cue anchor is written. */
|
|
38
|
+
export function readHarmonicGraphStamp(memoryDir: string, abstractionNodeStoreDir: string): string {
|
|
39
|
+
const stateDir = path.join(memoryDir, "state");
|
|
40
|
+
return [
|
|
41
|
+
sentinelSize(path.join(stateDir, MEMORY_CORPUS_VERSION_SENTINEL)),
|
|
42
|
+
sentinelSize(path.join(stateDir, MEMORY_STATUS_VERSION_SENTINEL)),
|
|
43
|
+
sentinelSize(path.join(stateDir, COLD_WRITE_VERSION_SENTINEL)),
|
|
44
|
+
sentinelSize(path.join(abstractionNodeStoreDir, HARMONIC_GRAPH_VERSION_SENTINEL)),
|
|
45
|
+
].join(":");
|
|
46
|
+
}
|