@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,14 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
importCapsule
|
|
3
|
+
} from "./chunk-3KIS4VGT.js";
|
|
4
|
+
import {
|
|
5
|
+
applyTagFilter,
|
|
6
|
+
normalizeTags,
|
|
7
|
+
parseTagMatch
|
|
8
|
+
} from "./chunk-BT7NVCML.js";
|
|
9
|
+
import {
|
|
10
|
+
decideDisclosureEscalation
|
|
11
|
+
} from "./chunk-H7XKCNR6.js";
|
|
1
12
|
import {
|
|
2
13
|
toRecallExplainJson
|
|
3
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LW2NMHDW.js";
|
|
4
15
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
listMemoryGovernanceRuns,
|
|
9
|
-
readMemoryGovernanceRunArtifact,
|
|
10
|
-
runMemoryGovernance
|
|
11
|
-
} from "./chunk-3OGMS3PE.js";
|
|
16
|
+
clusterByKey,
|
|
17
|
+
resolveGitContext
|
|
18
|
+
} from "./chunk-NN3TS5BM.js";
|
|
12
19
|
import {
|
|
13
20
|
getTrustZoneStoreStatus,
|
|
14
21
|
isTrustZoneName,
|
|
@@ -18,9 +25,28 @@ import {
|
|
|
18
25
|
seedTrustZoneDemoDataset,
|
|
19
26
|
summarizeTrustZonePromotionReadiness
|
|
20
27
|
} from "./chunk-EQINRHYR.js";
|
|
28
|
+
import {
|
|
29
|
+
estimateRecallTokens
|
|
30
|
+
} from "./chunk-USFPPRAF.js";
|
|
31
|
+
import {
|
|
32
|
+
buildProposedActions,
|
|
33
|
+
buildQualityScore,
|
|
34
|
+
groupActionsByStatus,
|
|
35
|
+
listMemoryGovernanceRuns,
|
|
36
|
+
readMemoryGovernanceRunArtifact,
|
|
37
|
+
runMemoryGovernance
|
|
38
|
+
} from "./chunk-LZRYQK6L.js";
|
|
21
39
|
import {
|
|
22
40
|
recordMemoryOutcome
|
|
23
41
|
} from "./chunk-EIR5VLIH.js";
|
|
42
|
+
import {
|
|
43
|
+
buildGraphSnapshot
|
|
44
|
+
} from "./chunk-PCUKNJAZ.js";
|
|
45
|
+
import {
|
|
46
|
+
persistExplicitCapture,
|
|
47
|
+
queueExplicitCaptureForReview,
|
|
48
|
+
validateExplicitCaptureInput
|
|
49
|
+
} from "./chunk-3FPTCC3Z.js";
|
|
24
50
|
import {
|
|
25
51
|
wrapWorkLayerContext
|
|
26
52
|
} from "./chunk-EEQLFRUM.js";
|
|
@@ -28,18 +54,16 @@ import {
|
|
|
28
54
|
buildProcedurePersistBody,
|
|
29
55
|
normalizeProcedureSteps
|
|
30
56
|
} from "./chunk-QDW3E4RD.js";
|
|
31
|
-
import {
|
|
32
|
-
persistExplicitCapture,
|
|
33
|
-
queueExplicitCaptureForReview,
|
|
34
|
-
validateExplicitCaptureInput
|
|
35
|
-
} from "./chunk-3FPTCC3Z.js";
|
|
36
57
|
import {
|
|
37
58
|
CrossNamespaceBudget
|
|
38
59
|
} from "./chunk-GDFS42HT.js";
|
|
39
60
|
import {
|
|
40
61
|
filterTrajectoriesByLookbackDays,
|
|
41
62
|
readCausalTrajectoryRecords
|
|
42
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-G2WADRQ3.js";
|
|
64
|
+
import {
|
|
65
|
+
defaultCapsulesDir
|
|
66
|
+
} from "./chunk-74EMIVE4.js";
|
|
43
67
|
import {
|
|
44
68
|
canReadNamespace,
|
|
45
69
|
canWriteNamespace,
|
|
@@ -52,14 +76,18 @@ import {
|
|
|
52
76
|
buildBriefing,
|
|
53
77
|
parseBriefingFocus,
|
|
54
78
|
parseBriefingWindow
|
|
55
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-SS253RXF.js";
|
|
56
80
|
import {
|
|
57
81
|
parseEntityFile
|
|
58
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-DCE6SQLA.js";
|
|
83
|
+
import {
|
|
84
|
+
DEFAULT_RECALL_DISCLOSURE,
|
|
85
|
+
isRecallDisclosure
|
|
86
|
+
} from "./chunk-43EKP2UK.js";
|
|
59
87
|
import {
|
|
60
88
|
inferMemoryStatus,
|
|
61
89
|
toMemoryPathRel
|
|
62
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-RULE4VG5.js";
|
|
63
91
|
import {
|
|
64
92
|
normalizeProjectionPreview,
|
|
65
93
|
normalizeProjectionTags
|
|
@@ -77,9 +105,15 @@ import {
|
|
|
77
105
|
AccessIdempotencyStore,
|
|
78
106
|
hashAccessIdempotencyPayload
|
|
79
107
|
} from "./chunk-XKECPATV.js";
|
|
108
|
+
import {
|
|
109
|
+
exportCapsule
|
|
110
|
+
} from "./chunk-IYY4MCPG.js";
|
|
80
111
|
|
|
81
112
|
// src/access-service.ts
|
|
82
113
|
import { stat } from "fs/promises";
|
|
114
|
+
import * as nodeFs from "fs/promises";
|
|
115
|
+
import { constants as fsConstants } from "fs";
|
|
116
|
+
import { ZodError } from "zod";
|
|
83
117
|
|
|
84
118
|
// src/work/storage.ts
|
|
85
119
|
import path from "path";
|
|
@@ -747,13 +781,7 @@ async function runProcedureMining(options) {
|
|
|
747
781
|
causalTrajectoryStoreDir: trajectoryDir
|
|
748
782
|
});
|
|
749
783
|
const recent = filterTrajectoriesByLookbackDays(trajectories, cfg.lookbackDays);
|
|
750
|
-
const clusters =
|
|
751
|
-
for (const t of recent) {
|
|
752
|
-
const key = clusterKey(t);
|
|
753
|
-
const arr = clusters.get(key) ?? [];
|
|
754
|
-
arr.push(t);
|
|
755
|
-
clusters.set(key, arr);
|
|
756
|
-
}
|
|
784
|
+
const clusters = clusterByKey(recent, clusterKey);
|
|
757
785
|
let clustersProcessed = 0;
|
|
758
786
|
let proceduresWritten = 0;
|
|
759
787
|
for (const [key, group] of clusters) {
|
|
@@ -906,8 +934,21 @@ function formatProcedureStatsText(report) {
|
|
|
906
934
|
}
|
|
907
935
|
|
|
908
936
|
// src/access-service.ts
|
|
937
|
+
import * as nodePath from "path";
|
|
909
938
|
var EngramAccessInputError = class extends Error {
|
|
910
939
|
};
|
|
940
|
+
var cachedPackageVersion = null;
|
|
941
|
+
async function getPackageVersion() {
|
|
942
|
+
if (cachedPackageVersion !== null) return cachedPackageVersion;
|
|
943
|
+
try {
|
|
944
|
+
const raw = await nodeFs.readFile(new URL("../package.json", import.meta.url), "utf-8");
|
|
945
|
+
const parsed = JSON.parse(raw);
|
|
946
|
+
cachedPackageVersion = typeof parsed.version === "string" && parsed.version.length > 0 ? parsed.version : "unknown";
|
|
947
|
+
} catch {
|
|
948
|
+
cachedPackageVersion = "unknown";
|
|
949
|
+
}
|
|
950
|
+
return cachedPackageVersion;
|
|
951
|
+
}
|
|
911
952
|
function normalizeTrustZoneInputError(error) {
|
|
912
953
|
const message = error instanceof Error ? error.message : null;
|
|
913
954
|
if (!message) {
|
|
@@ -1020,6 +1061,23 @@ function compareBrowseMemory(sort, left, right) {
|
|
|
1020
1061
|
return rightUpdated.localeCompare(leftUpdated) || rightCreated.localeCompare(leftCreated) || left.frontmatter.id.localeCompare(right.frontmatter.id);
|
|
1021
1062
|
}
|
|
1022
1063
|
}
|
|
1064
|
+
function shapeMemorySummary(memory, baseDir, disclosure, rawExcerpts) {
|
|
1065
|
+
const includeFullContent = disclosure === "section" || disclosure === "raw";
|
|
1066
|
+
return {
|
|
1067
|
+
id: memory.frontmatter.id,
|
|
1068
|
+
path: memory.path,
|
|
1069
|
+
category: memory.frontmatter.category,
|
|
1070
|
+
status: inferMemoryStatus(memory.frontmatter, toMemoryPathRel(baseDir, memory.path)),
|
|
1071
|
+
created: memory.frontmatter.created,
|
|
1072
|
+
updated: memory.frontmatter.updated,
|
|
1073
|
+
tags: normalizeProjectionTags(memory.frontmatter.tags),
|
|
1074
|
+
entityRef: memory.frontmatter.entityRef,
|
|
1075
|
+
preview: normalizeProjectionPreview(memory.content),
|
|
1076
|
+
...disclosure !== void 0 ? { disclosure } : {},
|
|
1077
|
+
...includeFullContent ? { content: memory.content } : {},
|
|
1078
|
+
...disclosure === "raw" && rawExcerpts !== void 0 ? { rawExcerpts } : {}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1023
1081
|
var EngramAccessService = class {
|
|
1024
1082
|
constructor(orchestrator) {
|
|
1025
1083
|
this.orchestrator = orchestrator;
|
|
@@ -1127,29 +1185,90 @@ var EngramAccessService = class {
|
|
|
1127
1185
|
graph
|
|
1128
1186
|
} : void 0;
|
|
1129
1187
|
}
|
|
1130
|
-
async serializeRecallResults(snapshot) {
|
|
1188
|
+
async serializeRecallResults(snapshot, disclosure, rawContext = null) {
|
|
1131
1189
|
if (!snapshot) return [];
|
|
1132
1190
|
const namespace = snapshot.namespace ? this.resolveNamespace(snapshot.namespace) : this.orchestrator.config.defaultNamespace;
|
|
1133
1191
|
const storage = await this.orchestrator.getStorage(namespace);
|
|
1134
1192
|
const storageDir = storage.dir;
|
|
1135
1193
|
const results = [];
|
|
1136
1194
|
const seen = /* @__PURE__ */ new Set();
|
|
1195
|
+
const rawExcerptsResult = await this.fetchRawExcerpts(
|
|
1196
|
+
disclosure,
|
|
1197
|
+
rawContext ? { ...rawContext, namespace } : null
|
|
1198
|
+
);
|
|
1199
|
+
const rawExcerpts = rawExcerptsResult ?? void 0;
|
|
1137
1200
|
for (const memoryPath of snapshot.resultPaths ?? []) {
|
|
1138
1201
|
if (!memoryPath || seen.has(memoryPath)) continue;
|
|
1139
1202
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
1140
1203
|
if (!memory) continue;
|
|
1141
1204
|
seen.add(memoryPath);
|
|
1142
|
-
results.push(
|
|
1205
|
+
results.push(
|
|
1206
|
+
this.serializeMemorySummary(
|
|
1207
|
+
memory,
|
|
1208
|
+
storageDir,
|
|
1209
|
+
disclosure,
|
|
1210
|
+
// Attach the (possibly empty) raw excerpts to the first raw
|
|
1211
|
+
// result; subsequent results do not duplicate the array.
|
|
1212
|
+
results.length === 0 ? rawExcerpts : void 0
|
|
1213
|
+
)
|
|
1214
|
+
);
|
|
1143
1215
|
}
|
|
1144
1216
|
if (results.length > 0) return results;
|
|
1145
1217
|
for (const memoryId of snapshot.memoryIds) {
|
|
1146
1218
|
const memory = await storage.getMemoryById(memoryId);
|
|
1147
1219
|
if (!memory || seen.has(memory.path)) continue;
|
|
1148
1220
|
seen.add(memory.path);
|
|
1149
|
-
results.push(
|
|
1221
|
+
results.push(
|
|
1222
|
+
this.serializeMemorySummary(
|
|
1223
|
+
memory,
|
|
1224
|
+
storageDir,
|
|
1225
|
+
disclosure,
|
|
1226
|
+
results.length === 0 ? rawExcerpts : void 0
|
|
1227
|
+
)
|
|
1228
|
+
);
|
|
1150
1229
|
}
|
|
1151
1230
|
return results;
|
|
1152
1231
|
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Fetch raw transcript excerpts from the LCM archive for `disclosure ===
|
|
1234
|
+
* "raw"` recalls (issue #677 PR 2/4). Returns `null` for non-raw recall
|
|
1235
|
+
* depths, an empty array when LCM is disabled / not initialized / has no
|
|
1236
|
+
* matches, and an array of LCM-side excerpts otherwise. Errors are
|
|
1237
|
+
* swallowed and treated as "no excerpts" so a failing LCM never breaks
|
|
1238
|
+
* the recall response.
|
|
1239
|
+
*
|
|
1240
|
+
* Namespace handling: LCM archival prefixes non-default-namespace
|
|
1241
|
+
* sessions with `${namespace}:${sessionKey}` (see `observe()` around
|
|
1242
|
+
* line 2498), so the lookup must mirror that prefix or raw recalls in
|
|
1243
|
+
* non-default namespaces miss their own excerpts.
|
|
1244
|
+
*/
|
|
1245
|
+
async fetchRawExcerpts(disclosure, context) {
|
|
1246
|
+
if (disclosure !== "raw") return null;
|
|
1247
|
+
if (!context || !context.query) return [];
|
|
1248
|
+
if (!context.sessionKey) return [];
|
|
1249
|
+
const lcm = this.orchestrator.lcmEngine;
|
|
1250
|
+
if (!lcm || !lcm.enabled) return [];
|
|
1251
|
+
try {
|
|
1252
|
+
const lcmSessionKey = context.namespace && context.namespace !== this.orchestrator.config.defaultNamespace ? `${context.namespace}:${context.sessionKey}` : context.sessionKey;
|
|
1253
|
+
const rows = await lcm.searchContextFull(
|
|
1254
|
+
context.query,
|
|
1255
|
+
// Cap the excerpt fanout so recall responses stay bounded. Five
|
|
1256
|
+
// matches is enough to anchor the model in the raw transcript
|
|
1257
|
+
// without ballooning token spend; raw is meant as the escape
|
|
1258
|
+
// hatch, not the default.
|
|
1259
|
+
5,
|
|
1260
|
+
lcmSessionKey
|
|
1261
|
+
);
|
|
1262
|
+
return rows.map((r) => ({
|
|
1263
|
+
turnIndex: r.turn_index,
|
|
1264
|
+
role: r.role,
|
|
1265
|
+
content: r.content,
|
|
1266
|
+
sessionId: r.session_id
|
|
1267
|
+
}));
|
|
1268
|
+
} catch {
|
|
1269
|
+
return [];
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1153
1272
|
async handleIdempotentWrite(options) {
|
|
1154
1273
|
if (options.skip === true) {
|
|
1155
1274
|
return options.execute();
|
|
@@ -1205,8 +1324,8 @@ var EngramAccessService = class {
|
|
|
1205
1324
|
async withIdempotencyLock(key, fn) {
|
|
1206
1325
|
const previous = this.idempotencyLocks.get(key) ?? Promise.resolve();
|
|
1207
1326
|
let release;
|
|
1208
|
-
const current = new Promise((
|
|
1209
|
-
release =
|
|
1327
|
+
const current = new Promise((resolve2) => {
|
|
1328
|
+
release = resolve2;
|
|
1210
1329
|
});
|
|
1211
1330
|
const queued = previous.then(() => current, () => current);
|
|
1212
1331
|
this.idempotencyLocks.set(key, queued);
|
|
@@ -1350,17 +1469,81 @@ var EngramAccessService = class {
|
|
|
1350
1469
|
defaultBranch: ctx.defaultBranch
|
|
1351
1470
|
});
|
|
1352
1471
|
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Auto-resolve and attach a coding context for a session when one is not
|
|
1474
|
+
* already present. Resolves from `projectTag` (highest priority after
|
|
1475
|
+
* explicit `codingContext`), then from `cwd` via git detection.
|
|
1476
|
+
*
|
|
1477
|
+
* This is a no-op when:
|
|
1478
|
+
* - `sessionKey` is missing
|
|
1479
|
+
* - the session already has a coding context attached
|
|
1480
|
+
* - codingMode.projectScope is disabled (CLAUDE.md #30)
|
|
1481
|
+
* - neither `cwd` nor `projectTag` is provided
|
|
1482
|
+
*
|
|
1483
|
+
* Never throws — git resolution failures are silently ignored because not
|
|
1484
|
+
* being in a repo is a normal runtime state.
|
|
1485
|
+
*/
|
|
1486
|
+
async maybeAttachCodingContext(sessionKey, options) {
|
|
1487
|
+
if (!sessionKey) return;
|
|
1488
|
+
if (!this.orchestrator.config.codingMode?.projectScope) return;
|
|
1489
|
+
if (this.orchestrator.getCodingContextForSession(sessionKey)) return;
|
|
1490
|
+
if (typeof options.projectTag === "string" && options.projectTag.trim().length > 0) {
|
|
1491
|
+
const tag = options.projectTag.trim();
|
|
1492
|
+
this.orchestrator.setCodingContextForSession(sessionKey, {
|
|
1493
|
+
projectId: `tag:${tag}`,
|
|
1494
|
+
branch: null,
|
|
1495
|
+
rootPath: `tag:${tag}`,
|
|
1496
|
+
defaultBranch: null
|
|
1497
|
+
});
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
if (typeof options.cwd === "string" && options.cwd.trim().length > 0) {
|
|
1501
|
+
try {
|
|
1502
|
+
const gitCtx = await resolveGitContext(options.cwd);
|
|
1503
|
+
if (gitCtx) {
|
|
1504
|
+
this.setCodingContext({
|
|
1505
|
+
sessionKey,
|
|
1506
|
+
codingContext: {
|
|
1507
|
+
projectId: gitCtx.projectId,
|
|
1508
|
+
branch: gitCtx.branch,
|
|
1509
|
+
rootPath: gitCtx.rootPath,
|
|
1510
|
+
defaultBranch: gitCtx.defaultBranch
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
} catch {
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1353
1518
|
async recall(request) {
|
|
1354
1519
|
const query = request.query.trim();
|
|
1355
1520
|
if (query.length === 0) {
|
|
1356
1521
|
throw new EngramAccessInputError("query is required");
|
|
1357
1522
|
}
|
|
1523
|
+
const callerProvidedDisclosure = request.disclosure !== void 0 && request.disclosure !== null;
|
|
1524
|
+
const requestedDisclosure = (() => {
|
|
1525
|
+
if (!callerProvidedDisclosure) {
|
|
1526
|
+
return DEFAULT_RECALL_DISCLOSURE;
|
|
1527
|
+
}
|
|
1528
|
+
if (!isRecallDisclosure(request.disclosure)) {
|
|
1529
|
+
throw new EngramAccessInputError(
|
|
1530
|
+
`disclosure must be one of: chunk, section, raw (got: ${String(request.disclosure)})`
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
return request.disclosure;
|
|
1534
|
+
})();
|
|
1358
1535
|
if (request.codingContext !== void 0 && request.sessionKey) {
|
|
1359
1536
|
this.setCodingContext({
|
|
1360
1537
|
sessionKey: request.sessionKey,
|
|
1361
1538
|
codingContext: request.codingContext
|
|
1362
1539
|
});
|
|
1363
1540
|
}
|
|
1541
|
+
if (request.codingContext === void 0 && request.sessionKey) {
|
|
1542
|
+
await this.maybeAttachCodingContext(request.sessionKey, {
|
|
1543
|
+
cwd: request.cwd,
|
|
1544
|
+
projectTag: request.projectTag
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1364
1547
|
const namespaceOverride = this.resolveRecallNamespace(request.namespace, request.sessionKey);
|
|
1365
1548
|
const namespace = namespaceOverride ?? this.orchestrator.config.defaultNamespace;
|
|
1366
1549
|
const mode = this.normalizeRecallMode(request.mode);
|
|
@@ -1421,16 +1604,77 @@ var EngramAccessService = class {
|
|
|
1421
1604
|
this.budget.gc();
|
|
1422
1605
|
}
|
|
1423
1606
|
const topK = Number.isFinite(request.topK) ? Math.max(0, Math.floor(request.topK ?? 0)) : void 0;
|
|
1607
|
+
let asOf;
|
|
1608
|
+
if (request.asOf !== void 0 && request.asOf !== null) {
|
|
1609
|
+
if (typeof request.asOf !== "string" || request.asOf.trim().length === 0) {
|
|
1610
|
+
throw new EngramAccessInputError(
|
|
1611
|
+
"asOf must be a non-empty ISO 8601 timestamp string"
|
|
1612
|
+
);
|
|
1613
|
+
}
|
|
1614
|
+
const parsed = Date.parse(request.asOf);
|
|
1615
|
+
if (!Number.isFinite(parsed)) {
|
|
1616
|
+
throw new EngramAccessInputError(
|
|
1617
|
+
`asOf must be a parseable ISO 8601 timestamp (got: "${request.asOf}")`
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
asOf = request.asOf;
|
|
1621
|
+
}
|
|
1424
1622
|
const recallOptions = {
|
|
1425
1623
|
namespace: namespaceOverride,
|
|
1426
1624
|
topK,
|
|
1427
|
-
mode
|
|
1625
|
+
mode,
|
|
1626
|
+
...asOf !== void 0 ? { asOf } : {},
|
|
1627
|
+
...request.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
1428
1628
|
};
|
|
1429
1629
|
const startedAt = Date.now();
|
|
1430
1630
|
const context = await this.orchestrator.recall(query, request.sessionKey, recallOptions);
|
|
1431
1631
|
const snapshot = request.sessionKey ? this.orchestrator.lastRecall.get(request.sessionKey) : null;
|
|
1432
1632
|
const effectiveNamespace = snapshot?.namespace ? this.resolveNamespace(snapshot.namespace) : namespace;
|
|
1433
|
-
const
|
|
1633
|
+
const resultsReturned = snapshot?.memoryIds?.length ?? 0;
|
|
1634
|
+
const appliedTopK = snapshot?.budgetsApplied?.appliedTopK;
|
|
1635
|
+
const configMaxResults = typeof this.orchestrator.config.qmdMaxResults === "number" && Number.isFinite(this.orchestrator.config.qmdMaxResults) && this.orchestrator.config.qmdMaxResults > 0 ? this.orchestrator.config.qmdMaxResults : 0;
|
|
1636
|
+
const topKDenominator = typeof appliedTopK === "number" && Number.isFinite(appliedTopK) && appliedTopK > 0 ? Math.max(appliedTopK, resultsReturned) : typeof topK === "number" && topK > 0 ? Math.max(topK, resultsReturned) : Math.max(configMaxResults, resultsReturned, 1);
|
|
1637
|
+
const topKConfidence = snapshot && topKDenominator > 0 ? Math.min(1, resultsReturned / topKDenominator) : void 0;
|
|
1638
|
+
const escalationDecision = decideDisclosureEscalation({
|
|
1639
|
+
mode: this.orchestrator.config.recallDisclosureEscalation,
|
|
1640
|
+
threshold: this.orchestrator.config.recallDisclosureEscalationThreshold,
|
|
1641
|
+
originalDisclosure: requestedDisclosure,
|
|
1642
|
+
callerProvidedDisclosure,
|
|
1643
|
+
topKConfidence
|
|
1644
|
+
});
|
|
1645
|
+
const disclosure = escalationDecision.effective;
|
|
1646
|
+
let results = await this.serializeRecallResults(snapshot, disclosure, {
|
|
1647
|
+
query,
|
|
1648
|
+
sessionKey: request.sessionKey
|
|
1649
|
+
});
|
|
1650
|
+
const filterTags = normalizeTags(request.tags);
|
|
1651
|
+
let tagMatchMode;
|
|
1652
|
+
try {
|
|
1653
|
+
tagMatchMode = parseTagMatch(request.tagMatch);
|
|
1654
|
+
} catch (err) {
|
|
1655
|
+
throw new EngramAccessInputError(
|
|
1656
|
+
err instanceof Error ? err.message : String(err)
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
let effectiveContext = context;
|
|
1660
|
+
if (filterTags && filterTags.length > 0) {
|
|
1661
|
+
const beforeIds = results.map((r) => r.id);
|
|
1662
|
+
const { results: admitted } = applyTagFilter(results, {
|
|
1663
|
+
tags: filterTags,
|
|
1664
|
+
tagMatch: tagMatchMode
|
|
1665
|
+
});
|
|
1666
|
+
results = admitted;
|
|
1667
|
+
const admittedIds = new Set(results.map((r) => r.id));
|
|
1668
|
+
const droppedAny = beforeIds.some((id) => !admittedIds.has(id));
|
|
1669
|
+
if (droppedAny) {
|
|
1670
|
+
effectiveContext = results.map((r) => {
|
|
1671
|
+
const content = typeof r.content === "string" ? r.content ?? "" : "";
|
|
1672
|
+
const preview = typeof r.preview === "string" ? r.preview ?? "" : "";
|
|
1673
|
+
return content || preview;
|
|
1674
|
+
}).filter((s) => s.length > 0).join("\n\n");
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
const filteredMemoryIds = filterTags && filterTags.length > 0 ? results.map((r) => r.id) : snapshot?.memoryIds ?? [];
|
|
1434
1678
|
const debug = await this.buildRecallDebug(
|
|
1435
1679
|
snapshot,
|
|
1436
1680
|
effectiveNamespace,
|
|
@@ -1451,8 +1695,13 @@ var EngramAccessService = class {
|
|
|
1451
1695
|
trigger: "access-surface",
|
|
1452
1696
|
queryText: query,
|
|
1453
1697
|
candidateMemoryIds: snapshot?.memoryIds ?? [],
|
|
1454
|
-
|
|
1455
|
-
|
|
1698
|
+
// Audit must reflect what was actually injected, not what
|
|
1699
|
+
// recall produced before the tag filter. Using `context`
|
|
1700
|
+
// (pre-filter) overstates injectedChars and can leak content
|
|
1701
|
+
// from excluded memories into the audit summary (cursor
|
|
1702
|
+
// Medium on PR #712).
|
|
1703
|
+
summary: effectiveContext.slice(0, 200) || null,
|
|
1704
|
+
injectedChars: effectiveContext.length,
|
|
1456
1705
|
toggleState: "enabled",
|
|
1457
1706
|
latencyMs: Date.now() - startedAt,
|
|
1458
1707
|
plannerMode: snapshot?.plannerMode ?? mode,
|
|
@@ -1471,15 +1720,16 @@ var EngramAccessService = class {
|
|
|
1471
1720
|
query,
|
|
1472
1721
|
sessionKey: request.sessionKey,
|
|
1473
1722
|
namespace: effectiveNamespace,
|
|
1474
|
-
context,
|
|
1475
|
-
count: snapshot?.memoryIds.length ?? results.length,
|
|
1476
|
-
memoryIds:
|
|
1723
|
+
context: effectiveContext,
|
|
1724
|
+
count: filterTags && filterTags.length > 0 ? results.length : snapshot?.memoryIds.length ?? results.length,
|
|
1725
|
+
memoryIds: filteredMemoryIds,
|
|
1477
1726
|
results,
|
|
1478
1727
|
recordedAt: snapshot?.recordedAt,
|
|
1479
1728
|
traceId: snapshot?.traceId,
|
|
1480
1729
|
plannerMode: snapshot?.plannerMode ?? mode,
|
|
1481
1730
|
fallbackUsed: snapshot?.fallbackUsed ?? false,
|
|
1482
1731
|
sourcesUsed: snapshot?.sourcesUsed ?? [],
|
|
1732
|
+
disclosure,
|
|
1483
1733
|
budgetsApplied: snapshot?.budgetsApplied,
|
|
1484
1734
|
auditAnomalies,
|
|
1485
1735
|
budgetWarning: budgetDecision.reason === "warn-over-soft" ? budgetDecision : void 0,
|
|
@@ -1551,6 +1801,11 @@ var EngramAccessService = class {
|
|
|
1551
1801
|
if (query.trim().length === 0) {
|
|
1552
1802
|
throw new Error("recallXray: query is required and must be non-empty");
|
|
1553
1803
|
}
|
|
1804
|
+
if (request.disclosure !== void 0 && !isRecallDisclosure(request.disclosure)) {
|
|
1805
|
+
throw new EngramAccessInputError(
|
|
1806
|
+
`recallXray: disclosure must be one of: chunk, section, raw (got: ${String(request.disclosure)})`
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1554
1809
|
const namespacesEnabled = this.orchestrator.config.namespacesEnabled;
|
|
1555
1810
|
const requestedNamespace = request.namespace?.trim() ? this.resolveNamespace(request.namespace) : void 0;
|
|
1556
1811
|
const authenticatedPrincipal = request.authenticatedPrincipal?.trim();
|
|
@@ -1579,8 +1834,8 @@ var EngramAccessService = class {
|
|
|
1579
1834
|
const previousQueue = this.xrayQueue;
|
|
1580
1835
|
let release = () => {
|
|
1581
1836
|
};
|
|
1582
|
-
this.xrayQueue = new Promise((
|
|
1583
|
-
release =
|
|
1837
|
+
this.xrayQueue = new Promise((resolve2) => {
|
|
1838
|
+
release = resolve2;
|
|
1584
1839
|
});
|
|
1585
1840
|
await previousQueue;
|
|
1586
1841
|
try {
|
|
@@ -1601,11 +1856,98 @@ var EngramAccessService = class {
|
|
|
1601
1856
|
// (CLAUDE.md rule 42).
|
|
1602
1857
|
...authenticatedPrincipal ? { principalOverride: authenticatedPrincipal } : {}
|
|
1603
1858
|
});
|
|
1604
|
-
const
|
|
1605
|
-
if (!
|
|
1606
|
-
if (requestedNamespace &&
|
|
1859
|
+
const rawSnapshot = this.orchestrator.getLastXraySnapshot();
|
|
1860
|
+
if (!rawSnapshot) return { snapshotFound: false };
|
|
1861
|
+
if (requestedNamespace && rawSnapshot.namespace !== requestedNamespace) {
|
|
1607
1862
|
return { snapshotFound: false };
|
|
1608
1863
|
}
|
|
1864
|
+
let snapshot = rawSnapshot;
|
|
1865
|
+
const xrayFilterTags = normalizeTags(request.tags);
|
|
1866
|
+
let xrayTagMatch;
|
|
1867
|
+
try {
|
|
1868
|
+
xrayTagMatch = parseTagMatch(request.tagMatch);
|
|
1869
|
+
} catch (err) {
|
|
1870
|
+
throw new EngramAccessInputError(
|
|
1871
|
+
err instanceof Error ? err.message : String(err)
|
|
1872
|
+
);
|
|
1873
|
+
}
|
|
1874
|
+
if (xrayFilterTags && xrayFilterTags.length > 0) {
|
|
1875
|
+
const namespace = snapshot.namespace ? this.resolveNamespace(snapshot.namespace) : this.orchestrator.config.defaultNamespace;
|
|
1876
|
+
const tagsByIndex = await Promise.all(
|
|
1877
|
+
snapshot.results.map(async (result) => {
|
|
1878
|
+
try {
|
|
1879
|
+
const storage = await this.orchestrator.getStorage(namespace);
|
|
1880
|
+
const memory = await storage.readMemoryByPath(result.path);
|
|
1881
|
+
const t = memory?.frontmatter?.tags;
|
|
1882
|
+
return Array.isArray(t) ? normalizeProjectionTags(t) : [];
|
|
1883
|
+
} catch {
|
|
1884
|
+
return [];
|
|
1885
|
+
}
|
|
1886
|
+
})
|
|
1887
|
+
);
|
|
1888
|
+
const tagged = snapshot.results.map((result, index) => ({
|
|
1889
|
+
result,
|
|
1890
|
+
tags: tagsByIndex[index] ?? []
|
|
1891
|
+
}));
|
|
1892
|
+
const { results: admittedTagged, trace } = applyTagFilter(tagged, {
|
|
1893
|
+
tags: xrayFilterTags,
|
|
1894
|
+
tagMatch: xrayTagMatch
|
|
1895
|
+
});
|
|
1896
|
+
const admittedResults = admittedTagged.map((entry) => entry.result);
|
|
1897
|
+
const filters = trace ? [...snapshot.filters, trace] : snapshot.filters;
|
|
1898
|
+
snapshot = { ...snapshot, results: admittedResults, filters };
|
|
1899
|
+
}
|
|
1900
|
+
if (request.disclosure !== void 0) {
|
|
1901
|
+
const disclosure = request.disclosure;
|
|
1902
|
+
const namespace = snapshot.namespace ? this.resolveNamespace(snapshot.namespace) : this.orchestrator.config.defaultNamespace;
|
|
1903
|
+
const trimmedSessionKey = request.sessionKey?.trim() || void 0;
|
|
1904
|
+
const rawExcerpts = disclosure === "raw" ? await this.fetchRawExcerpts(disclosure, {
|
|
1905
|
+
query,
|
|
1906
|
+
...trimmedSessionKey ? { sessionKey: trimmedSessionKey } : {},
|
|
1907
|
+
namespace
|
|
1908
|
+
}) : null;
|
|
1909
|
+
const rawExcerptText = rawExcerpts && rawExcerpts.length > 0 ? rawExcerpts.map((e) => e.content).join("\n") : "";
|
|
1910
|
+
const memoryByIndex = await Promise.all(
|
|
1911
|
+
snapshot.results.map(async (result) => {
|
|
1912
|
+
try {
|
|
1913
|
+
const storage = await this.orchestrator.getStorage(namespace);
|
|
1914
|
+
return await storage.readMemoryByPath(result.path);
|
|
1915
|
+
} catch {
|
|
1916
|
+
return null;
|
|
1917
|
+
}
|
|
1918
|
+
})
|
|
1919
|
+
);
|
|
1920
|
+
const firstReadableIndex = memoryByIndex.findIndex((m) => m !== null);
|
|
1921
|
+
const baseDir = (await this.orchestrator.getStorage(namespace)).dir;
|
|
1922
|
+
const decorated = snapshot.results.map((result, index) => {
|
|
1923
|
+
const memory = memoryByIndex[index];
|
|
1924
|
+
if (!memory) {
|
|
1925
|
+
return { ...result, disclosure };
|
|
1926
|
+
}
|
|
1927
|
+
const shaped = shapeMemorySummary(
|
|
1928
|
+
memory,
|
|
1929
|
+
baseDir,
|
|
1930
|
+
disclosure,
|
|
1931
|
+
disclosure === "raw" && index === firstReadableIndex && rawExcerpts && rawExcerpts.length > 0 ? rawExcerpts : void 0
|
|
1932
|
+
);
|
|
1933
|
+
return {
|
|
1934
|
+
...result,
|
|
1935
|
+
disclosure,
|
|
1936
|
+
estimatedTokens: estimateRecallTokens(JSON.stringify(shaped))
|
|
1937
|
+
};
|
|
1938
|
+
});
|
|
1939
|
+
if (disclosure === "raw" && firstReadableIndex === -1 && rawExcerptText.length > 0 && decorated.length > 0) {
|
|
1940
|
+
decorated[0] = {
|
|
1941
|
+
...decorated[0],
|
|
1942
|
+
disclosure,
|
|
1943
|
+
estimatedTokens: estimateRecallTokens(rawExcerptText)
|
|
1944
|
+
};
|
|
1945
|
+
}
|
|
1946
|
+
return {
|
|
1947
|
+
snapshotFound: true,
|
|
1948
|
+
snapshot: { ...snapshot, results: decorated }
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1609
1951
|
return { snapshotFound: true, snapshot };
|
|
1610
1952
|
} finally {
|
|
1611
1953
|
release();
|
|
@@ -2074,6 +2416,10 @@ var EngramAccessService = class {
|
|
|
2074
2416
|
};
|
|
2075
2417
|
}
|
|
2076
2418
|
async governanceRun(request, principal) {
|
|
2419
|
+
const deepSleep = this.orchestrator.config.dreamsPhases.deepSleep;
|
|
2420
|
+
if (deepSleep.enabled === false && deepSleep.enabledExplicitlySet === true) {
|
|
2421
|
+
throw new Error("memory governance is disabled by dreams.phases.deepSleep.enabled=false");
|
|
2422
|
+
}
|
|
2077
2423
|
const resolvedNamespace = this.resolveWritableNamespace(
|
|
2078
2424
|
request.namespace,
|
|
2079
2425
|
void 0,
|
|
@@ -2130,6 +2476,66 @@ var EngramAccessService = class {
|
|
|
2130
2476
|
skippedReason: result.skippedReason
|
|
2131
2477
|
};
|
|
2132
2478
|
}
|
|
2479
|
+
async liveConnectorsRun(request = {}, principal) {
|
|
2480
|
+
this.resolveWritableNamespace(
|
|
2481
|
+
void 0,
|
|
2482
|
+
void 0,
|
|
2483
|
+
request.authenticatedPrincipal ?? principal
|
|
2484
|
+
);
|
|
2485
|
+
return this.orchestrator.runLiveConnectors({
|
|
2486
|
+
force: request.force === true
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* Run the pattern-reinforcement maintenance job (issue #687 PR 2/4).
|
|
2491
|
+
*
|
|
2492
|
+
* Cluster duplicate non-procedural memories and reinforce the
|
|
2493
|
+
* canonical (most-recent) member. Gated on
|
|
2494
|
+
* `patternReinforcementEnabled` — when disabled, returns
|
|
2495
|
+
* `{ ran: false, skippedReason: "disabled" }` so the cron payload
|
|
2496
|
+
* surface in CI logs cleanly.
|
|
2497
|
+
*
|
|
2498
|
+
* Resolves the namespace via the same writable path used by
|
|
2499
|
+
* `procedureMiningRun` so cross-tenant writes are impossible
|
|
2500
|
+
* (CLAUDE.md rule 42).
|
|
2501
|
+
*
|
|
2502
|
+
* Delegates the run to `orchestrator.runPatternReinforcement` so
|
|
2503
|
+
* the cadence floor (`patternReinforcementCadenceMs`) is enforced
|
|
2504
|
+
* uniformly across cron + MCP paths (PR #730 review feedback,
|
|
2505
|
+
* Codex P2). Accepts `force: true` for ad-hoc operator runs that
|
|
2506
|
+
* must bypass the cadence floor — mirrors the pattern used by
|
|
2507
|
+
* other maintenance MCP tools.
|
|
2508
|
+
*/
|
|
2509
|
+
async patternReinforcementRun(request = {}, principal) {
|
|
2510
|
+
const resolvedNamespace = this.resolveWritableNamespace(
|
|
2511
|
+
request.namespace,
|
|
2512
|
+
void 0,
|
|
2513
|
+
request.authenticatedPrincipal ?? principal
|
|
2514
|
+
);
|
|
2515
|
+
const outcome = await this.orchestrator.runPatternReinforcement({
|
|
2516
|
+
namespace: resolvedNamespace,
|
|
2517
|
+
force: request.force === true
|
|
2518
|
+
});
|
|
2519
|
+
if (!outcome.ran) {
|
|
2520
|
+
return {
|
|
2521
|
+
namespace: resolvedNamespace,
|
|
2522
|
+
ran: false,
|
|
2523
|
+
skippedReason: outcome.skippedReason,
|
|
2524
|
+
clustersFound: 0,
|
|
2525
|
+
canonicalsUpdated: 0,
|
|
2526
|
+
duplicatesSuperseded: 0
|
|
2527
|
+
};
|
|
2528
|
+
}
|
|
2529
|
+
const result = outcome.result;
|
|
2530
|
+
return {
|
|
2531
|
+
namespace: resolvedNamespace,
|
|
2532
|
+
ran: true,
|
|
2533
|
+
clustersFound: result.clustersFound,
|
|
2534
|
+
canonicalsUpdated: result.canonicalsUpdated,
|
|
2535
|
+
duplicatesSuperseded: result.duplicatesSuperseded,
|
|
2536
|
+
result
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2133
2539
|
/**
|
|
2134
2540
|
* Procedural memory stats (issue #567 PR 5/5). Read-only — resolves the
|
|
2135
2541
|
* namespace via the same path used by `recallExplain` / `trustZoneStatus`
|
|
@@ -2320,18 +2726,8 @@ var EngramAccessService = class {
|
|
|
2320
2726
|
frontmatter: memory.frontmatter
|
|
2321
2727
|
};
|
|
2322
2728
|
}
|
|
2323
|
-
serializeMemorySummary(memory, baseDir) {
|
|
2324
|
-
return
|
|
2325
|
-
id: memory.frontmatter.id,
|
|
2326
|
-
path: memory.path,
|
|
2327
|
-
category: memory.frontmatter.category,
|
|
2328
|
-
status: inferMemoryStatus(memory.frontmatter, toMemoryPathRel(baseDir, memory.path)),
|
|
2329
|
-
created: memory.frontmatter.created,
|
|
2330
|
-
updated: memory.frontmatter.updated,
|
|
2331
|
-
tags: normalizeProjectionTags(memory.frontmatter.tags),
|
|
2332
|
-
entityRef: memory.frontmatter.entityRef,
|
|
2333
|
-
preview: normalizeProjectionPreview(memory.content)
|
|
2334
|
-
};
|
|
2729
|
+
serializeMemorySummary(memory, baseDir, disclosure, rawExcerpts) {
|
|
2730
|
+
return shapeMemorySummary(memory, baseDir, disclosure, rawExcerpts);
|
|
2335
2731
|
}
|
|
2336
2732
|
async observe(request) {
|
|
2337
2733
|
if (!request.sessionKey || typeof request.sessionKey !== "string" || request.sessionKey.trim().length === 0) {
|
|
@@ -2353,6 +2749,10 @@ var EngramAccessService = class {
|
|
|
2353
2749
|
request.sessionKey,
|
|
2354
2750
|
request.authenticatedPrincipal
|
|
2355
2751
|
);
|
|
2752
|
+
await this.maybeAttachCodingContext(request.sessionKey, {
|
|
2753
|
+
cwd: request.cwd,
|
|
2754
|
+
projectTag: request.projectTag
|
|
2755
|
+
});
|
|
2356
2756
|
const lcmSessionKey = namespace !== this.orchestrator.config.defaultNamespace ? `${namespace}:${request.sessionKey}` : request.sessionKey;
|
|
2357
2757
|
let lcmArchived = false;
|
|
2358
2758
|
if (this.orchestrator.lcmEngine && this.orchestrator.lcmEngine.enabled) {
|
|
@@ -2540,6 +2940,14 @@ var EngramAccessService = class {
|
|
|
2540
2940
|
if (!anchor) return { found: false, message: "No identity anchor found yet. Use identity_anchor_update to create one." };
|
|
2541
2941
|
return { found: true, anchor };
|
|
2542
2942
|
}
|
|
2943
|
+
/**
|
|
2944
|
+
* @deprecated since issue #679 PR 5/5 — the identity-anchor model is
|
|
2945
|
+
* superseded by the peer registry. Use `peerSet({ id: "self", ... })` or
|
|
2946
|
+
* `remnic peer set self` to update the self peer's identity kernel, and
|
|
2947
|
+
* `remnic peer migrate` to seed `peers/self/identity.md` from existing
|
|
2948
|
+
* legacy anchor data. This method continues to function for backward
|
|
2949
|
+
* compatibility but will be removed in a future major version.
|
|
2950
|
+
*/
|
|
2543
2951
|
async identityAnchorUpdate(request) {
|
|
2544
2952
|
if (!this.orchestrator.config.identityContinuityEnabled) {
|
|
2545
2953
|
return { enabled: false, reason: "Identity continuity is disabled." };
|
|
@@ -2934,6 +3342,80 @@ ${next}`);
|
|
|
2934
3342
|
const explanation = await this.orchestrator.explainLastGraphRecall({ namespace });
|
|
2935
3343
|
return { explanation };
|
|
2936
3344
|
}
|
|
3345
|
+
/**
|
|
3346
|
+
* Read-only graph snapshot for the admin pane (issue #691 PR 2/5).
|
|
3347
|
+
*
|
|
3348
|
+
* Reads adjacency from the JSONL edge store written by `GraphIndex` and
|
|
3349
|
+
* resolves node metadata via the namespaced storage manager. Namespace
|
|
3350
|
+
* resolution mirrors the read-side path used by `recall` /
|
|
3351
|
+
* `procedureStats`, so multi-principal deployments can't leak edges from
|
|
3352
|
+
* a peer namespace (CLAUDE.md rule 42).
|
|
3353
|
+
*/
|
|
3354
|
+
async graphSnapshot(request, authenticatedPrincipal) {
|
|
3355
|
+
const namespace = this.resolveReadableNamespace(
|
|
3356
|
+
request.namespace,
|
|
3357
|
+
authenticatedPrincipal
|
|
3358
|
+
);
|
|
3359
|
+
const storage = await this.orchestrator.getStorage(namespace);
|
|
3360
|
+
const cfg = this.orchestrator.config;
|
|
3361
|
+
let namespaceRootReal;
|
|
3362
|
+
try {
|
|
3363
|
+
namespaceRootReal = await nodeFs.realpath(storage.dir);
|
|
3364
|
+
} catch {
|
|
3365
|
+
namespaceRootReal = nodePath.resolve(storage.dir);
|
|
3366
|
+
}
|
|
3367
|
+
const namespaceRootWithSep = namespaceRootReal.endsWith(nodePath.sep) ? namespaceRootReal : namespaceRootReal + nodePath.sep;
|
|
3368
|
+
const loadNode = async (relPath) => {
|
|
3369
|
+
if (nodePath.isAbsolute(relPath)) {
|
|
3370
|
+
log.warn(
|
|
3371
|
+
`graphSnapshot: rejected absolute edge endpoint (len=${relPath.length}) outside namespace root`
|
|
3372
|
+
);
|
|
3373
|
+
return null;
|
|
3374
|
+
}
|
|
3375
|
+
const candidate = nodePath.resolve(namespaceRootReal, relPath);
|
|
3376
|
+
if (candidate !== namespaceRootReal && !candidate.startsWith(namespaceRootWithSep)) {
|
|
3377
|
+
log.warn(
|
|
3378
|
+
`graphSnapshot: rejected traversing edge endpoint (len=${relPath.length}) outside namespace root`
|
|
3379
|
+
);
|
|
3380
|
+
return null;
|
|
3381
|
+
}
|
|
3382
|
+
let canonical;
|
|
3383
|
+
try {
|
|
3384
|
+
canonical = await nodeFs.realpath(candidate);
|
|
3385
|
+
} catch {
|
|
3386
|
+
canonical = candidate;
|
|
3387
|
+
}
|
|
3388
|
+
if (canonical !== namespaceRootReal && !canonical.startsWith(namespaceRootWithSep)) {
|
|
3389
|
+
log.warn(
|
|
3390
|
+
`graphSnapshot: rejected symlinked edge endpoint (len=${relPath.length}) that resolved outside namespace root`
|
|
3391
|
+
);
|
|
3392
|
+
return null;
|
|
3393
|
+
}
|
|
3394
|
+
const memory = await storage.readMemoryByPath(canonical);
|
|
3395
|
+
if (!memory) return null;
|
|
3396
|
+
const fm = memory.frontmatter;
|
|
3397
|
+
return {
|
|
3398
|
+
category: fm.category ?? "unknown",
|
|
3399
|
+
label: fm.id ?? nodePath.basename(canonical, nodePath.extname(canonical)),
|
|
3400
|
+
updated: fm.updated
|
|
3401
|
+
};
|
|
3402
|
+
};
|
|
3403
|
+
return buildGraphSnapshot({
|
|
3404
|
+
memoryDir: namespaceRootReal,
|
|
3405
|
+
graphConfig: {
|
|
3406
|
+
entityGraphEnabled: cfg.entityGraphEnabled === true,
|
|
3407
|
+
timeGraphEnabled: cfg.timeGraphEnabled === true,
|
|
3408
|
+
causalGraphEnabled: cfg.causalGraphEnabled === true
|
|
3409
|
+
},
|
|
3410
|
+
request: {
|
|
3411
|
+
limit: request.limit,
|
|
3412
|
+
since: request.since,
|
|
3413
|
+
focusNodeId: request.focusNodeId,
|
|
3414
|
+
categories: request.categories
|
|
3415
|
+
},
|
|
3416
|
+
loadNode
|
|
3417
|
+
});
|
|
3418
|
+
}
|
|
2937
3419
|
async memoryFeedback(request) {
|
|
2938
3420
|
if (!this.orchestrator.config.feedbackEnabled) {
|
|
2939
3421
|
return {
|
|
@@ -2995,17 +3477,17 @@ ${next}`);
|
|
|
2995
3477
|
const storage = await this.orchestrator.getStorage(resolvedNs);
|
|
2996
3478
|
const storageDir = storage.dir;
|
|
2997
3479
|
const { writeFile: writeFile2, mkdir: mkdir2 } = await import("fs/promises");
|
|
2998
|
-
const { join, resolve } = await import("path");
|
|
3480
|
+
const { join: join2, resolve: resolve2 } = await import("path");
|
|
2999
3481
|
const safeKey = request.sessionKey.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3000
3482
|
if (!safeKey) throw new EngramAccessInputError("sessionKey is required");
|
|
3001
|
-
const checkpointDir =
|
|
3002
|
-
const resolved =
|
|
3003
|
-
if (!resolved.startsWith(
|
|
3483
|
+
const checkpointDir = join2(storageDir, "checkpoints", safeKey);
|
|
3484
|
+
const resolved = resolve2(checkpointDir);
|
|
3485
|
+
if (!resolved.startsWith(resolve2(storageDir))) {
|
|
3004
3486
|
throw new EngramAccessInputError("Invalid sessionKey");
|
|
3005
3487
|
}
|
|
3006
3488
|
await mkdir2(checkpointDir, { recursive: true });
|
|
3007
3489
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3008
|
-
const filePath =
|
|
3490
|
+
const filePath = join2(checkpointDir, `checkpoint-${ts}.md`);
|
|
3009
3491
|
await writeFile2(filePath, request.context, "utf-8");
|
|
3010
3492
|
return { saved: true };
|
|
3011
3493
|
}
|
|
@@ -3040,8 +3522,8 @@ ${next}`);
|
|
|
3040
3522
|
);
|
|
3041
3523
|
const memoryIds = [];
|
|
3042
3524
|
for (const entry of request.entries) {
|
|
3043
|
-
const
|
|
3044
|
-
const id =
|
|
3525
|
+
const basename2 = entry.path.split("/").pop() ?? entry.path;
|
|
3526
|
+
const id = basename2.endsWith(".md") ? basename2.slice(0, -3) : basename2;
|
|
3045
3527
|
if (id.length > 0) {
|
|
3046
3528
|
memoryIds.push(id);
|
|
3047
3529
|
}
|
|
@@ -3059,10 +3541,196 @@ ${next}`);
|
|
|
3059
3541
|
}
|
|
3060
3542
|
return { submitted: memoryIds.length, matched: matchedIds.length };
|
|
3061
3543
|
}
|
|
3544
|
+
// ── Operator Console state (issue #688 PR 2/3) ────────────────────────────
|
|
3545
|
+
/**
|
|
3546
|
+
* Gather a point-in-time `ConsoleStateSnapshot` from the orchestrator.
|
|
3547
|
+
*
|
|
3548
|
+
* Principal-aware: `resolveReadableNamespace` enforces ACL before the
|
|
3549
|
+
* snapshot is gathered, so callers cannot read a namespace they don't
|
|
3550
|
+
* have read access to (CLAUDE.md rule 42). The resolved namespace's
|
|
3551
|
+
* storage directory is forwarded as `config.memoryDir` so the ledger-
|
|
3552
|
+
* tail reader in `gatherConsoleState` scans the correct namespace root
|
|
3553
|
+
* rather than the global root. Read-only — never mutates orchestrator state.
|
|
3554
|
+
*/
|
|
3555
|
+
async consoleState(namespace, principal) {
|
|
3556
|
+
const resolvedNamespace = this.resolveReadableNamespace(namespace, principal);
|
|
3557
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3558
|
+
const { gatherConsoleState } = await import("./state-NCHQ4TRG.js");
|
|
3559
|
+
const orchestratorProxy = Object.create(this.orchestrator, {
|
|
3560
|
+
config: {
|
|
3561
|
+
value: { ...this.orchestrator.config, memoryDir: storage.dir },
|
|
3562
|
+
enumerable: true,
|
|
3563
|
+
configurable: true
|
|
3564
|
+
}
|
|
3565
|
+
});
|
|
3566
|
+
return gatherConsoleState(orchestratorProxy);
|
|
3567
|
+
}
|
|
3568
|
+
// ── Peer Registry surfaces (issue #679 PR 4/5) ────────────────────────────
|
|
3569
|
+
/**
|
|
3570
|
+
* List all registered peers. Returns the array of `Peer` objects in
|
|
3571
|
+
* deterministic alphabetical order (mirroring `listPeers` storage semantics).
|
|
3572
|
+
*/
|
|
3573
|
+
async peerList() {
|
|
3574
|
+
const { listPeers } = await import("./peers-6OSQ3NK6.js");
|
|
3575
|
+
const peers = await listPeers(this.orchestrator.config.memoryDir);
|
|
3576
|
+
return { peers };
|
|
3577
|
+
}
|
|
3578
|
+
/**
|
|
3579
|
+
* Get a single peer by id. Returns `{ found: false }` when the peer does
|
|
3580
|
+
* not exist rather than throwing, matching the `memoryGet` / `entityGet`
|
|
3581
|
+
* pattern used throughout the service.
|
|
3582
|
+
*/
|
|
3583
|
+
async peerGet(peerId) {
|
|
3584
|
+
const peers = await import("./peers-6OSQ3NK6.js");
|
|
3585
|
+
const validateId = peers.assertValidPeerId;
|
|
3586
|
+
try {
|
|
3587
|
+
validateId(peerId);
|
|
3588
|
+
} catch (err) {
|
|
3589
|
+
throw new EngramAccessInputError(err.message);
|
|
3590
|
+
}
|
|
3591
|
+
const peer = await peers.readPeer(this.orchestrator.config.memoryDir, peerId);
|
|
3592
|
+
if (!peer) return { found: false };
|
|
3593
|
+
return { found: true, peer };
|
|
3594
|
+
}
|
|
3595
|
+
/**
|
|
3596
|
+
* Upsert a peer. Writes `peers/{id}/identity.md`. On first write the
|
|
3597
|
+
* `createdAt` timestamp is set to now; on subsequent writes only
|
|
3598
|
+
* `displayName` and `notes` are mutated (kind and createdAt are immutable
|
|
3599
|
+
* once set, per the storage contract).
|
|
3600
|
+
*
|
|
3601
|
+
* Returns `{ created: true }` on first write, `{ created: false }` on update.
|
|
3602
|
+
*/
|
|
3603
|
+
async peerSet(input) {
|
|
3604
|
+
const peers = await import("./peers-6OSQ3NK6.js");
|
|
3605
|
+
const validateId = peers.assertValidPeerId;
|
|
3606
|
+
const { id } = input;
|
|
3607
|
+
try {
|
|
3608
|
+
validateId(id);
|
|
3609
|
+
} catch (err) {
|
|
3610
|
+
throw new EngramAccessInputError(err.message);
|
|
3611
|
+
}
|
|
3612
|
+
const memoryDir = this.orchestrator.config.memoryDir;
|
|
3613
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3614
|
+
const existing = await peers.readPeer(memoryDir, id);
|
|
3615
|
+
const ALLOWED_KINDS = /* @__PURE__ */ new Set(["self", "human", "agent", "integration"]);
|
|
3616
|
+
if (!existing) {
|
|
3617
|
+
const kind = input.kind ?? "human";
|
|
3618
|
+
if (!ALLOWED_KINDS.has(kind)) {
|
|
3619
|
+
throw new EngramAccessInputError(
|
|
3620
|
+
`peer kind must be one of ${[...ALLOWED_KINDS].join(", ")}`
|
|
3621
|
+
);
|
|
3622
|
+
}
|
|
3623
|
+
const newPeer = {
|
|
3624
|
+
id,
|
|
3625
|
+
kind,
|
|
3626
|
+
displayName: input.displayName ?? id,
|
|
3627
|
+
createdAt: now,
|
|
3628
|
+
updatedAt: now,
|
|
3629
|
+
...typeof input.notes === "string" ? { notes: input.notes } : {}
|
|
3630
|
+
};
|
|
3631
|
+
await peers.writePeer(memoryDir, newPeer);
|
|
3632
|
+
return { ok: true, created: true, peer: newPeer };
|
|
3633
|
+
}
|
|
3634
|
+
const updated = {
|
|
3635
|
+
id: existing.id,
|
|
3636
|
+
kind: existing.kind,
|
|
3637
|
+
createdAt: existing.createdAt,
|
|
3638
|
+
updatedAt: now,
|
|
3639
|
+
displayName: input.displayName !== void 0 ? input.displayName : existing.displayName,
|
|
3640
|
+
...input.notes !== void 0 ? { notes: input.notes } : existing.notes !== void 0 ? { notes: existing.notes } : {}
|
|
3641
|
+
};
|
|
3642
|
+
await peers.writePeer(memoryDir, updated);
|
|
3643
|
+
return { ok: true, created: false, peer: updated };
|
|
3644
|
+
}
|
|
3645
|
+
/**
|
|
3646
|
+
* Delete a peer by removing `peers/{id}/identity.md`. If the file does not
|
|
3647
|
+
* exist the call is a no-op (idempotent). The peer directory itself
|
|
3648
|
+
* (`peers/{id}/`) is intentionally left in place — profile and interaction
|
|
3649
|
+
* log data are not destroyed.
|
|
3650
|
+
*/
|
|
3651
|
+
async peerDelete(peerId) {
|
|
3652
|
+
const peers = await import("./peers-6OSQ3NK6.js");
|
|
3653
|
+
const validateId = peers.assertValidPeerId;
|
|
3654
|
+
try {
|
|
3655
|
+
validateId(peerId);
|
|
3656
|
+
} catch (err) {
|
|
3657
|
+
throw new EngramAccessInputError(err.message);
|
|
3658
|
+
}
|
|
3659
|
+
const deleted = await peers.deletePeer(this.orchestrator.config.memoryDir, peerId);
|
|
3660
|
+
return { ok: true, deleted };
|
|
3661
|
+
}
|
|
3662
|
+
/**
|
|
3663
|
+
* Destructively purge the entire peer directory for a given peerId —
|
|
3664
|
+
* `identity.md`, `profile.md`, `interactions.log.md`, and any other
|
|
3665
|
+
* files in `peers/{id}/`. Requires `confirm: "yes"` to prevent
|
|
3666
|
+
* accidental invocation.
|
|
3667
|
+
*
|
|
3668
|
+
* This is the DESTRUCTIVE counterpart to `peerDelete`, which only
|
|
3669
|
+
* removes `identity.md`. All companion files are permanently removed.
|
|
3670
|
+
*
|
|
3671
|
+
* Returns `{ ok: true, purged: true }` when the directory existed and
|
|
3672
|
+
* was removed; `{ ok: true, purged: false }` when the directory did
|
|
3673
|
+
* not exist (idempotent no-op).
|
|
3674
|
+
*/
|
|
3675
|
+
async peerForget(peerId, opts) {
|
|
3676
|
+
const peers = await import("./peers-6OSQ3NK6.js");
|
|
3677
|
+
const validateId = peers.assertValidPeerId;
|
|
3678
|
+
try {
|
|
3679
|
+
validateId(peerId);
|
|
3680
|
+
} catch (err) {
|
|
3681
|
+
throw new EngramAccessInputError(err.message);
|
|
3682
|
+
}
|
|
3683
|
+
if (opts.confirm !== "yes") {
|
|
3684
|
+
throw new EngramAccessInputError(
|
|
3685
|
+
"peerForget requires confirm: 'yes' to prevent accidental data loss"
|
|
3686
|
+
);
|
|
3687
|
+
}
|
|
3688
|
+
const result = await peers.forgetPeer(this.orchestrator.config.memoryDir, peerId, {
|
|
3689
|
+
confirm: "yes"
|
|
3690
|
+
});
|
|
3691
|
+
return { ok: true, purged: result.purged };
|
|
3692
|
+
}
|
|
3693
|
+
/**
|
|
3694
|
+
* Get the evolving cognitive profile for a peer. Returns `{ found: false }`
|
|
3695
|
+
* when no profile file exists yet (profile is written by the async reasoner,
|
|
3696
|
+
* PR 2/5). The peer identity itself need not exist for a profile to exist,
|
|
3697
|
+
* but in practice the reasoner only writes profiles for registered peers.
|
|
3698
|
+
*/
|
|
3699
|
+
async peerProfileGet(peerId) {
|
|
3700
|
+
const peers = await import("./peers-6OSQ3NK6.js");
|
|
3701
|
+
const validateId = peers.assertValidPeerId;
|
|
3702
|
+
try {
|
|
3703
|
+
validateId(peerId);
|
|
3704
|
+
} catch (err) {
|
|
3705
|
+
throw new EngramAccessInputError(err.message);
|
|
3706
|
+
}
|
|
3707
|
+
const profile = await peers.readPeerProfile(this.orchestrator.config.memoryDir, peerId);
|
|
3708
|
+
if (!profile) return { found: false };
|
|
3709
|
+
return { found: true, profile };
|
|
3710
|
+
}
|
|
3062
3711
|
// ── Contradiction Review (issue #520) ──────────────────────────────────────
|
|
3063
3712
|
get memoryDir() {
|
|
3064
3713
|
return this.orchestrator.config.memoryDir;
|
|
3065
3714
|
}
|
|
3715
|
+
/**
|
|
3716
|
+
* Resolve the storage directory for a given namespace. Used by the SSE
|
|
3717
|
+
* graph-event handler to subscribe to the correct per-namespace bus rather
|
|
3718
|
+
* than the global root (CLAUDE.md rule 42 — read/write paths must resolve
|
|
3719
|
+
* through the same namespace layer).
|
|
3720
|
+
*
|
|
3721
|
+
* `principal` must be the transport-bound request principal (from
|
|
3722
|
+
* `resolveRequestPrincipal`). When namespaces are enabled, an absent
|
|
3723
|
+
* principal causes `resolveReadableNamespace` to throw an auth error,
|
|
3724
|
+
* matching the behaviour of every other authenticated read path.
|
|
3725
|
+
*
|
|
3726
|
+
* Falls back to `this.memoryDir` when namespaces are disabled or the
|
|
3727
|
+
* namespace is absent, matching the behaviour of every other read path.
|
|
3728
|
+
*/
|
|
3729
|
+
async getMemoryDirForNamespace(namespace, principal) {
|
|
3730
|
+
const resolved = this.resolveReadableNamespace(namespace, principal);
|
|
3731
|
+
const storage = await this.orchestrator.getStorage(resolved);
|
|
3732
|
+
return storage.dir;
|
|
3733
|
+
}
|
|
3066
3734
|
get storageRef() {
|
|
3067
3735
|
return this.orchestrator.storage;
|
|
3068
3736
|
}
|
|
@@ -3087,6 +3755,257 @@ ${next}`);
|
|
|
3087
3755
|
};
|
|
3088
3756
|
};
|
|
3089
3757
|
}
|
|
3758
|
+
/**
|
|
3759
|
+
* Import a capsule archive into the orchestrator's memory directory.
|
|
3760
|
+
*
|
|
3761
|
+
* Delegates directly to the standalone {@link importCapsuleFn} function.
|
|
3762
|
+
* The `root` parameter defaults to the orchestrator's `memoryDir` when
|
|
3763
|
+
* omitted, so callers that only have access to the service do not need to
|
|
3764
|
+
* thread the config value through.
|
|
3765
|
+
*
|
|
3766
|
+
* `versioning` defaults to the orchestrator's page-versioning config so
|
|
3767
|
+
* `mode: "overwrite"` automatically snapshots prior content without the
|
|
3768
|
+
* caller having to construct the config object.
|
|
3769
|
+
*/
|
|
3770
|
+
async capsuleImport(opts) {
|
|
3771
|
+
const { namespace, principal, root: explicitRoot, memoryDir: explicitMemoryDir, ...importOptions } = opts;
|
|
3772
|
+
const resolvedNamespace = this.resolveWritableNamespace(namespace, void 0, principal);
|
|
3773
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3774
|
+
const root = explicitRoot ?? storage.dir;
|
|
3775
|
+
const memoryDir = explicitMemoryDir ?? this.orchestrator.config.memoryDir;
|
|
3776
|
+
const versioning = importOptions.versioning ?? {
|
|
3777
|
+
enabled: this.orchestrator.config.versioningEnabled,
|
|
3778
|
+
maxVersionsPerPage: this.orchestrator.config.versioningMaxPerPage,
|
|
3779
|
+
sidecarDir: this.orchestrator.config.versioningSidecarDir
|
|
3780
|
+
};
|
|
3781
|
+
await this.validateCapsuleImportArchivePath(importOptions.archivePath);
|
|
3782
|
+
try {
|
|
3783
|
+
return await importCapsule({ ...importOptions, root, memoryDir, versioning });
|
|
3784
|
+
} catch (err) {
|
|
3785
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3786
|
+
if (this.isCapsuleImportArchiveInputError(err, message)) {
|
|
3787
|
+
throw new EngramAccessInputError(`capsule import failed: ${message}`);
|
|
3788
|
+
}
|
|
3789
|
+
throw err;
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
async validateCapsuleImportArchivePath(archivePath) {
|
|
3793
|
+
let archiveStat;
|
|
3794
|
+
try {
|
|
3795
|
+
archiveStat = await stat(archivePath);
|
|
3796
|
+
} catch (err) {
|
|
3797
|
+
if (!this.isCapsuleImportPathInputFsError(err)) throw err;
|
|
3798
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3799
|
+
throw new EngramAccessInputError(`capsule import failed: archive is not readable: ${message}`);
|
|
3800
|
+
}
|
|
3801
|
+
if (!archiveStat.isFile()) {
|
|
3802
|
+
throw new EngramAccessInputError("capsule import failed: archivePath must point to a file");
|
|
3803
|
+
}
|
|
3804
|
+
try {
|
|
3805
|
+
await nodeFs.access(archivePath, fsConstants.R_OK);
|
|
3806
|
+
} catch (err) {
|
|
3807
|
+
if (!this.isCapsuleImportPathInputFsError(err)) throw err;
|
|
3808
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3809
|
+
throw new EngramAccessInputError(`capsule import failed: archive is not readable: ${message}`);
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
isCapsuleImportPathInputFsError(err) {
|
|
3813
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
3814
|
+
return code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM" || code === "ELOOP";
|
|
3815
|
+
}
|
|
3816
|
+
isCapsuleImportArchiveInputError(err, message) {
|
|
3817
|
+
if (err instanceof ZodError) return true;
|
|
3818
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
3819
|
+
if (typeof code === "string" && code.startsWith("Z_")) return true;
|
|
3820
|
+
return message.startsWith("importCapsule: archive") || message.startsWith("importCapsule: bundle") || message.startsWith("importCapsule: manifest") || message.startsWith("importCapsule: record") || /incorrect header check|invalid stored block lengths|not in gzip format|unexpected end of file/i.test(message);
|
|
3821
|
+
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Export a capsule archive from the orchestrator's memory directory.
|
|
3824
|
+
*
|
|
3825
|
+
* HTTP and future MCP surfaces use this rather than calling the transfer
|
|
3826
|
+
* helper directly so namespace ACL checks stay consistent with the archive
|
|
3827
|
+
* write side effect. The exporter still owns archive construction and
|
|
3828
|
+
* validation.
|
|
3829
|
+
*/
|
|
3830
|
+
async capsuleExport(opts) {
|
|
3831
|
+
const { namespace, principal, root: explicitRoot, memoryDir: explicitMemoryDir, ...exportOptions } = opts;
|
|
3832
|
+
const resolvedNamespace = this.resolveWritableNamespace(namespace, void 0, principal);
|
|
3833
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3834
|
+
const root = explicitRoot ?? storage.dir;
|
|
3835
|
+
const memoryDir = explicitMemoryDir ?? this.orchestrator.config.memoryDir;
|
|
3836
|
+
const pluginVersion = exportOptions.pluginVersion ?? await getPackageVersion();
|
|
3837
|
+
return exportCapsule({
|
|
3838
|
+
...exportOptions,
|
|
3839
|
+
pluginVersion,
|
|
3840
|
+
root,
|
|
3841
|
+
memoryDir: exportOptions.encrypt === true ? memoryDir : void 0
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
/**
|
|
3845
|
+
* List capsule archives in the namespace-scoped capsule store.
|
|
3846
|
+
*
|
|
3847
|
+
* MCP uses this access-layer method instead of reading arbitrary paths so
|
|
3848
|
+
* capsule discovery remains bound to the same namespace ACLs as export and
|
|
3849
|
+
* import.
|
|
3850
|
+
*/
|
|
3851
|
+
async capsuleList(options) {
|
|
3852
|
+
const resolvedNamespace = this.resolveReadableNamespace(options?.namespace, options?.principal);
|
|
3853
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3854
|
+
const capsulesDir = defaultCapsulesDir(storage.dir);
|
|
3855
|
+
let dirEntries;
|
|
3856
|
+
try {
|
|
3857
|
+
const capsulesDirStat = await nodeFs.lstat(capsulesDir);
|
|
3858
|
+
if (capsulesDirStat.isSymbolicLink()) {
|
|
3859
|
+
throw new EngramAccessInputError("capsule list failed: capsule store directory must not be a symlink");
|
|
3860
|
+
}
|
|
3861
|
+
if (!capsulesDirStat.isDirectory()) {
|
|
3862
|
+
throw new EngramAccessInputError("capsule list failed: capsule store path must be a directory");
|
|
3863
|
+
}
|
|
3864
|
+
dirEntries = await nodeFs.readdir(capsulesDir, { withFileTypes: true });
|
|
3865
|
+
} catch (err) {
|
|
3866
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
3867
|
+
if (code === "ENOENT") {
|
|
3868
|
+
return { namespace: resolvedNamespace, capsulesDir, capsules: [] };
|
|
3869
|
+
}
|
|
3870
|
+
throw err;
|
|
3871
|
+
}
|
|
3872
|
+
const archiveNames = dirEntries.filter(
|
|
3873
|
+
(entry) => entry.isFile() && (entry.name.endsWith(".capsule.json.gz") || entry.name.endsWith(".capsule.json.gz.enc"))
|
|
3874
|
+
).map((entry) => entry.name).sort();
|
|
3875
|
+
const capsules = [];
|
|
3876
|
+
for (const archiveName of archiveNames) {
|
|
3877
|
+
const archivePath = nodePath.join(capsulesDir, archiveName);
|
|
3878
|
+
const id = archiveName.replace(/\.capsule\.json\.gz\.enc$/, "").replace(/\.capsule\.json\.gz$/, "");
|
|
3879
|
+
const manifestPath = nodePath.join(capsulesDir, `${id}.manifest.json`);
|
|
3880
|
+
let createdAt = null;
|
|
3881
|
+
let pluginVersion = null;
|
|
3882
|
+
let fileCount = null;
|
|
3883
|
+
let description = null;
|
|
3884
|
+
let manifestPathOrNull = manifestPath;
|
|
3885
|
+
try {
|
|
3886
|
+
const manifestStat = await nodeFs.lstat(manifestPath);
|
|
3887
|
+
if (manifestStat.isSymbolicLink() || !manifestStat.isFile()) {
|
|
3888
|
+
capsules.push({
|
|
3889
|
+
id,
|
|
3890
|
+
archivePath,
|
|
3891
|
+
manifestPath: manifestPathOrNull,
|
|
3892
|
+
createdAt,
|
|
3893
|
+
pluginVersion,
|
|
3894
|
+
fileCount,
|
|
3895
|
+
description
|
|
3896
|
+
});
|
|
3897
|
+
continue;
|
|
3898
|
+
}
|
|
3899
|
+
const raw = await nodeFs.readFile(manifestPath, "utf-8");
|
|
3900
|
+
const sidecar = JSON.parse(raw);
|
|
3901
|
+
createdAt = typeof sidecar.createdAt === "string" ? sidecar.createdAt : null;
|
|
3902
|
+
pluginVersion = typeof sidecar.pluginVersion === "string" ? sidecar.pluginVersion : null;
|
|
3903
|
+
fileCount = Array.isArray(sidecar.files) ? sidecar.files.length : null;
|
|
3904
|
+
const capsule = sidecar.capsule;
|
|
3905
|
+
description = capsule && typeof capsule.description === "string" ? capsule.description : null;
|
|
3906
|
+
} catch (err) {
|
|
3907
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : void 0;
|
|
3908
|
+
if (code === "ENOENT") {
|
|
3909
|
+
manifestPathOrNull = null;
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
capsules.push({
|
|
3913
|
+
id,
|
|
3914
|
+
archivePath,
|
|
3915
|
+
manifestPath: manifestPathOrNull,
|
|
3916
|
+
createdAt,
|
|
3917
|
+
pluginVersion,
|
|
3918
|
+
fileCount,
|
|
3919
|
+
description
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
3922
|
+
return { namespace: resolvedNamespace, capsulesDir, capsules };
|
|
3923
|
+
}
|
|
3924
|
+
// ── Dreams pipeline telemetry surfaces (issue #678 PR 3+4) ──────────────
|
|
3925
|
+
/**
|
|
3926
|
+
* Return per-phase Dreams telemetry for the last N hours (default 24).
|
|
3927
|
+
*/
|
|
3928
|
+
async dreamsStatus(options) {
|
|
3929
|
+
const { getDreamsStatus, normalizeDreamsStatusWindowHours } = await import("./dreams-ledger-LR2NBAZE.js");
|
|
3930
|
+
let windowHours;
|
|
3931
|
+
try {
|
|
3932
|
+
windowHours = normalizeDreamsStatusWindowHours(options?.windowHours);
|
|
3933
|
+
} catch (error) {
|
|
3934
|
+
throw new EngramAccessInputError(error instanceof Error ? error.message : String(error));
|
|
3935
|
+
}
|
|
3936
|
+
const resolvedNamespace = this.resolveReadableNamespace(options?.namespace, options?.principal);
|
|
3937
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3938
|
+
return getDreamsStatus(storage.dir, windowHours);
|
|
3939
|
+
}
|
|
3940
|
+
/**
|
|
3941
|
+
* Manually invoke a single Dreams phase pass (PR 4/4).
|
|
3942
|
+
*
|
|
3943
|
+
* Deep-sleep delegates to memory governance (shadow → dry-run, apply → live).
|
|
3944
|
+
* Light-sleep and REM scan the observation ledger and memory corpus
|
|
3945
|
+
* respectively, returning the same telemetry shape as a scheduled run.
|
|
3946
|
+
*/
|
|
3947
|
+
async dreamsRun(options) {
|
|
3948
|
+
const { runDreamsPhase } = await import("./dreams-ledger-LR2NBAZE.js");
|
|
3949
|
+
const validPhases = ["lightSleep", "rem", "deepSleep"];
|
|
3950
|
+
if (!validPhases.includes(options.phase)) {
|
|
3951
|
+
throw new EngramAccessInputError(
|
|
3952
|
+
`Invalid phase: ${String(options.phase)}. Must be one of: ${validPhases.join(", ")}`
|
|
3953
|
+
);
|
|
3954
|
+
}
|
|
3955
|
+
const deepSleep = this.orchestrator.config.dreamsPhases.deepSleep;
|
|
3956
|
+
if (options.phase === "deepSleep" && deepSleep.enabled === false && deepSleep.enabledExplicitlySet === true) {
|
|
3957
|
+
throw new EngramAccessInputError(
|
|
3958
|
+
"memory governance is disabled by dreams.phases.deepSleep.enabled=false"
|
|
3959
|
+
);
|
|
3960
|
+
}
|
|
3961
|
+
const dryRun = options.dryRun === true;
|
|
3962
|
+
const resolvedNamespace = this.resolveWritableNamespace(
|
|
3963
|
+
options.namespace,
|
|
3964
|
+
void 0,
|
|
3965
|
+
options.authenticatedPrincipal
|
|
3966
|
+
);
|
|
3967
|
+
const storage = await this.orchestrator.getStorage(resolvedNamespace);
|
|
3968
|
+
const memoryDir = storage.dir;
|
|
3969
|
+
const phaseRunner = dryRun || options.phase === "deepSleep" ? void 0 : async (_opts) => {
|
|
3970
|
+
if (_opts.phase === "lightSleep") {
|
|
3971
|
+
const result3 = await this.orchestrator.runLifecyclePolicyNow(storage);
|
|
3972
|
+
return {
|
|
3973
|
+
itemsProcessed: result3.memoriesAssessed,
|
|
3974
|
+
notes: `scored ${result3.memoriesAssessed} memories`
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
const result2 = await this.orchestrator.runSemanticConsolidationNow({
|
|
3978
|
+
dryRun: false,
|
|
3979
|
+
storage
|
|
3980
|
+
});
|
|
3981
|
+
const itemsProcessed = result2.clusters.reduce(
|
|
3982
|
+
(sum, cluster) => sum + cluster.memories.length,
|
|
3983
|
+
0
|
|
3984
|
+
);
|
|
3985
|
+
return {
|
|
3986
|
+
itemsProcessed,
|
|
3987
|
+
notes: `REM consolidation found ${result2.clustersFound} clusters`
|
|
3988
|
+
};
|
|
3989
|
+
};
|
|
3990
|
+
const governanceRunner = options.phase === "deepSleep" ? async (_opts) => {
|
|
3991
|
+
return this.orchestrator.runDeepSleepGovernanceNow({
|
|
3992
|
+
storage,
|
|
3993
|
+
dryRun: _opts.dryRun
|
|
3994
|
+
});
|
|
3995
|
+
} : void 0;
|
|
3996
|
+
const result = await runDreamsPhase(
|
|
3997
|
+
{ memoryDir, phase: options.phase, dryRun },
|
|
3998
|
+
governanceRunner,
|
|
3999
|
+
phaseRunner
|
|
4000
|
+
);
|
|
4001
|
+
return {
|
|
4002
|
+
phase: result.phase,
|
|
4003
|
+
dryRun: result.dryRun,
|
|
4004
|
+
durationMs: result.durationMs,
|
|
4005
|
+
itemsProcessed: result.itemsProcessed,
|
|
4006
|
+
notes: result.notes
|
|
4007
|
+
};
|
|
4008
|
+
}
|
|
3090
4009
|
};
|
|
3091
4010
|
|
|
3092
4011
|
export {
|
|
@@ -3095,6 +4014,7 @@ export {
|
|
|
3095
4014
|
formatProcedureStatsText,
|
|
3096
4015
|
EngramAccessInputError,
|
|
3097
4016
|
ENGRAM_ACCESS_WRITE_SCHEMA_VERSION,
|
|
4017
|
+
shapeMemorySummary,
|
|
3098
4018
|
EngramAccessService
|
|
3099
4019
|
};
|
|
3100
|
-
//# sourceMappingURL=chunk-
|
|
4020
|
+
//# sourceMappingURL=chunk-DR7MCMPS.js.map
|