@remnic/core 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abort-error.js +1 -0
- package/dist/abstraction-nodes.js +1 -0
- package/dist/access-audit.js +1 -0
- package/dist/access-cli.js +70 -45
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +50 -5
- package/dist/access-http.js +37 -15
- package/dist/access-idempotency.js +1 -0
- package/dist/access-mcp.d.ts +10 -5
- package/dist/access-mcp.js +36 -13
- package/dist/access-schema.d.ts +133 -13
- package/dist/access-schema.js +20 -1
- package/dist/access-service-_AEUMVyX.d.ts +1981 -0
- package/dist/access-service.d.ts +11 -6
- package/dist/access-service.js +38 -14
- package/dist/active-memory-bridge.js +1 -0
- package/dist/active-recall.js +1 -0
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.js +1 -0
- package/dist/behavior-learner.js.map +1 -1
- package/dist/behavior-signals.js +1 -0
- package/dist/bootstrap.d.ts +6 -4
- package/dist/bootstrap.js +1 -0
- package/dist/boxes.js +1 -0
- package/dist/briefing.d.ts +9 -5
- package/dist/briefing.js +9 -6
- package/dist/buffer-surprise-report.js +1 -0
- package/dist/buffer-surprise.js +1 -0
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -0
- package/dist/calibration.d.ts +8 -1
- package/dist/calibration.js +10 -2
- package/dist/calibration.js.map +1 -1
- package/dist/capsule-cli.d.ts +137 -0
- package/dist/capsule-cli.js +34 -0
- package/dist/capsule-crypto-5CYAGVC5.js +18 -0
- package/dist/capsule-export-NZQPOTQ4.js +17 -0
- package/dist/capsule-export-NZQPOTQ4.js.map +1 -0
- package/dist/capsule-import-SDCUXLEV.js +16 -0
- package/dist/capsule-import-SDCUXLEV.js.map +1 -0
- package/dist/capsule-merge-DI7PNQ2H.js +189 -0
- package/dist/capsule-merge-DI7PNQ2H.js.map +1 -0
- package/dist/causal-behavior.js +1 -0
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +1 -0
- package/dist/causal-consolidation.js +11 -8
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -1
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.js +4 -1
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +2 -1
- package/dist/chunk-2LSZVONP.js +67 -0
- package/dist/chunk-2LSZVONP.js.map +1 -0
- package/dist/chunk-32KD5IHZ.js +245 -0
- package/dist/chunk-32KD5IHZ.js.map +1 -0
- package/dist/{chunk-VDX363PS.js → chunk-34F3PLWZ.js} +10 -3
- package/dist/chunk-34F3PLWZ.js.map +1 -0
- package/dist/chunk-3KIS4VGT.js +228 -0
- package/dist/chunk-3KIS4VGT.js.map +1 -0
- package/dist/chunk-3LCWFNVS.js +350 -0
- package/dist/chunk-3LCWFNVS.js.map +1 -0
- package/dist/chunk-43EKP2UK.js +26 -0
- package/dist/chunk-43EKP2UK.js.map +1 -0
- package/dist/chunk-457A4P3L.js +119 -0
- package/dist/chunk-457A4P3L.js.map +1 -0
- package/dist/{chunk-TMYO7B5P.js → chunk-47WOM4YW.js} +2 -2
- package/dist/{chunk-OC5OXUQ4.js → chunk-4PLGJRBV.js} +653 -17
- package/dist/chunk-4PLGJRBV.js.map +1 -0
- package/dist/{chunk-PVICZTKG.js → chunk-55FXRRSJ.js} +5 -5
- package/dist/{chunk-PVICZTKG.js.map → chunk-55FXRRSJ.js.map} +1 -1
- package/dist/{chunk-ULYOGL6R.js → chunk-5HRY2WRF.js} +7 -3
- package/dist/chunk-5HRY2WRF.js.map +1 -0
- package/dist/chunk-6TBWYBJ3.js +236 -0
- package/dist/chunk-6TBWYBJ3.js.map +1 -0
- package/dist/chunk-74EMIVE4.js +329 -0
- package/dist/chunk-74EMIVE4.js.map +1 -0
- package/dist/chunk-74WWN7ZW.js +82 -0
- package/dist/chunk-74WWN7ZW.js.map +1 -0
- package/dist/{chunk-6YJHX2DL.js → chunk-7GCMLT7J.js} +242 -22
- package/dist/chunk-7GCMLT7J.js.map +1 -0
- package/dist/chunk-A6XUJE5D.js +126 -0
- package/dist/chunk-A6XUJE5D.js.map +1 -0
- package/dist/chunk-AJA46VX5.js +393 -0
- package/dist/chunk-AJA46VX5.js.map +1 -0
- package/dist/{chunk-UWB5LMWY.js → chunk-AKUCB2OG.js} +525 -24
- package/dist/chunk-AKUCB2OG.js.map +1 -0
- package/dist/chunk-ASIQZXYO.js +277 -0
- package/dist/chunk-ASIQZXYO.js.map +1 -0
- package/dist/{chunk-DG6YMRDC.js → chunk-B2TL6GA2.js} +2 -2
- package/dist/chunk-BJMBJZ2Y.js +290 -0
- package/dist/chunk-BJMBJZ2Y.js.map +1 -0
- package/dist/chunk-BT7NVCML.js +79 -0
- package/dist/chunk-BT7NVCML.js.map +1 -0
- package/dist/chunk-CK5NTM2S.js +454 -0
- package/dist/chunk-CK5NTM2S.js.map +1 -0
- package/dist/{chunk-AYXIPSZO.js → chunk-CRU27Q4J.js} +2 -2
- package/dist/{chunk-F5VP6YCB.js → chunk-DCE6SQLA.js} +572 -155
- package/dist/chunk-DCE6SQLA.js.map +1 -0
- package/dist/{chunk-CUPFXL3J.js → chunk-DHRQHX36.js} +4 -4
- package/dist/chunk-DHRQHX36.js.map +1 -0
- package/dist/{chunk-STGWEHYR.js → chunk-DR7MCMPS.js} +981 -61
- package/dist/chunk-DR7MCMPS.js.map +1 -0
- package/dist/chunk-FP2373TW.js +149 -0
- package/dist/chunk-FP2373TW.js.map +1 -0
- package/dist/{chunk-RBBWYEFJ.js → chunk-G2WADRQ3.js} +1 -1
- package/dist/chunk-G7D6GZ5J.js +48 -0
- package/dist/chunk-G7D6GZ5J.js.map +1 -0
- package/dist/chunk-H7XKCNR6.js +60 -0
- package/dist/chunk-H7XKCNR6.js.map +1 -0
- package/dist/{chunk-3YGHKTBF.js → chunk-IM3JSE73.js} +953 -322
- package/dist/chunk-IM3JSE73.js.map +1 -0
- package/dist/chunk-IXEJRKCZ.js +18 -0
- package/dist/chunk-IXEJRKCZ.js.map +1 -0
- package/dist/chunk-IYY4MCPG.js +275 -0
- package/dist/chunk-IYY4MCPG.js.map +1 -0
- package/dist/{chunk-BECYBZLX.js → chunk-JWSENLQI.js} +502 -22
- package/dist/chunk-JWSENLQI.js.map +1 -0
- package/dist/chunk-KNKUID7G.js +183 -0
- package/dist/chunk-KNKUID7G.js.map +1 -0
- package/dist/chunk-L2IO2QPY.js +2036 -0
- package/dist/chunk-L2IO2QPY.js.map +1 -0
- package/dist/{chunk-SPI27QT6.js → chunk-L5IIGA5V.js} +9 -4
- package/dist/chunk-L5IIGA5V.js.map +1 -0
- package/dist/{chunk-XXVWLXSG.js → chunk-LVYGDT5V.js} +56 -82
- package/dist/chunk-LVYGDT5V.js.map +1 -0
- package/dist/{chunk-ZAIM4TUE.js → chunk-LW2NMHDW.js} +46 -1
- package/dist/chunk-LW2NMHDW.js.map +1 -0
- package/dist/{chunk-3OGMS3PE.js → chunk-LZRYQK6L.js} +3 -2
- package/dist/chunk-LZRYQK6L.js.map +1 -0
- package/dist/chunk-MDYG7VI7.js +48 -0
- package/dist/chunk-MDYG7VI7.js.map +1 -0
- package/dist/chunk-MXC3AP5I.js +74 -0
- package/dist/chunk-MXC3AP5I.js.map +1 -0
- package/dist/{chunk-DIXB44VE.js → chunk-N7X62G74.js} +25 -10
- package/dist/chunk-N7X62G74.js.map +1 -0
- package/dist/chunk-NN3TS5BM.js +147 -0
- package/dist/chunk-NN3TS5BM.js.map +1 -0
- package/dist/chunk-OA3L7BFR.js +183 -0
- package/dist/chunk-OA3L7BFR.js.map +1 -0
- package/dist/chunk-OZHRDTDX.js +240 -0
- package/dist/chunk-OZHRDTDX.js.map +1 -0
- package/dist/chunk-PCUKNJAZ.js +165 -0
- package/dist/chunk-PCUKNJAZ.js.map +1 -0
- package/dist/{chunk-6PFRXT4K.js → chunk-PFV5C235.js} +11 -6
- package/dist/chunk-PFV5C235.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/{chunk-Y7R2XJ5Q.js → chunk-Q7FJ5ZHM.js} +6 -2
- package/dist/chunk-Q7FJ5ZHM.js.map +1 -0
- package/dist/{chunk-NBVAS5MT.js → chunk-R2L7SUX2.js} +6 -6
- package/dist/{chunk-WCLICCGB.js → chunk-RILIVK4O.js} +91 -4
- package/dist/chunk-RILIVK4O.js.map +1 -0
- package/dist/{chunk-C2EFFULQ.js → chunk-RK2Y4XOM.js} +163 -20
- package/dist/chunk-RK2Y4XOM.js.map +1 -0
- package/dist/{chunk-TP4FZJIZ.js → chunk-RULE4VG5.js} +5 -1
- package/dist/chunk-RULE4VG5.js.map +1 -0
- package/dist/{chunk-PVPWZSSI.js → chunk-SMA4IMHV.js} +19 -3
- package/dist/chunk-SMA4IMHV.js.map +1 -0
- package/dist/{chunk-L7IXWRYE.js → chunk-SS253RXF.js} +22 -13
- package/dist/chunk-SS253RXF.js.map +1 -0
- package/dist/chunk-TUFG6VXY.js +875 -0
- package/dist/chunk-TUFG6VXY.js.map +1 -0
- package/dist/chunk-TYEOAFH3.js +251 -0
- package/dist/chunk-TYEOAFH3.js.map +1 -0
- package/dist/chunk-UKJAGEXH.js +260 -0
- package/dist/chunk-UKJAGEXH.js.map +1 -0
- package/dist/{chunk-KVBLZUKV.js → chunk-USFPPRAF.js} +93 -3
- package/dist/chunk-USFPPRAF.js.map +1 -0
- package/dist/{chunk-GA5P7RST.js → chunk-VTJVUHRK.js} +22 -36
- package/dist/chunk-VTJVUHRK.js.map +1 -0
- package/dist/chunk-WIICJPET.js +45 -0
- package/dist/chunk-WIICJPET.js.map +1 -0
- package/dist/{chunk-VBVG2M5G.js → chunk-WPGJYVUH.js} +6 -2
- package/dist/chunk-WPGJYVUH.js.map +1 -0
- package/dist/{chunk-4HQS2HPX.js → chunk-WSZIHQBK.js} +29 -9
- package/dist/{chunk-4HQS2HPX.js.map → chunk-WSZIHQBK.js.map} +1 -1
- package/dist/{chunk-NZLQTHS5.js → chunk-WW3QQF4H.js} +4 -1
- package/dist/chunk-WW3QQF4H.js.map +1 -0
- package/dist/{chunk-FVA6TGI3.js → chunk-Y3WQ4ZWK.js} +42 -2
- package/dist/chunk-Y3WQ4ZWK.js.map +1 -0
- package/dist/chunk-YNJHCGDT.js +309 -0
- package/dist/chunk-YNJHCGDT.js.map +1 -0
- package/dist/{chunk-LOIMBRDE.js → chunk-ZGXSCMQN.js} +1993 -411
- package/dist/chunk-ZGXSCMQN.js.map +1 -0
- package/dist/{chunk-W6SL7OFG.js → chunk-ZTSE2ZJ6.js} +12 -2
- package/dist/{chunk-W6SL7OFG.js.map → chunk-ZTSE2ZJ6.js.map} +1 -1
- package/dist/chunking.js +1 -0
- package/dist/cipher-GVE2GQ5H.js +28 -0
- package/dist/cipher-GVE2GQ5H.js.map +1 -0
- package/dist/citations.js +1 -0
- package/dist/{cli-BkeRaYfk.d.ts → cli-x2APT9a6.d.ts} +26 -7
- package/dist/cli.d.ts +11 -6
- package/dist/cli.js +67 -33
- package/dist/codex-thread-key.js +1 -0
- package/dist/commitment-ledger.js +1 -0
- package/dist/compression-optimizer.js +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.js +4 -1
- package/dist/connectors-cli-DFGtY2DB.d.ts +257 -0
- package/dist/connectors-cli.d.ts +2 -0
- package/dist/connectors-cli.js +22 -0
- package/dist/connectors-cli.js.map +1 -0
- package/dist/consolidation-operator.d.ts +65 -5
- package/dist/consolidation-operator.js +6 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-provenance-check.js +3 -2
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/consolidation-undo.js +1 -0
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/{contradiction-review-WIUBAR52.js → contradiction-review-5LTTVDQV.js} +2 -1
- package/dist/contradiction-review-5LTTVDQV.js.map +1 -0
- package/dist/{contradiction-scan-E3GJTI4F.js → contradiction-scan-3Z6YW7YA.js} +2 -1
- package/dist/{contradiction-scan-E3GJTI4F.js.map → contradiction-scan-3Z6YW7YA.js.map} +1 -1
- package/dist/cross-namespace-budget.js +1 -0
- package/dist/cue-anchors.js +1 -0
- package/dist/dashboard-runtime.js +1 -0
- package/dist/day-summary.js +1 -0
- package/dist/delinearize.js +1 -0
- package/dist/direct-answer-wiring.js +1 -0
- package/dist/direct-answer.js +1 -0
- package/dist/dreams-ledger-LR2NBAZE.js +286 -0
- package/dist/dreams-ledger-LR2NBAZE.js.map +1 -0
- package/dist/embedding-fallback.js +1 -0
- package/dist/{engine-72LSIWQP.js → engine-ICC2DSQF.js} +10 -7
- package/dist/engine-ICC2DSQF.js.map +1 -0
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +9 -6
- package/dist/entity-schema.js +1 -0
- package/dist/evals.js +1 -0
- package/dist/evidence-pack.d.ts +16 -0
- package/dist/evidence-pack.js +8 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/explicit-capture.d.ts +6 -4
- package/dist/explicit-capture.js +1 -0
- package/dist/extraction-judge-telemetry.js +1 -0
- package/dist/extraction-judge-training.js +1 -0
- package/dist/extraction-judge.js +1 -0
- package/dist/extraction.js +7 -6
- package/dist/fallback-llm.js +3 -2
- package/dist/first-start-migration-4MHQEOSD.js +263 -0
- package/dist/first-start-migration-4MHQEOSD.js.map +1 -0
- package/dist/forget-PLR6J5DN.js +69 -0
- package/dist/forget-PLR6J5DN.js.map +1 -0
- package/dist/framework-CyHYDcri.d.ts +153 -0
- package/dist/fs-utils-IRVUFB6G.js +30 -0
- package/dist/fs-utils-IRVUFB6G.js.map +1 -0
- package/dist/graph-dashboard-diff.js +1 -0
- package/dist/graph-dashboard-key.js +1 -0
- package/dist/graph-dashboard-parser.js +1 -0
- package/dist/graph-edge-decay-PWB63GRE.js +207 -0
- package/dist/graph-edge-decay-PWB63GRE.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +81 -0
- package/dist/graph-edge-reinforcement.js +24 -0
- package/dist/graph-edge-reinforcement.js.map +1 -0
- package/dist/graph-events.d.ts +87 -0
- package/dist/graph-events.js +14 -0
- package/dist/graph-events.js.map +1 -0
- package/dist/graph-recall.js +1 -0
- package/dist/graph-retrieval.js +1 -0
- package/dist/graph-snapshot.d.ts +112 -0
- package/dist/graph-snapshot.js +19 -0
- package/dist/graph-snapshot.js.map +1 -0
- package/dist/graph.d.ts +105 -7
- package/dist/graph.js +20 -3
- package/dist/harmonic-retrieval.js +1 -0
- package/dist/himem.js +1 -0
- package/dist/hygiene.js +1 -0
- package/dist/identity-continuity.js +1 -0
- package/dist/importance.js +1 -0
- package/dist/index.d.ts +562 -13
- package/dist/index.js +329 -67
- package/dist/index.js.map +1 -1
- package/dist/intent.js +1 -0
- package/dist/json-extract.js +1 -0
- package/dist/json-store.js +1 -0
- package/dist/kdf-7S6RWKLZ.js +26 -0
- package/dist/kdf-7S6RWKLZ.js.map +1 -0
- package/dist/legacy-hook-compat.js +1 -0
- package/dist/legacy-hook-compat.js.map +1 -1
- package/dist/lifecycle.js +1 -0
- package/dist/live-connectors-runner.d.ts +48 -0
- package/dist/live-connectors-runner.js +17 -0
- package/dist/live-connectors-runner.js.map +1 -0
- package/dist/local-llm.js +1 -0
- package/dist/logger.js +1 -0
- package/dist/memory-action-policy.js +1 -0
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-cache.js +4 -1
- package/dist/memory-governance-KG52RITE.js +37 -0
- package/dist/memory-governance-KG52RITE.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.js +4 -1
- package/dist/memory-projection-format.js +1 -0
- package/dist/{memory-projection-store-DeSXPh1j.d.ts → memory-projection-store-D3vBHS4J.d.ts} +1 -0
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-projection-store.js +1 -0
- package/dist/memory-worth-bench.js +1 -0
- package/dist/memory-worth-bench.js.map +1 -1
- package/dist/memory-worth-filter.js +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/memory-worth-outcomes.js +1 -0
- package/dist/memory-worth.js +1 -0
- package/dist/metadata-FC3XPDRQ.js +21 -0
- package/dist/metadata-FC3XPDRQ.js.map +1 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js +8 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js.map +1 -0
- package/dist/model-registry.js +1 -0
- package/dist/models-json.js +1 -0
- package/dist/native-knowledge.js +1 -0
- package/dist/negative.js +1 -0
- package/dist/objective-state-writers.js +1 -0
- package/dist/objective-state-writers.js.map +1 -1
- package/dist/objective-state.js +1 -0
- package/dist/openai-chat-compat.js +1 -0
- package/dist/operator-toolkit.d.ts +46 -2
- package/dist/operator-toolkit.js +28 -16
- package/dist/opik-exporter.js +1 -0
- package/dist/opik-exporter.js.map +1 -1
- package/dist/{orchestrator-CmJ-NTdJ.d.ts → orchestrator-ChkesB8U.d.ts} +177 -13
- package/dist/orchestrator.d.ts +6 -4
- package/dist/orchestrator.js +55 -39
- package/dist/page-versioning.js +1 -0
- package/dist/path-RMTY5Y5A.js +9 -0
- package/dist/path-RMTY5Y5A.js.map +1 -0
- package/dist/patterns-cli.d.ts +160 -0
- package/dist/patterns-cli.js +29 -0
- package/dist/patterns-cli.js.map +1 -0
- package/dist/peers-6OSQ3NK6.js +44 -0
- package/dist/peers-6OSQ3NK6.js.map +1 -0
- package/dist/plugin-id.js +1 -0
- package/dist/policy-runtime.js +1 -0
- package/dist/{port-BADbLZU5.d.ts → port-hqGnoStS.d.ts} +6 -0
- package/dist/profiling.js +1 -0
- package/dist/purge-6ATBGT77.js +205 -0
- package/dist/purge-6ATBGT77.js.map +1 -0
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd-recall-cache.js +1 -0
- package/dist/qmd.d.ts +2 -1
- package/dist/qmd.js +4 -3
- package/dist/reasoning-trace-recall.js +1 -0
- package/dist/reasoning-trace-types.js +1 -0
- package/dist/recall-audit-anomaly.js +1 -0
- package/dist/recall-audit.js +1 -0
- package/dist/recall-disclosure-escalation.d.ts +84 -0
- package/dist/recall-disclosure-escalation.js +14 -0
- package/dist/recall-disclosure-escalation.js.map +1 -0
- package/dist/recall-explain-renderer.js +4 -1
- package/dist/recall-mmr.js +1 -0
- package/dist/recall-qos.js +1 -0
- package/dist/recall-query-policy.js +1 -0
- package/dist/recall-state.d.ts +7 -0
- package/dist/recall-state.js +2 -1
- package/dist/recall-tag-filter.d.ts +56 -0
- package/dist/recall-tag-filter.js +14 -0
- package/dist/recall-tag-filter.js.map +1 -0
- package/dist/recall-tokenization.js +1 -0
- package/dist/recall-xray-cli.d.ts +9 -2
- package/dist/recall-xray-cli.js +9 -4
- package/dist/recall-xray-renderer.js +4 -1
- package/dist/recall-xray.d.ts +116 -2
- package/dist/recall-xray.js +9 -3
- package/dist/reconstruct.js +1 -0
- package/dist/release-changelog.js +2 -0
- package/dist/release-changelog.js.map +1 -1
- package/dist/relevance.js +1 -0
- package/dist/rerank.js +1 -0
- package/dist/{resolution-QBTDHTG7.js → resolution-YGIBORXI.js} +2 -1
- package/dist/{resolution-QBTDHTG7.js.map → resolution-YGIBORXI.js.map} +1 -1
- package/dist/resolve-auth-token.d.ts +51 -0
- package/dist/resolve-auth-token.js +12 -0
- package/dist/resolve-auth-token.js.map +1 -0
- package/dist/resolve-provider-secret.d.ts +9 -1
- package/dist/resolve-provider-secret.js +4 -1
- package/dist/resume-bundles.js +4 -3
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-agents.js +1 -0
- package/dist/retrieval-tiers.js +1 -0
- package/dist/retrieval.js +1 -0
- package/dist/sanitize.js +1 -0
- package/dist/schemas.d.ts +37 -24
- package/dist/schemas.js +2 -1
- package/dist/sdk-compat.js +1 -0
- package/dist/sdk-compat.js.map +1 -1
- package/dist/secure-store-4R2GSO7S.js +156 -0
- package/dist/secure-store-4R2GSO7S.js.map +1 -0
- package/dist/semantic-chunking.js +1 -0
- package/dist/{semantic-consolidation-CxJU6MJk.d.ts → semantic-consolidation-ByBXb-sf.d.ts} +3 -3
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +11 -6
- package/dist/semantic-rule-promotion.d.ts +1 -1
- package/dist/semantic-rule-promotion.js +9 -6
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -6
- package/dist/session-integrity.js +1 -0
- package/dist/session-observer-bands.js +1 -0
- package/dist/session-observer-state.js +1 -0
- package/dist/session-toggles.js +2 -0
- package/dist/session-toggles.js.map +1 -1
- package/dist/signal.js +1 -0
- package/dist/skills-registry.js +2 -0
- package/dist/skills-registry.js.map +1 -1
- package/dist/source-attribution.js +1 -0
- package/dist/state-NCHQ4TRG.js +8 -0
- package/dist/state-NCHQ4TRG.js.map +1 -0
- package/dist/state-store-3EH7HYIN.js +16 -0
- package/dist/state-store-3EH7HYIN.js.map +1 -0
- package/dist/storage.d.ts +76 -2
- package/dist/storage.js +8 -5
- package/dist/store-contract.js +1 -0
- package/dist/summarizer.js +5 -4
- package/dist/summary-snapshot.js +1 -0
- package/dist/temporal-index.js +1 -0
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +2 -1
- package/dist/temporal-validity.d.ts +52 -0
- package/dist/temporal-validity.js +14 -0
- package/dist/temporal-validity.js.map +1 -0
- package/dist/threading.js +1 -0
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-migration.js +1 -0
- package/dist/tier-routing.js +1 -0
- package/dist/tier-stats-62ZVDFKS.js +152 -0
- package/dist/tier-stats-62ZVDFKS.js.map +1 -0
- package/dist/tmt.js +1 -0
- package/dist/tokens.js +1 -0
- package/dist/topics.js +1 -0
- package/dist/trace-C5ETWBEF.js +290 -0
- package/dist/trace-C5ETWBEF.js.map +1 -0
- package/dist/transcript.js +1 -0
- package/dist/trust-zones.js +1 -0
- package/dist/tui-RI7P6PBS.js +13 -0
- package/dist/tui-RI7P6PBS.js.map +1 -0
- package/dist/types-V3FJ26TF.js +30 -0
- package/dist/types-V3FJ26TF.js.map +1 -0
- package/dist/types.d.ts +634 -9
- package/dist/types.js +10 -3
- package/dist/utility-learner.js +1 -0
- package/dist/utility-runtime.js +1 -0
- package/dist/utility-telemetry.js +1 -0
- package/dist/verified-recall.js +9 -6
- package/dist/version-utils.js +1 -0
- package/dist/whitespace.js +1 -0
- package/dist/work-product-ledger.js +1 -0
- package/package.json +2 -1
- package/dist/access-service-Br8ZydTK.d.ts +0 -827
- package/dist/chunk-3OGMS3PE.js.map +0 -1
- package/dist/chunk-3YGHKTBF.js.map +0 -1
- package/dist/chunk-6PFRXT4K.js.map +0 -1
- package/dist/chunk-6YJHX2DL.js.map +0 -1
- package/dist/chunk-BECYBZLX.js.map +0 -1
- package/dist/chunk-C2EFFULQ.js.map +0 -1
- package/dist/chunk-CUPFXL3J.js.map +0 -1
- package/dist/chunk-DIXB44VE.js.map +0 -1
- package/dist/chunk-F5VP6YCB.js.map +0 -1
- package/dist/chunk-FVA6TGI3.js.map +0 -1
- package/dist/chunk-GA5P7RST.js.map +0 -1
- package/dist/chunk-KVBLZUKV.js.map +0 -1
- package/dist/chunk-L7IXWRYE.js.map +0 -1
- package/dist/chunk-LOIMBRDE.js.map +0 -1
- package/dist/chunk-LTCGGW2D.js +0 -14
- package/dist/chunk-LTCGGW2D.js.map +0 -1
- package/dist/chunk-NZLQTHS5.js.map +0 -1
- package/dist/chunk-OC5OXUQ4.js.map +0 -1
- package/dist/chunk-PVPWZSSI.js.map +0 -1
- package/dist/chunk-SPI27QT6.js.map +0 -1
- package/dist/chunk-STGWEHYR.js.map +0 -1
- package/dist/chunk-TP4FZJIZ.js.map +0 -1
- package/dist/chunk-ULYOGL6R.js.map +0 -1
- package/dist/chunk-UWB5LMWY.js.map +0 -1
- package/dist/chunk-VBVG2M5G.js.map +0 -1
- package/dist/chunk-VDX363PS.js.map +0 -1
- package/dist/chunk-WCLICCGB.js.map +0 -1
- package/dist/chunk-X6GF3FX2.js +0 -26
- package/dist/chunk-X6GF3FX2.js.map +0 -1
- package/dist/chunk-XXVWLXSG.js.map +0 -1
- package/dist/chunk-Y7R2XJ5Q.js.map +0 -1
- package/dist/chunk-ZAIM4TUE.js.map +0 -1
- /package/dist/{contradiction-review-WIUBAR52.js.map → capsule-cli.js.map} +0 -0
- /package/dist/{engine-72LSIWQP.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
- /package/dist/{chunk-TMYO7B5P.js.map → chunk-47WOM4YW.js.map} +0 -0
- /package/dist/{chunk-DG6YMRDC.js.map → chunk-B2TL6GA2.js.map} +0 -0
- /package/dist/{chunk-AYXIPSZO.js.map → chunk-CRU27Q4J.js.map} +0 -0
- /package/dist/{chunk-RBBWYEFJ.js.map → chunk-G2WADRQ3.js.map} +0 -0
- /package/dist/{chunk-NBVAS5MT.js.map → chunk-R2L7SUX2.js.map} +0 -0
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readEdgeConfidence
|
|
3
|
+
} from "./chunk-2LSZVONP.js";
|
|
4
|
+
import {
|
|
5
|
+
emitGraphEvent
|
|
6
|
+
} from "./chunk-WIICJPET.js";
|
|
7
|
+
|
|
1
8
|
// src/graph.ts
|
|
2
9
|
import { mkdir, appendFile, readFile } from "fs/promises";
|
|
3
10
|
import * as path from "path";
|
|
11
|
+
var DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR = 0.2;
|
|
12
|
+
var DEFAULT_GRAPH_TRAVERSAL_PAGERANK_ITERATIONS = 8;
|
|
4
13
|
var CAUSAL_PHRASES = [
|
|
5
14
|
"as a result",
|
|
6
15
|
"led to",
|
|
@@ -18,29 +27,71 @@ function graphFilePath(memoryDir, type) {
|
|
|
18
27
|
async function ensureGraphsDir(memoryDir) {
|
|
19
28
|
await mkdir(graphsDir(memoryDir), { recursive: true });
|
|
20
29
|
}
|
|
30
|
+
var graphWriteLocks = /* @__PURE__ */ new Map();
|
|
31
|
+
function withGraphWriteLock(filePath, fn) {
|
|
32
|
+
const prev = graphWriteLocks.get(filePath) ?? Promise.resolve();
|
|
33
|
+
const next = prev.then(fn, fn);
|
|
34
|
+
graphWriteLocks.set(
|
|
35
|
+
filePath,
|
|
36
|
+
next.then(
|
|
37
|
+
() => void 0,
|
|
38
|
+
() => void 0
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
21
43
|
async function appendEdge(memoryDir, edge) {
|
|
22
44
|
await ensureGraphsDir(memoryDir);
|
|
45
|
+
const filePath = graphFilePath(memoryDir, edge.type);
|
|
23
46
|
const line = JSON.stringify(edge) + "\n";
|
|
24
|
-
await
|
|
47
|
+
await withGraphWriteLock(filePath, async () => {
|
|
48
|
+
await appendFile(filePath, line, "utf8");
|
|
49
|
+
});
|
|
50
|
+
emitGraphEvent(memoryDir, "edge-added", {
|
|
51
|
+
source: edge.from,
|
|
52
|
+
target: edge.to,
|
|
53
|
+
kind: edge.type,
|
|
54
|
+
weight: edge.weight,
|
|
55
|
+
label: edge.label,
|
|
56
|
+
confidence: typeof edge.confidence === "number" ? edge.confidence : 1
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function isNodeError(err) {
|
|
60
|
+
return typeof err === "object" && err !== null && "code" in err;
|
|
61
|
+
}
|
|
62
|
+
function parseEdgesJsonl(raw) {
|
|
63
|
+
const edges = [];
|
|
64
|
+
for (const line of raw.split("\n")) {
|
|
65
|
+
const trimmed = line.trim();
|
|
66
|
+
if (!trimmed) continue;
|
|
67
|
+
try {
|
|
68
|
+
edges.push(JSON.parse(trimmed));
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return edges;
|
|
25
73
|
}
|
|
26
74
|
async function readEdges(memoryDir, type) {
|
|
27
75
|
const filePath = graphFilePath(memoryDir, type);
|
|
28
76
|
try {
|
|
29
77
|
const raw = await readFile(filePath, "utf8");
|
|
30
|
-
|
|
31
|
-
for (const line of raw.split("\n")) {
|
|
32
|
-
const trimmed = line.trim();
|
|
33
|
-
if (!trimmed) continue;
|
|
34
|
-
try {
|
|
35
|
-
edges.push(JSON.parse(trimmed));
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return edges;
|
|
78
|
+
return parseEdgesJsonl(raw);
|
|
40
79
|
} catch {
|
|
41
80
|
return [];
|
|
42
81
|
}
|
|
43
82
|
}
|
|
83
|
+
async function readEdgesStrict(memoryDir, type) {
|
|
84
|
+
const filePath = graphFilePath(memoryDir, type);
|
|
85
|
+
try {
|
|
86
|
+
const raw = await readFile(filePath, "utf8");
|
|
87
|
+
return parseEdgesJsonl(raw);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
44
95
|
async function readAllEdges(memoryDir, config) {
|
|
45
96
|
const parts = await Promise.all([
|
|
46
97
|
config.entityGraphEnabled ? readEdges(memoryDir, "entity") : Promise.resolve([]),
|
|
@@ -238,21 +289,38 @@ var GraphIndex = class _GraphIndex {
|
|
|
238
289
|
* Spreading activation BFS (SYNAPSE-inspired).
|
|
239
290
|
*
|
|
240
291
|
* Starting from `seeds`, traverse the combined graph for up to `maxSteps` hops.
|
|
241
|
-
* Each candidate gets an activation score = edge.weight × decay^hop.
|
|
242
|
-
*
|
|
292
|
+
* Each candidate gets an activation score = edge.weight × edgeConfidence × decay^hop.
|
|
293
|
+
*
|
|
294
|
+
* Issue #681 PR 3/3 — confidence-aware traversal:
|
|
295
|
+
* - Each edge's `weight` is multiplied by its `confidence` (legacy edges
|
|
296
|
+
* missing `confidence` are treated as 1.0, preserving prior behavior).
|
|
297
|
+
* - Edges with `confidence < graphTraversalConfidenceFloor` are pruned and
|
|
298
|
+
* contribute neither activation nor downstream neighbors.
|
|
299
|
+
* - When `graphTraversalPageRankIterations > 0`, an additional PageRank-
|
|
300
|
+
* style refinement pass redistributes activation along confidence-weighted
|
|
301
|
+
* edges, sharpening the ranking among multi-hop candidates.
|
|
302
|
+
* - Per-result provenance includes the highest-confidence edge that landed
|
|
303
|
+
* on each candidate, so the X-ray surface can attribute pruning and
|
|
304
|
+
* ranking decisions back to specific edges.
|
|
243
305
|
*
|
|
244
|
-
* @param seeds
|
|
306
|
+
* @param seeds - initial memory paths to expand from (e.g. QMD top results)
|
|
245
307
|
* @param maxSteps - max BFS hops (from config: maxGraphTraversalSteps)
|
|
246
|
-
* @returns Array of {path, score} sorted descending, not including seed paths
|
|
308
|
+
* @returns Array of {path, score, edgeConfidence, ...} sorted descending, not including seed paths
|
|
247
309
|
*/
|
|
248
|
-
async spreadingActivation(seeds, maxSteps) {
|
|
310
|
+
async spreadingActivation(seeds, maxSteps, opts) {
|
|
249
311
|
if (!this.cfg.multiGraphMemoryEnabled) return [];
|
|
250
312
|
const steps = maxSteps ?? this.cfg.maxGraphTraversalSteps;
|
|
251
313
|
const decay = this.cfg.graphActivationDecay;
|
|
314
|
+
const floor = opts?.includeLowConfidence === true ? 0 : clampConfidenceFloor(this.cfg.graphTraversalConfidenceFloor);
|
|
315
|
+
const iterations = clampPageRankIterations(
|
|
316
|
+
this.cfg.graphTraversalPageRankIterations
|
|
317
|
+
);
|
|
252
318
|
try {
|
|
253
319
|
const allEdges = await this.loadEdgesCached();
|
|
254
320
|
const adj = /* @__PURE__ */ new Map();
|
|
255
321
|
for (const edge of allEdges) {
|
|
322
|
+
const conf = readEdgeConfidence(edge);
|
|
323
|
+
if (conf < floor) continue;
|
|
256
324
|
if (!adj.has(edge.from)) adj.set(edge.from, []);
|
|
257
325
|
adj.get(edge.from).push(edge);
|
|
258
326
|
if (edge.type !== "causal") {
|
|
@@ -271,7 +339,9 @@ var GraphIndex = class _GraphIndex {
|
|
|
271
339
|
const edges = adj.get(node) ?? [];
|
|
272
340
|
for (const edge of edges) {
|
|
273
341
|
const neighbor = edge.to === node ? edge.from : edge.to;
|
|
274
|
-
const
|
|
342
|
+
const conf = readEdgeConfidence(edge);
|
|
343
|
+
if (conf < floor) continue;
|
|
344
|
+
const score = edge.weight * conf * Math.pow(decay, hop + 1);
|
|
275
345
|
if (!seedSet.has(neighbor)) {
|
|
276
346
|
const existing = scores.get(neighbor) ?? 0;
|
|
277
347
|
scores.set(neighbor, existing + score);
|
|
@@ -281,7 +351,8 @@ var GraphIndex = class _GraphIndex {
|
|
|
281
351
|
seed: sourceSeed,
|
|
282
352
|
hopDepth: hop + 1,
|
|
283
353
|
decayedWeight: score,
|
|
284
|
-
graphType: edge.type
|
|
354
|
+
graphType: edge.type,
|
|
355
|
+
edgeConfidence: conf
|
|
285
356
|
});
|
|
286
357
|
}
|
|
287
358
|
}
|
|
@@ -291,6 +362,13 @@ var GraphIndex = class _GraphIndex {
|
|
|
291
362
|
}
|
|
292
363
|
}
|
|
293
364
|
}
|
|
365
|
+
if (iterations > 0 && scores.size > 1) {
|
|
366
|
+
applyPageRankRefinement(scores, adj, {
|
|
367
|
+
iterations,
|
|
368
|
+
floor,
|
|
369
|
+
damping: 0.85
|
|
370
|
+
});
|
|
371
|
+
}
|
|
294
372
|
if (this.cfg.graphLateralInhibitionEnabled && scores.size > 1) {
|
|
295
373
|
const inhibited = applyLateralInhibition(scores, {
|
|
296
374
|
beta: this.cfg.graphLateralInhibitionBeta,
|
|
@@ -306,7 +384,8 @@ var GraphIndex = class _GraphIndex {
|
|
|
306
384
|
seed: provenance.get(p)?.seed ?? "",
|
|
307
385
|
hopDepth: provenance.get(p)?.hopDepth ?? 0,
|
|
308
386
|
decayedWeight: provenance.get(p)?.decayedWeight ?? 0,
|
|
309
|
-
graphType: provenance.get(p)?.graphType ?? "entity"
|
|
387
|
+
graphType: provenance.get(p)?.graphType ?? "entity",
|
|
388
|
+
edgeConfidence: provenance.get(p)?.edgeConfidence ?? 1
|
|
310
389
|
})).sort((a, b) => b.score - a.score);
|
|
311
390
|
} catch (err) {
|
|
312
391
|
const { log } = await import("./logger.js");
|
|
@@ -315,6 +394,63 @@ var GraphIndex = class _GraphIndex {
|
|
|
315
394
|
}
|
|
316
395
|
}
|
|
317
396
|
};
|
|
397
|
+
function clampConfidenceFloor(raw) {
|
|
398
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) {
|
|
399
|
+
return DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR;
|
|
400
|
+
}
|
|
401
|
+
if (raw < 0) return 0;
|
|
402
|
+
if (raw > 1) return 1;
|
|
403
|
+
return raw;
|
|
404
|
+
}
|
|
405
|
+
function clampPageRankIterations(raw) {
|
|
406
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) return 0;
|
|
407
|
+
if (raw <= 0) return 0;
|
|
408
|
+
return Math.floor(raw);
|
|
409
|
+
}
|
|
410
|
+
function applyPageRankRefinement(scores, adj, opts) {
|
|
411
|
+
const { iterations, floor, damping } = opts;
|
|
412
|
+
if (iterations <= 0 || scores.size === 0) return;
|
|
413
|
+
const safeDamping = Math.min(1, Math.max(0, damping));
|
|
414
|
+
const eligible = (edge, fromNode) => {
|
|
415
|
+
if (readEdgeConfidence(edge) < floor) return false;
|
|
416
|
+
const neighbor = edge.to === fromNode ? edge.from : edge.to;
|
|
417
|
+
return scores.has(neighbor);
|
|
418
|
+
};
|
|
419
|
+
const outboundTotal = /* @__PURE__ */ new Map();
|
|
420
|
+
for (const [node, edges] of adj.entries()) {
|
|
421
|
+
if (!scores.has(node)) continue;
|
|
422
|
+
let sum = 0;
|
|
423
|
+
for (const edge of edges) {
|
|
424
|
+
if (!eligible(edge, node)) continue;
|
|
425
|
+
sum += readEdgeConfidence(edge) * edge.weight;
|
|
426
|
+
}
|
|
427
|
+
if (sum > 0) outboundTotal.set(node, sum);
|
|
428
|
+
}
|
|
429
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
430
|
+
const next = /* @__PURE__ */ new Map();
|
|
431
|
+
for (const [node, score] of scores) {
|
|
432
|
+
next.set(node, (1 - safeDamping) * score);
|
|
433
|
+
}
|
|
434
|
+
for (const [node, score] of scores) {
|
|
435
|
+
const outEdges = adj.get(node);
|
|
436
|
+
const total = outboundTotal.get(node);
|
|
437
|
+
if (!outEdges || outEdges.length === 0 || !total || total <= 0) {
|
|
438
|
+
next.set(node, (next.get(node) ?? 0) + safeDamping * score);
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
for (const edge of outEdges) {
|
|
442
|
+
if (!eligible(edge, node)) continue;
|
|
443
|
+
const conf = readEdgeConfidence(edge);
|
|
444
|
+
const neighbor = edge.to === node ? edge.from : edge.to;
|
|
445
|
+
const flow = safeDamping * score * (conf * edge.weight / total);
|
|
446
|
+
next.set(neighbor, (next.get(neighbor) ?? 0) + flow);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
for (const [node, score] of next) {
|
|
450
|
+
scores.set(node, score);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
318
454
|
function applyLateralInhibition(scores, opts) {
|
|
319
455
|
const { beta, topM } = opts;
|
|
320
456
|
if (beta === 0 || topM === 0) return new Map(scores);
|
|
@@ -334,16 +470,23 @@ function applyLateralInhibition(scores, opts) {
|
|
|
334
470
|
}
|
|
335
471
|
|
|
336
472
|
export {
|
|
473
|
+
DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR,
|
|
474
|
+
DEFAULT_GRAPH_TRAVERSAL_PAGERANK_ITERATIONS,
|
|
337
475
|
CAUSAL_PHRASES,
|
|
338
476
|
graphsDir,
|
|
339
477
|
graphFilePath,
|
|
340
478
|
ensureGraphsDir,
|
|
479
|
+
withGraphWriteLock,
|
|
341
480
|
appendEdge,
|
|
342
481
|
readEdges,
|
|
482
|
+
readEdgesStrict,
|
|
343
483
|
readAllEdges,
|
|
344
484
|
analyzeGraphHealth,
|
|
345
485
|
detectCausalPhrase,
|
|
346
486
|
GraphIndex,
|
|
487
|
+
clampConfidenceFloor,
|
|
488
|
+
clampPageRankIterations,
|
|
489
|
+
applyPageRankRefinement,
|
|
347
490
|
applyLateralInhibition
|
|
348
491
|
};
|
|
349
|
-
//# sourceMappingURL=chunk-
|
|
492
|
+
//# sourceMappingURL=chunk-RK2Y4XOM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/graph.ts"],"sourcesContent":["/**\n * Multi-Graph Memory (MAGMA/SYNAPSE-inspired, v8.2)\n *\n * Maintains three typed edge graphs:\n * entity.jsonl — memories sharing a named entity (entityRef)\n * time.jsonl — consecutive memories in the same thread/session\n * causal.jsonl — memories linked by causal language heuristics\n *\n * Stored under `<memoryDir>/state/graphs/`.\n * All writes are fail-open: errors are caught/logged, never thrown.\n */\n\nimport { mkdir, appendFile, readFile } from \"node:fs/promises\";\nimport * as path from \"path\";\n\nimport { readEdgeConfidence } from \"./graph-edge-reinforcement.js\";\nimport { emitGraphEvent } from \"./graph-events.js\";\n\nexport type GraphType = \"entity\" | \"time\" | \"causal\";\n\nexport interface GraphEdge {\n from: string; // relative memory path (e.g. \"facts/2026-02-22/abc.md\")\n to: string; // relative memory path\n type: GraphType;\n weight: number; // 1.0 default, decay applied during traversal\n label: string; // entity name, threadId, or matched causal phrase\n ts: string; // ISO timestamp of edge creation\n\n // Issue #681 — edge confidence + reinforcement (PR 1/3: schema + primitive only).\n // Both fields are optional so existing edges without confidence still validate.\n // Treat a missing `confidence` as 1.0 (legacy behavior) at read sites.\n // PR 2/3 wires the maintenance decay job; PR 3/3 weights PageRank traversal by confidence.\n confidence?: number; // [0, 1]; missing = 1.0\n lastReinforcedAt?: string; // ISO timestamp of most recent reinforcement\n}\n\nexport interface GraphConfig {\n multiGraphMemoryEnabled: boolean;\n entityGraphEnabled: boolean;\n timeGraphEnabled: boolean;\n causalGraphEnabled: boolean;\n maxGraphTraversalSteps: number;\n graphActivationDecay: number;\n maxEntityGraphEdgesPerMemory: number;\n graphLateralInhibitionEnabled: boolean;\n graphLateralInhibitionBeta: number;\n graphLateralInhibitionTopM: number;\n /**\n * Issue #681 PR 3/3 — minimum edge confidence required for traversal.\n * Edges with confidence below this floor are pruned. Legacy edges\n * (no `confidence` field) are treated as 1.0 and always pass.\n * Range `[0, 1]`. Default 0.2.\n */\n graphTraversalConfidenceFloor: number;\n /**\n * Issue #681 PR 3/3 — number of PageRank-style refinement iterations\n * applied on top of BFS activation. Set to 0 to disable refinement\n * and return raw BFS scores. Default 8.\n */\n graphTraversalPageRankIterations: number;\n}\n\n/** Default minimum edge confidence required for traversal (issue #681 PR 3/3). */\nexport const DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR = 0.2;\n/** Default PageRank-style refinement iteration count (issue #681 PR 3/3). */\nexport const DEFAULT_GRAPH_TRAVERSAL_PAGERANK_ITERATIONS = 8;\n\n// Causal signal phrases — order matters (most specific first)\nexport const CAUSAL_PHRASES = [\n \"as a result\",\n \"led to\",\n \"because of\",\n \"therefore\",\n \"caused\",\n \"because\",\n];\n\nexport function graphsDir(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"graphs\");\n}\n\nexport function graphFilePath(memoryDir: string, type: GraphType): string {\n return path.join(graphsDir(memoryDir), `${type}.jsonl`);\n}\n\nexport async function ensureGraphsDir(memoryDir: string): Promise<void> {\n await mkdir(graphsDir(memoryDir), { recursive: true });\n}\n\n// ---------------------------------------------------------------------------\n// Per-graph-file write lock (gotcha #40 promise-chain pattern).\n//\n// Both the append path (`appendEdge`) and the rewrite path used by the\n// decay maintenance job must serialize on the same lock keyed by the\n// JSONL file path. Without this, an extraction can append a new edge\n// between the decay job's read-snapshot and rewrite, silently dropping\n// the appended edge during active traffic (issue #729 / Codex P1).\n// ---------------------------------------------------------------------------\nconst graphWriteLocks = new Map<string, Promise<void>>();\n\n/**\n * Run `fn` while holding the write lock for the given graph JSONL file.\n *\n * The lock is keyed by absolute file path so concurrent writes to\n * different graph types proceed independently. The chain recovers from\n * rejection (gotcha #40) so a single I/O failure does not poison all\n * future writers, but the original error is still surfaced to the\n * caller of `withGraphWriteLock`.\n */\nexport function withGraphWriteLock<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n const prev = graphWriteLocks.get(filePath) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n graphWriteLocks.set(\n filePath,\n next.then(\n () => undefined,\n () => undefined,\n ),\n );\n return next;\n}\n\nexport async function appendEdge(memoryDir: string, edge: GraphEdge): Promise<void> {\n await ensureGraphsDir(memoryDir);\n const filePath = graphFilePath(memoryDir, edge.type);\n const line = JSON.stringify(edge) + \"\\n\";\n await withGraphWriteLock(filePath, async () => {\n await appendFile(filePath, line, \"utf8\");\n });\n // Emit edge-added event for SSE subscribers (issue #691 PR 5/5).\n // Fail-open: emitGraphEvent catches listener errors so a bad SSE client\n // can never surface into the extraction pipeline.\n emitGraphEvent(memoryDir, \"edge-added\", {\n source: edge.from,\n target: edge.to,\n kind: edge.type,\n weight: edge.weight,\n label: edge.label,\n confidence: typeof edge.confidence === \"number\" ? edge.confidence : 1.0,\n });\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return typeof err === \"object\" && err !== null && \"code\" in err;\n}\n\nfunction parseEdgesJsonl(raw: string): GraphEdge[] {\n const edges: GraphEdge[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n edges.push(JSON.parse(trimmed) as GraphEdge);\n } catch {\n // skip corrupt lines — fail-open for partial JSONL recovery\n }\n }\n return edges;\n}\n\n/**\n * Read all edges of a given type from the JSONL file.\n * Returns [] if the file doesn't exist or any read error occurs (fail-open).\n *\n * Production traversal callers (recall/PageRank) depend on this fail-open\n * posture so a temporarily missing or unreadable graph file never blocks\n * a recall. Maintenance jobs that need to distinguish ENOENT from real\n * I/O failures must use {@link readEdgesStrict} instead.\n */\nexport async function readEdges(memoryDir: string, type: GraphType): Promise<GraphEdge[]> {\n const filePath = graphFilePath(memoryDir, type);\n try {\n const raw = await readFile(filePath, \"utf8\");\n return parseEdgesJsonl(raw);\n } catch {\n return [];\n }\n}\n\n/**\n * Same as {@link readEdges} but only swallows `ENOENT`; all other read\n * errors (`EACCES`, `EIO`, …) are propagated. Used by the graph-edge\n * decay maintenance job so I/O outages surface as a failed run instead\n * of being silently reported as \"no edges to decay\" (issue #729 /\n * Codex P1, line 120).\n */\nexport async function readEdgesStrict(memoryDir: string, type: GraphType): Promise<GraphEdge[]> {\n const filePath = graphFilePath(memoryDir, type);\n try {\n const raw = await readFile(filePath, \"utf8\");\n return parseEdgesJsonl(raw);\n } catch (err) {\n if (isNodeError(err) && err.code === \"ENOENT\") {\n return [];\n }\n throw err;\n }\n}\n\n/**\n * Read edges from all enabled graph types.\n */\nexport async function readAllEdges(\n memoryDir: string,\n config: Pick<GraphConfig, \"entityGraphEnabled\" | \"timeGraphEnabled\" | \"causalGraphEnabled\">,\n): Promise<GraphEdge[]> {\n const parts: GraphEdge[][] = await Promise.all([\n config.entityGraphEnabled ? readEdges(memoryDir, \"entity\") : Promise.resolve([]),\n config.timeGraphEnabled ? readEdges(memoryDir, \"time\") : Promise.resolve([]),\n config.causalGraphEnabled ? readEdges(memoryDir, \"causal\") : Promise.resolve([]),\n ]);\n return parts.flat();\n}\n\nexport interface GraphHealthFileStats {\n type: GraphType;\n filePath: string;\n exists: boolean;\n totalLines: number;\n validEdges: number;\n corruptLines: number;\n uniqueNodes: number;\n}\n\nexport interface GraphHealthReport {\n generatedAt: string;\n enabledTypes: GraphType[];\n totals: {\n totalLines: number;\n validEdges: number;\n corruptLines: number;\n uniqueNodes: number;\n };\n files: GraphHealthFileStats[];\n repairGuidance?: string[];\n}\n\nfunction isValidGraphEdge(raw: unknown, expectedType: GraphType): raw is GraphEdge {\n if (!raw || typeof raw !== \"object\") return false;\n const edge = raw as Record<string, unknown>;\n return (\n edge.type === expectedType &&\n typeof edge.from === \"string\" && edge.from.length > 0 &&\n typeof edge.to === \"string\" && edge.to.length > 0 &&\n typeof edge.weight === \"number\" && Number.isFinite(edge.weight) &&\n typeof edge.label === \"string\" &&\n typeof edge.ts === \"string\"\n );\n}\n\nexport async function analyzeGraphHealth(\n memoryDir: string,\n options?: {\n entityGraphEnabled?: boolean;\n timeGraphEnabled?: boolean;\n causalGraphEnabled?: boolean;\n includeRepairGuidance?: boolean;\n },\n): Promise<GraphHealthReport> {\n const enabledTypes: GraphType[] = [];\n if (options?.entityGraphEnabled !== false) enabledTypes.push(\"entity\");\n if (options?.timeGraphEnabled !== false) enabledTypes.push(\"time\");\n if (options?.causalGraphEnabled !== false) enabledTypes.push(\"causal\");\n\n const files: GraphHealthFileStats[] = [];\n const globalNodes = new Set<string>();\n\n for (const type of enabledTypes) {\n const filePath = graphFilePath(memoryDir, type);\n let exists = true;\n let totalLines = 0;\n let validEdges = 0;\n let corruptLines = 0;\n const nodes = new Set<string>();\n\n try {\n const raw = await readFile(filePath, \"utf8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n totalLines += 1;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isValidGraphEdge(parsed, type)) {\n corruptLines += 1;\n continue;\n }\n validEdges += 1;\n nodes.add(parsed.from);\n nodes.add(parsed.to);\n globalNodes.add(parsed.from);\n globalNodes.add(parsed.to);\n } catch {\n corruptLines += 1;\n }\n }\n } catch {\n exists = false;\n }\n\n files.push({\n type,\n filePath,\n exists,\n totalLines,\n validEdges,\n corruptLines,\n uniqueNodes: nodes.size,\n });\n }\n\n const totals = files.reduce(\n (acc, item) => {\n acc.totalLines += item.totalLines;\n acc.validEdges += item.validEdges;\n acc.corruptLines += item.corruptLines;\n return acc;\n },\n {\n totalLines: 0,\n validEdges: 0,\n corruptLines: 0,\n uniqueNodes: globalNodes.size,\n },\n );\n totals.uniqueNodes = globalNodes.size;\n\n const report: GraphHealthReport = {\n generatedAt: new Date().toISOString(),\n enabledTypes,\n totals,\n files,\n };\n\n if (options?.includeRepairGuidance === true) {\n const guidance: string[] = [];\n if (totals.corruptLines > 0) {\n guidance.push(\"Corrupt graph lines detected: back up memory/state/graphs, then rebuild graphs from clean memory replay/extraction runs.\");\n }\n if (totals.validEdges === 0) {\n guidance.push(\"No valid edges detected yet: run normal extraction traffic (or replay ingestion) to seed graph files.\");\n }\n if (guidance.length > 0) report.repairGuidance = guidance;\n }\n\n return report;\n}\n\n/**\n * Detect causal signal phrases in text. Returns the first matched phrase, or null.\n */\nexport function detectCausalPhrase(text: string): string | null {\n const lower = text.toLowerCase();\n for (const phrase of CAUSAL_PHRASES) {\n if (lower.includes(phrase)) return phrase;\n }\n return null;\n}\n\n/**\n * GraphIndex — builds and updates the three memory graphs.\n *\n * Usage (orchestrator):\n * this.graphIndex = new GraphIndex(config.memoryDir, config);\n *\n * // After each memory write:\n * await this.graphIndex.onMemoryWritten(memoryPath, frontmatter, threadId, recentInThread);\n */\nexport class GraphIndex {\n private readonly memoryDir: string;\n private readonly cfg: GraphConfig;\n\n // Cache for readAllEdges() result. With 30k+ entity edges (6 MB JSONL) the\n // file read + JSON parse takes 2-4 s per call. This instance-level cache\n // eliminates that overhead on every spreadingActivation() call; it is\n // invalidated (set to null) in onMemoryWritten() so new edges appear promptly.\n private edgeCache: { allEdges: GraphEdge[]; loadedAt: number } | null = null;\n private static readonly EDGE_CACHE_TTL_MS = 300_000; // 5 minutes\n\n constructor(memoryDir: string, cfg: GraphConfig) {\n this.memoryDir = memoryDir;\n this.cfg = cfg;\n }\n\n /** Clear the edge cache so the next spreadingActivation() re-reads from disk.\n * Call after any code path that appends edges outside of onMemoryWritten(). */\n invalidateEdgeCache(): void {\n this.edgeCache = null;\n }\n\n private async loadEdgesCached(): Promise<GraphEdge[]> {\n if (\n this.edgeCache &&\n Date.now() - this.edgeCache.loadedAt < GraphIndex.EDGE_CACHE_TTL_MS\n ) {\n return this.edgeCache.allEdges;\n }\n const allEdges = await readAllEdges(this.memoryDir, {\n entityGraphEnabled: this.cfg.entityGraphEnabled,\n timeGraphEnabled: this.cfg.timeGraphEnabled,\n causalGraphEnabled: this.cfg.causalGraphEnabled,\n });\n this.edgeCache = { allEdges, loadedAt: Date.now() };\n return allEdges;\n }\n\n /**\n * Called after a memory is written to disk.\n *\n * @param memoryPath - relative path from memoryDir (e.g. \"facts/2026-02-22/abc.md\")\n * @param entityRef - entityRef frontmatter field (if any)\n * @param content - full memory text (for causal detection)\n * @param created - ISO timestamp of this memory\n * @param threadId - current thread ID (for time graph)\n * @param recentInThread - paths of the N most-recent memories in this thread (for time graph)\n * @param entitySiblings - paths of other memories that share the same entityRef (for entity graph)\n */\n async onMemoryWritten(opts: {\n memoryPath: string;\n entityRef?: string;\n content: string;\n created: string;\n threadId?: string;\n recentInThread?: string[];\n entitySiblings?: string[];\n causalPredecessor?: string;\n }): Promise<void> {\n if (!this.cfg.multiGraphMemoryEnabled) return;\n const ts = new Date().toISOString();\n\n try {\n // Entity graph\n if (this.cfg.entityGraphEnabled && opts.entityRef && opts.entitySiblings?.length) {\n const siblings = opts.entitySiblings.slice(0, this.cfg.maxEntityGraphEdgesPerMemory);\n for (const sibling of siblings) {\n await appendEdge(this.memoryDir, {\n from: opts.memoryPath,\n to: sibling,\n type: \"entity\",\n weight: 1.0,\n label: opts.entityRef,\n ts,\n });\n }\n }\n\n // Time graph — link to most recent memory in same thread\n if (this.cfg.timeGraphEnabled && opts.threadId && opts.recentInThread?.length) {\n const predecessor = opts.recentInThread[opts.recentInThread.length - 1];\n if (predecessor && predecessor !== opts.memoryPath) {\n await appendEdge(this.memoryDir, {\n from: predecessor,\n to: opts.memoryPath,\n type: \"time\",\n weight: 1.0,\n label: opts.threadId,\n ts,\n });\n }\n }\n\n // Causal graph\n if (this.cfg.causalGraphEnabled && opts.causalPredecessor) {\n const phrase = detectCausalPhrase(opts.content);\n if (phrase) {\n await appendEdge(this.memoryDir, {\n from: opts.causalPredecessor,\n to: opts.memoryPath,\n type: \"causal\",\n weight: 1.0,\n label: phrase,\n ts,\n });\n }\n }\n } catch (err) {\n // Fail-open: graph write errors must never surface to caller\n const { log } = await import(\"./logger.js\");\n log.warn(`[graph] onMemoryWritten error: ${err}`);\n } finally {\n // Invalidate edge cache so spreadingActivation() picks up new edges.\n // In `finally` so the cache is cleared even on partial write failure.\n this.edgeCache = null;\n }\n }\n\n /**\n * Spreading activation BFS (SYNAPSE-inspired).\n *\n * Starting from `seeds`, traverse the combined graph for up to `maxSteps` hops.\n * Each candidate gets an activation score = edge.weight × edgeConfidence × decay^hop.\n *\n * Issue #681 PR 3/3 — confidence-aware traversal:\n * - Each edge's `weight` is multiplied by its `confidence` (legacy edges\n * missing `confidence` are treated as 1.0, preserving prior behavior).\n * - Edges with `confidence < graphTraversalConfidenceFloor` are pruned and\n * contribute neither activation nor downstream neighbors.\n * - When `graphTraversalPageRankIterations > 0`, an additional PageRank-\n * style refinement pass redistributes activation along confidence-weighted\n * edges, sharpening the ranking among multi-hop candidates.\n * - Per-result provenance includes the highest-confidence edge that landed\n * on each candidate, so the X-ray surface can attribute pruning and\n * ranking decisions back to specific edges.\n *\n * @param seeds - initial memory paths to expand from (e.g. QMD top results)\n * @param maxSteps - max BFS hops (from config: maxGraphTraversalSteps)\n * @returns Array of {path, score, edgeConfidence, ...} sorted descending, not including seed paths\n */\n async spreadingActivation(\n seeds: string[],\n maxSteps?: number,\n opts?: {\n /**\n * Issue #681 — when `true`, bypasses the configured\n * `graphTraversalConfidenceFloor` and includes low-confidence\n * edges in traversal. Equivalent to forcing the floor to `0`.\n * Default `false` (floor from config is applied).\n */\n includeLowConfidence?: boolean;\n },\n ): Promise<Array<{\n path: string;\n score: number;\n seed: string;\n hopDepth: number;\n decayedWeight: number;\n graphType: \"entity\" | \"time\" | \"causal\";\n /**\n * Confidence of the edge that produced this candidate's recorded\n * provenance (the strongest edge along the chosen entry path).\n * In `[0, 1]`. Legacy edges without `confidence` surface as 1.0.\n */\n edgeConfidence: number;\n }>> {\n if (!this.cfg.multiGraphMemoryEnabled) return [];\n const steps = maxSteps ?? this.cfg.maxGraphTraversalSteps;\n const decay = this.cfg.graphActivationDecay;\n // When `includeLowConfidence` is set, use floor=0 so all edges\n // participate in traversal regardless of their decay state.\n // Otherwise clamp the configured floor into [0, 1] so misconfiguration\n // cannot (a) admit edges with negative confidence or (b) reject every\n // edge.\n const floor = opts?.includeLowConfidence === true\n ? 0\n : clampConfidenceFloor(this.cfg.graphTraversalConfidenceFloor);\n const iterations = clampPageRankIterations(\n this.cfg.graphTraversalPageRankIterations,\n );\n\n try {\n const allEdges = await this.loadEdgesCached();\n\n // Build adjacency index: from → edges, to → edges (bidirectional for entity/time, directional for causal).\n // Edges below the confidence floor are pruned at index time so neither\n // direct activation nor downstream BFS expansion can re-introduce them.\n const adj = new Map<string, GraphEdge[]>();\n for (const edge of allEdges) {\n const conf = readEdgeConfidence(edge);\n if (conf < floor) continue;\n if (!adj.has(edge.from)) adj.set(edge.from, []);\n adj.get(edge.from)!.push(edge);\n // Entity and time edges are bidirectional\n if (edge.type !== \"causal\") {\n if (!adj.has(edge.to)) adj.set(edge.to, []);\n adj.get(edge.to)!.push({ ...edge, from: edge.to, to: edge.from });\n }\n }\n\n const seedSet = new Set(seeds);\n const scores = new Map<string, number>(); // candidate path → accumulated activation score\n const provenance = new Map<\n string,\n {\n seed: string;\n hopDepth: number;\n decayedWeight: number;\n graphType: \"entity\" | \"time\" | \"causal\";\n edgeConfidence: number;\n }\n >();\n const visited = new Set<string>(seeds);\n\n // BFS queue: [nodePath, hop, seedPath]\n const queue: Array<[string, number, string]> = seeds.map((s) => [s, 0, s]);\n\n while (queue.length > 0) {\n const [node, hop, sourceSeed] = queue.shift()!;\n if (hop >= steps) continue;\n\n const edges = adj.get(node) ?? [];\n for (const edge of edges) {\n const neighbor = edge.to === node ? edge.from : edge.to;\n const conf = readEdgeConfidence(edge);\n // Defense in depth: the adjacency build already drops sub-floor\n // edges, but if a synthesized reverse edge ever bypassed that\n // path, this guard keeps spreading activation honest.\n if (conf < floor) continue;\n const score = edge.weight * conf * Math.pow(decay, hop + 1);\n\n if (!seedSet.has(neighbor)) {\n const existing = scores.get(neighbor) ?? 0;\n scores.set(neighbor, existing + score);\n\n const prev = provenance.get(neighbor);\n if (\n !prev ||\n hop + 1 < prev.hopDepth ||\n (hop + 1 === prev.hopDepth && score > prev.decayedWeight)\n ) {\n provenance.set(neighbor, {\n seed: sourceSeed,\n hopDepth: hop + 1,\n decayedWeight: score,\n graphType: edge.type,\n edgeConfidence: conf,\n });\n }\n }\n\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push([neighbor, hop + 1, sourceSeed]);\n }\n }\n }\n\n // Issue #681 PR 3/3 — optional PageRank-style refinement.\n // Redistributes a node's accumulated activation along its outgoing\n // edges, weighted by edge confidence. Damping is fixed at the\n // canonical 0.85 so the ranking stays comparable across queries;\n // the `iterations` knob bounds compute, not behavior shape.\n if (iterations > 0 && scores.size > 1) {\n applyPageRankRefinement(scores, adj, {\n iterations,\n floor,\n damping: 0.85,\n });\n }\n\n // Apply lateral inhibition if enabled (Synapse-inspired competitive suppression)\n if (this.cfg.graphLateralInhibitionEnabled && scores.size > 1) {\n const inhibited = applyLateralInhibition(scores, {\n beta: this.cfg.graphLateralInhibitionBeta,\n topM: this.cfg.graphLateralInhibitionTopM,\n });\n for (const [k, v] of inhibited) {\n scores.set(k, v);\n }\n }\n\n return Array.from(scores.entries())\n .map(([p, score]) => ({\n path: p,\n score,\n seed: provenance.get(p)?.seed ?? \"\",\n hopDepth: provenance.get(p)?.hopDepth ?? 0,\n decayedWeight: provenance.get(p)?.decayedWeight ?? 0,\n graphType: provenance.get(p)?.graphType ?? \"entity\",\n edgeConfidence: provenance.get(p)?.edgeConfidence ?? 1,\n }))\n .sort((a, b) => b.score - a.score);\n } catch (err) {\n const { log } = await import(\"./logger.js\");\n log.warn(`[graph] spreadingActivation error: ${err}`);\n return [];\n }\n }\n}\n\n/**\n * Clamp `graphTraversalConfidenceFloor` into the legal range `[0, 1]`.\n * Non-finite or non-numeric values fall back to the documented default\n * so misconfiguration cannot silently disable the floor or reject every edge.\n *\n * Exported for tests; call sites in `spreadingActivation` use it to make\n * the contract explicit at every boundary.\n */\nexport function clampConfidenceFloor(raw: unknown): number {\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n return DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR;\n }\n if (raw < 0) return 0;\n if (raw > 1) return 1;\n return raw;\n}\n\n/**\n * Clamp `graphTraversalPageRankIterations` into a non-negative integer.\n * Negative or non-finite values fall back to 0 (disable refinement) so\n * misconfiguration cannot stall recall in an unbounded loop.\n */\nexport function clampPageRankIterations(raw: unknown): number {\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) return 0;\n if (raw <= 0) return 0;\n return Math.floor(raw);\n}\n\n/**\n * PageRank-style refinement on top of the BFS activation map.\n *\n * Each iteration redistributes a fraction of every node's score along\n * its outgoing edges, scaled by edge confidence. Confidence below\n * `floor` is filtered out before redistribution, mirroring the BFS\n * pruning rule. Mutates `scores` in place.\n *\n * Exported for tests; in production, call sites pass the same adjacency\n * map already used by BFS so behavior stays consistent.\n */\nexport function applyPageRankRefinement(\n scores: Map<string, number>,\n adj: Map<string, GraphEdge[]>,\n opts: { iterations: number; floor: number; damping: number },\n): void {\n const { iterations, floor, damping } = opts;\n if (iterations <= 0 || scores.size === 0) return;\n const safeDamping = Math.min(1, Math.max(0, damping));\n\n // Pre-compute confidence-weighted out-edge totals for normalization.\n // Done once per refinement, not per iteration, since adjacency is\n // immutable inside the loop.\n //\n // Codex P1 (#735): the denominator MUST be computed over the same\n // eligible-neighbor set the iteration redistributes into — i.e.\n // edges whose neighbor is in `scores`. Counting edges-to-seeds (or\n // edges-to-unseen-nodes) in the denominator while dropping their\n // flow during iteration leaks `safeDamping × score` every pass and\n // collapses leaf candidates' scores instead of just re-ranking them.\n const eligible = (edge: GraphEdge, fromNode: string): boolean => {\n if (readEdgeConfidence(edge) < floor) return false;\n const neighbor = edge.to === fromNode ? edge.from : edge.to;\n return scores.has(neighbor);\n };\n const outboundTotal = new Map<string, number>();\n for (const [node, edges] of adj.entries()) {\n if (!scores.has(node)) continue; // only candidate nodes redistribute\n let sum = 0;\n for (const edge of edges) {\n if (!eligible(edge, node)) continue;\n sum += readEdgeConfidence(edge) * edge.weight;\n }\n if (sum > 0) outboundTotal.set(node, sum);\n }\n\n for (let i = 0; i < iterations; i += 1) {\n const next = new Map<string, number>();\n // Teleport / damping floor: every node retains `(1 - damping) * score`\n // of its current activation so dangling nodes do not bleed to zero.\n for (const [node, score] of scores) {\n next.set(node, (1 - safeDamping) * score);\n }\n for (const [node, score] of scores) {\n const outEdges = adj.get(node);\n const total = outboundTotal.get(node);\n // Dangling-node fallback: when a candidate has zero eligible\n // outflow (no in-scores neighbors above the floor), the\n // `safeDamping × score` portion would otherwise evaporate. Keep\n // it on `node` so total mass is conserved and the score reflects\n // the candidate's standing rather than its in-degree topology.\n if (!outEdges || outEdges.length === 0 || !total || total <= 0) {\n next.set(node, (next.get(node) ?? 0) + safeDamping * score);\n continue;\n }\n for (const edge of outEdges) {\n if (!eligible(edge, node)) continue;\n const conf = readEdgeConfidence(edge);\n const neighbor = edge.to === node ? edge.from : edge.to;\n const flow = safeDamping * score * ((conf * edge.weight) / total);\n next.set(neighbor, (next.get(neighbor) ?? 0) + flow);\n }\n }\n for (const [node, score] of next) {\n scores.set(node, score);\n }\n }\n}\n\n/**\n * Lateral inhibition (Synapse-inspired).\n *\n * For each node, the top-M higher-activation competitors exert inhibition\n * proportional to their activation difference. Output is clamped to [0, ∞).\n *\n * No sigmoid is applied here — downstream `normalizeGraphActivationScore`\n * already applies x/(1+x) soft squash, so adding a sigmoid would double-\n * normalize and cap graph influence at ~50%.\n *\n * Formula: u_hat_i = max(0, u_i - beta * sum_{k in top-M where u_k > u_i}(u_k - u_i))\n *\n * When beta=0 or topM=0, returns original scores unchanged (no-op).\n */\nexport function applyLateralInhibition(\n scores: Map<string, number>,\n opts: { beta: number; topM: number },\n): Map<string, number> {\n const { beta, topM } = opts;\n if (beta === 0 || topM === 0) return new Map(scores);\n\n const sorted = Array.from(scores.entries()).sort((a, b) => b[1] - a[1]);\n const topCompetitors = sorted.slice(0, topM);\n\n const result = new Map<string, number>();\n for (const [node, u] of scores) {\n let inhibition = 0;\n for (const [, uK] of topCompetitors) {\n if (uK > u) {\n inhibition += uK - u;\n }\n }\n result.set(node, Math.max(0, u - beta * inhibition));\n }\n\n return result;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -28,6 +28,9 @@ function inferMemoryStatus(frontmatter, pathRel, fallbackStatus = "active") {
|
|
|
28
28
|
if (frontmatter.status) return frontmatter.status;
|
|
29
29
|
return fallbackStatus;
|
|
30
30
|
}
|
|
31
|
+
function isActiveMemoryStatus(status) {
|
|
32
|
+
return status === void 0 || status === "active";
|
|
33
|
+
}
|
|
31
34
|
function summarizeMemoryLifecycleState(memory) {
|
|
32
35
|
return {
|
|
33
36
|
category: memory.frontmatter.category,
|
|
@@ -85,9 +88,10 @@ export {
|
|
|
85
88
|
toMemoryPathRel,
|
|
86
89
|
isArchivedMemoryPath,
|
|
87
90
|
inferMemoryStatus,
|
|
91
|
+
isActiveMemoryStatus,
|
|
88
92
|
summarizeMemoryLifecycleState,
|
|
89
93
|
makeRebuiltMemoryLifecycleEvent,
|
|
90
94
|
buildLifecycleEventsForMemory,
|
|
91
95
|
sortMemoryLifecycleEvents
|
|
92
96
|
};
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-RULE4VG5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory-lifecycle-ledger-utils.ts"],"sourcesContent":["import path from \"node:path\";\nimport type {\n MemoryFile,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryFrontmatter,\n MemoryStatus,\n} from \"./types.js\";\n\nexport const MEMORY_LIFECYCLE_RULE_VERSION = \"memory-lifecycle-ledger.v1\";\n\nexport const MEMORY_LIFECYCLE_EVENT_SORT_ORDER: Record<MemoryLifecycleEventType, number> = {\n created: 0,\n updated: 1,\n promoted: 2,\n explicit_capture_accepted: 3,\n explicit_capture_queued: 4,\n imported: 5,\n merged: 6,\n restored: 7,\n superseded: 8,\n rejected: 9,\n archived: 10,\n};\n\nexport function toMemoryPathRel(baseDir: string, filePath: string): string {\n if (!baseDir) return filePath.split(path.sep).join(\"/\");\n return path.relative(baseDir, filePath).split(path.sep).join(\"/\");\n}\n\nexport function isArchivedMemoryPath(pathRel: string): boolean {\n return pathRel === \"archive\" || pathRel.startsWith(\"archive/\");\n}\n\nexport function inferMemoryStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus = \"active\",\n): MemoryStatus {\n if (frontmatter.status && frontmatter.status !== \"active\") return frontmatter.status;\n if (frontmatter.archivedAt) return \"archived\";\n if (isArchivedMemoryPath(pathRel)) return \"archived\";\n if (frontmatter.status) return frontmatter.status;\n return fallbackStatus;\n}\n\nexport function isActiveMemoryStatus(status: MemoryStatus | string | undefined): boolean {\n return status === undefined || status === \"active\";\n}\n\nexport function summarizeMemoryLifecycleState(memory: MemoryFile): MemoryLifecycleStateSummary {\n return {\n category: memory.frontmatter.category,\n path: memory.path,\n status: memory.frontmatter.status ?? \"active\",\n lifecycleState: memory.frontmatter.lifecycleState,\n };\n}\n\nexport function makeRebuiltMemoryLifecycleEvent(\n memory: MemoryFile,\n eventType: MemoryLifecycleEventType,\n timestamp: string,\n): MemoryLifecycleEvent {\n return {\n eventId: `rebuild-${memory.frontmatter.id}-${eventType}-${timestamp}`,\n memoryId: memory.frontmatter.id,\n eventType,\n timestamp,\n actor: \"maintenance.rebuildMemoryLifecycleLedger\",\n ruleVersion: MEMORY_LIFECYCLE_RULE_VERSION,\n after: summarizeMemoryLifecycleState(memory),\n relatedMemoryIds: [\n ...(memory.frontmatter.supersededBy ? [memory.frontmatter.supersededBy] : []),\n ...(memory.frontmatter.supersedes ? [memory.frontmatter.supersedes] : []),\n ...((memory.frontmatter.lineage ?? []).filter(Boolean)),\n ],\n };\n}\n\nexport function buildLifecycleEventsForMemory(memory: MemoryFile): MemoryLifecycleEvent[] {\n const events: MemoryLifecycleEvent[] = [];\n const created = memory.frontmatter.created;\n const updated = memory.frontmatter.updated;\n const archivedAt = memory.frontmatter.archivedAt;\n const supersededAt = memory.frontmatter.supersededAt;\n const effectiveArchivedAt =\n archivedAt ?? (memory.frontmatter.status === \"archived\" && updated ? updated : undefined);\n\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"created\", created));\n if (\n updated &&\n updated !== created &&\n updated !== effectiveArchivedAt &&\n updated !== supersededAt\n ) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"updated\", updated));\n }\n if (supersededAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"superseded\", supersededAt));\n }\n if (effectiveArchivedAt) {\n events.push(makeRebuiltMemoryLifecycleEvent(memory, \"archived\", effectiveArchivedAt));\n }\n\n return events;\n}\n\nexport function sortMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): MemoryLifecycleEvent[] {\n return [...events].sort((a, b) => {\n if (a.memoryId !== b.memoryId) return a.memoryId.localeCompare(b.memoryId);\n if (a.timestamp !== b.timestamp) return a.timestamp.localeCompare(b.timestamp);\n return MEMORY_LIFECYCLE_EVENT_SORT_ORDER[a.eventType] - MEMORY_LIFECYCLE_EVENT_SORT_ORDER[b.eventType];\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseXrayFormat
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LW2NMHDW.js";
|
|
4
|
+
import {
|
|
5
|
+
RECALL_DISCLOSURE_LEVELS,
|
|
6
|
+
isRecallDisclosure
|
|
7
|
+
} from "./chunk-43EKP2UK.js";
|
|
4
8
|
|
|
5
9
|
// src/recall-xray-cli.ts
|
|
10
|
+
function parseXrayDisclosureFlag(value) {
|
|
11
|
+
if (value === void 0 || value === null) return void 0;
|
|
12
|
+
if (typeof value !== "string" || !isRecallDisclosure(value)) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`--disclosure expects one of ${RECALL_DISCLOSURE_LEVELS.join(", ")}; got ${JSON.stringify(value)}`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
6
19
|
function parseXrayBudgetFlag(value) {
|
|
7
20
|
if (value === void 0 || value === null) return void 0;
|
|
8
21
|
const parsed = typeof value === "number" ? value : Number(value);
|
|
@@ -21,17 +34,20 @@ function parseXrayCliOptions(rawQuery, options) {
|
|
|
21
34
|
const budget = parseXrayBudgetFlag(options.budget);
|
|
22
35
|
const namespace = typeof options.namespace === "string" && options.namespace.trim().length > 0 ? options.namespace.trim() : void 0;
|
|
23
36
|
const outPath = typeof options.out === "string" && options.out.trim().length > 0 ? options.out.trim() : void 0;
|
|
37
|
+
const disclosure = parseXrayDisclosureFlag(options.disclosure);
|
|
24
38
|
return {
|
|
25
39
|
query: rawQuery,
|
|
26
40
|
format,
|
|
27
41
|
...budget !== void 0 ? { budget } : {},
|
|
28
42
|
...namespace !== void 0 ? { namespace } : {},
|
|
29
|
-
...outPath !== void 0 ? { outPath } : {}
|
|
43
|
+
...outPath !== void 0 ? { outPath } : {},
|
|
44
|
+
...disclosure !== void 0 ? { disclosure } : {}
|
|
30
45
|
};
|
|
31
46
|
}
|
|
32
47
|
|
|
33
48
|
export {
|
|
49
|
+
parseXrayDisclosureFlag,
|
|
34
50
|
parseXrayBudgetFlag,
|
|
35
51
|
parseXrayCliOptions
|
|
36
52
|
};
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-SMA4IMHV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recall-xray-cli.ts"],"sourcesContent":["/**\n * Input-validation helpers for the `remnic xray` CLI command (issue\n * #570, PR 3).\n *\n * Pulled out of `cli.ts` so the validation paths can be unit-tested in\n * isolation — the full CLI handler is hard to exercise without booting\n * an orchestrator. CLAUDE.md rules 14 + 51 require that `--format`,\n * `--budget`, `--namespace`, and `--out` reject missing-value /\n * unknown / non-positive arguments with a listed-options error, rather\n * than silently defaulting.\n */\n\nimport {\n parseXrayFormat,\n type RecallXrayFormat,\n} from \"./recall-xray-renderer.js\";\nimport {\n isRecallDisclosure,\n RECALL_DISCLOSURE_LEVELS,\n type RecallDisclosure,\n} from \"./types.js\";\n\nexport interface ParsedXrayCliOptions {\n format: RecallXrayFormat;\n /** Positive integer override, or undefined when not specified. */\n budget?: number;\n /** Trimmed namespace, or undefined when not specified. */\n namespace?: string;\n /** Trimmed, tilde-unexpanded output path, or undefined when stdout. */\n outPath?: string;\n /** Disclosure depth for X-ray telemetry, or undefined when not specified. */\n disclosure?: RecallDisclosure;\n}\n\n/**\n * Validate and coerce `--disclosure <level>`. Must be one of the\n * canonical levels; throws a listed-options error otherwise.\n */\nexport function parseXrayDisclosureFlag(value: unknown): RecallDisclosure | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\" || !isRecallDisclosure(value)) {\n throw new Error(\n `--disclosure expects one of ${RECALL_DISCLOSURE_LEVELS.join(\", \")}; got ${JSON.stringify(value)}`,\n );\n }\n return value;\n}\n\n/**\n * Validate and coerce `--budget <chars>`. Must be a positive integer;\n * throws a listed-options error otherwise.\n */\nexport function parseXrayBudgetFlag(value: unknown): number | undefined {\n if (value === undefined || value === null) return undefined;\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (\n !Number.isFinite(parsed) ||\n parsed <= 0 ||\n !Number.isInteger(parsed)\n ) {\n throw new Error(\n `--budget expects a positive integer; got ${JSON.stringify(value)}`,\n );\n }\n return parsed;\n}\n\n/**\n * Parse and validate the full option bag for `remnic xray`. Extracted\n * so the CLI handler in `cli.ts` can stay thin and the validation can\n * be unit-tested without booting an orchestrator.\n */\nexport function parseXrayCliOptions(\n rawQuery: unknown,\n options: Record<string, unknown>,\n): { query: string } & ParsedXrayCliOptions {\n if (typeof rawQuery !== \"string\" || rawQuery.trim().length === 0) {\n throw new Error(\"xray: <query> is required and must be non-empty\");\n }\n const format = parseXrayFormat(options.format);\n const budget = parseXrayBudgetFlag(options.budget);\n const namespace =\n typeof options.namespace === \"string\" &&\n options.namespace.trim().length > 0\n ? options.namespace.trim()\n : undefined;\n const outPath =\n typeof options.out === \"string\" && options.out.trim().length > 0\n ? options.out.trim()\n : undefined;\n const disclosure = parseXrayDisclosureFlag(options.disclosure);\n return {\n query: rawQuery,\n format,\n ...(budget !== undefined ? { budget } : {}),\n ...(namespace !== undefined ? { namespace } : {}),\n ...(outPath !== undefined ? { outPath } : {}),\n ...(disclosure !== undefined ? { disclosure } : {}),\n };\n}\n"],"mappings":";;;;;;;;;AAsCO,SAAS,wBAAwB,OAA8C;AACpF,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,YAAY,CAAC,mBAAmB,KAAK,GAAG;AAC3D,UAAM,IAAI;AAAA,MACR,+BAA+B,yBAAyB,KAAK,IAAI,CAAC,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,IAClG;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,oBAAoB,OAAoC;AACtE,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAC/D,MACE,CAAC,OAAO,SAAS,MAAM,KACvB,UAAU,KACV,CAAC,OAAO,UAAU,MAAM,GACxB;AACA,UAAM,IAAI;AAAA,MACR,4CAA4C,KAAK,UAAU,KAAK,CAAC;AAAA,IACnE;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,oBACd,UACA,SAC0C;AAC1C,MAAI,OAAO,aAAa,YAAY,SAAS,KAAK,EAAE,WAAW,GAAG;AAChE,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,QAAM,SAAS,gBAAgB,QAAQ,MAAM;AAC7C,QAAM,SAAS,oBAAoB,QAAQ,MAAM;AACjD,QAAM,YACJ,OAAO,QAAQ,cAAc,YAC7B,QAAQ,UAAU,KAAK,EAAE,SAAS,IAC9B,QAAQ,UAAU,KAAK,IACvB;AACN,QAAM,UACJ,OAAO,QAAQ,QAAQ,YAAY,QAAQ,IAAI,KAAK,EAAE,SAAS,IAC3D,QAAQ,IAAI,KAAK,IACjB;AACN,QAAM,aAAa,wBAAwB,QAAQ,UAAU;AAC7D,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
StorageManager
|
|
3
|
-
|
|
2
|
+
StorageManager,
|
|
3
|
+
normalizeEntityName
|
|
4
|
+
} from "./chunk-DCE6SQLA.js";
|
|
4
5
|
import {
|
|
5
6
|
readEnvVar,
|
|
6
7
|
resolveHomeDir
|
|
@@ -73,21 +74,29 @@ function parseBriefingFocus(token) {
|
|
|
73
74
|
}
|
|
74
75
|
return { type: "topic", value: trimmed };
|
|
75
76
|
}
|
|
76
|
-
function focusToEntityRefSlug(focus) {
|
|
77
|
-
const sluggedValue = focus.value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
78
|
-
return `${focus.type}-${sluggedValue}`;
|
|
79
|
-
}
|
|
80
77
|
function focusMatchesMemory(memory, focus) {
|
|
81
78
|
const needle = focus.value.toLowerCase();
|
|
82
79
|
const entityRef = (memory.frontmatter.entityRef ?? "").toLowerCase();
|
|
83
|
-
const
|
|
80
|
+
const rawHaystackParts = [
|
|
84
81
|
memory.content,
|
|
85
|
-
entityRef,
|
|
86
82
|
...memory.frontmatter.tags ?? []
|
|
87
|
-
]
|
|
83
|
+
];
|
|
84
|
+
if (focus.type === "topic" && entityRef) {
|
|
85
|
+
rawHaystackParts.push(entityRef);
|
|
86
|
+
}
|
|
87
|
+
const rawHaystack = rawHaystackParts.join(" ").toLowerCase();
|
|
88
88
|
if (rawHaystack.includes(needle)) return true;
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
if (!entityRef) return false;
|
|
90
|
+
const focusCanonical = normalizeEntityName(focus.value, focus.type);
|
|
91
|
+
let refForNormalize = entityRef;
|
|
92
|
+
const typeDelimMatch = refForNormalize.match(
|
|
93
|
+
new RegExp(`^${focus.type}[^a-z0-9]+`, "i")
|
|
94
|
+
);
|
|
95
|
+
if (typeDelimMatch) {
|
|
96
|
+
refForNormalize = refForNormalize.slice(typeDelimMatch[0].length);
|
|
97
|
+
}
|
|
98
|
+
const refCanonical = normalizeEntityName(refForNormalize, focus.type);
|
|
99
|
+
return refCanonical === focusCanonical;
|
|
91
100
|
}
|
|
92
101
|
function focusMatchesEntity(entity, focus) {
|
|
93
102
|
const needle = focus.value.toLowerCase();
|
|
@@ -527,7 +536,7 @@ function filterMemoriesByWindow(memories, window) {
|
|
|
527
536
|
const toMs = window.to.getTime();
|
|
528
537
|
return memories.filter((m) => {
|
|
529
538
|
const status = m.frontmatter.status;
|
|
530
|
-
if (status === "superseded" || status === "archived" || status === "rejected" || status === "quarantined") {
|
|
539
|
+
if (status === "superseded" || status === "archived" || status === "rejected" || status === "quarantined" || status === "forgotten") {
|
|
531
540
|
return false;
|
|
532
541
|
}
|
|
533
542
|
const ts = memoryTimestamp(m);
|
|
@@ -815,4 +824,4 @@ export {
|
|
|
815
824
|
resolveBriefingSaveDir,
|
|
816
825
|
briefingFilename
|
|
817
826
|
};
|
|
818
|
-
//# sourceMappingURL=chunk-
|
|
827
|
+
//# sourceMappingURL=chunk-SS253RXF.js.map
|