@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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getKey,
|
|
3
|
+
readHeader,
|
|
4
|
+
secureStoreDir
|
|
5
|
+
} from "./chunk-BJMBJZ2Y.js";
|
|
6
|
+
import {
|
|
7
|
+
open,
|
|
8
|
+
seal
|
|
9
|
+
} from "./chunk-A6XUJE5D.js";
|
|
10
|
+
|
|
11
|
+
// src/transfer/capsule-crypto.ts
|
|
12
|
+
import { open as openFileHandle, readFile, writeFile } from "fs/promises";
|
|
13
|
+
import path from "path";
|
|
14
|
+
var MAGIC = Buffer.from("REMNIC-ENC\0", "ascii");
|
|
15
|
+
var FORMAT_VERSION = 2;
|
|
16
|
+
var MIN_ENC_SIZE_V1 = MAGIC.length + 1 + 45;
|
|
17
|
+
var MIN_ENC_SIZE = MAGIC.length + 1 + 2;
|
|
18
|
+
async function isEncryptedCapsuleFile(filePath) {
|
|
19
|
+
if (!filePath.endsWith(".enc")) return false;
|
|
20
|
+
let fh = null;
|
|
21
|
+
try {
|
|
22
|
+
fh = await openFileHandle(filePath, "r");
|
|
23
|
+
const buf = Buffer.allocUnsafe(MAGIC.length);
|
|
24
|
+
const { bytesRead } = await fh.read(buf, 0, MAGIC.length, 0);
|
|
25
|
+
if (bytesRead < MAGIC.length) return false;
|
|
26
|
+
return buf.equals(MAGIC);
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
} finally {
|
|
30
|
+
if (fh !== null) {
|
|
31
|
+
await fh.close().catch(() => void 0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function encryptCapsuleFile(opts) {
|
|
36
|
+
const encPath = opts.outPath ?? `${opts.sourceGzPath}.enc`;
|
|
37
|
+
const key = getKeyOrThrow(opts.memoryDir, "encrypt capsule");
|
|
38
|
+
const plaintext = await readFile(opts.sourceGzPath);
|
|
39
|
+
const basename = path.basename(encPath);
|
|
40
|
+
const aad = Buffer.from(basename, "utf-8");
|
|
41
|
+
const kdfSection = await loadKdfSection(opts.memoryDir);
|
|
42
|
+
const envelope = seal(key, kdfSection.salt, plaintext, { aad });
|
|
43
|
+
const versionBuf = Buffer.alloc(1);
|
|
44
|
+
versionBuf.writeUInt8(FORMAT_VERSION, 0);
|
|
45
|
+
const kdfJsonBuf = Buffer.from(kdfSection.json, "utf-8");
|
|
46
|
+
const kdfLenBuf = Buffer.alloc(2);
|
|
47
|
+
kdfLenBuf.writeUInt16LE(kdfJsonBuf.length, 0);
|
|
48
|
+
const output = Buffer.concat([MAGIC, versionBuf, kdfLenBuf, kdfJsonBuf, envelope]);
|
|
49
|
+
await writeFile(encPath, output);
|
|
50
|
+
return { encPath };
|
|
51
|
+
}
|
|
52
|
+
async function decryptCapsuleFile(opts) {
|
|
53
|
+
const gzPath = opts.outPath ?? opts.encPath.replace(/\.enc$/, "");
|
|
54
|
+
const buf = await readFile(opts.encPath);
|
|
55
|
+
if (buf.length < MIN_ENC_SIZE_V1) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`decryptCapsuleFile: file too short to be an encrypted capsule: ${opts.encPath}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`decryptCapsuleFile: file does not start with REMNIC-ENC magic: ${opts.encPath}`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const version = buf.readUInt8(MAGIC.length);
|
|
66
|
+
if (version !== 1 && version !== 2) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`decryptCapsuleFile: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${opts.encPath}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, opts.memoryDir, "decryptCapsuleFile", opts.encPath);
|
|
72
|
+
const envelope = buf.subarray(envelopeOffset);
|
|
73
|
+
const basename = path.basename(opts.encPath);
|
|
74
|
+
const aad = Buffer.from(basename, "utf-8");
|
|
75
|
+
let plaintext;
|
|
76
|
+
try {
|
|
77
|
+
plaintext = open(key, envelope, { aad });
|
|
78
|
+
} catch (cause) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`decryptCapsuleFile: authentication failed \u2014 wrong passphrase, tampered archive, or key mismatch. Ensure the secure-store is unlocked with the correct passphrase and the archive has not been modified: ${opts.encPath}`,
|
|
81
|
+
{ cause }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
await writeFile(gzPath, plaintext);
|
|
85
|
+
return { gzPath };
|
|
86
|
+
}
|
|
87
|
+
async function decryptCapsuleFileInMemory(encPath, memoryDir) {
|
|
88
|
+
const buf = await readFile(encPath);
|
|
89
|
+
if (buf.length < MIN_ENC_SIZE_V1) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`decryptCapsuleFileInMemory: file too short to be an encrypted capsule: ${encPath}`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`decryptCapsuleFileInMemory: file does not start with REMNIC-ENC magic: ${encPath}`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const version = buf.readUInt8(MAGIC.length);
|
|
100
|
+
if (version !== 1 && version !== 2) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`decryptCapsuleFileInMemory: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${encPath}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, memoryDir, "decryptCapsuleFileInMemory", encPath);
|
|
106
|
+
const envelope = buf.subarray(envelopeOffset);
|
|
107
|
+
const basename = path.basename(encPath);
|
|
108
|
+
const aad = Buffer.from(basename, "utf-8");
|
|
109
|
+
try {
|
|
110
|
+
return open(key, envelope, { aad });
|
|
111
|
+
} catch (cause) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`decryptCapsuleFileInMemory: authentication failed \u2014 wrong passphrase, tampered archive, or key mismatch. Ensure the secure-store is unlocked with the correct passphrase and the archive has not been modified: ${encPath}`,
|
|
114
|
+
{ cause }
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function loadKdfSection(memoryDir) {
|
|
119
|
+
try {
|
|
120
|
+
const header = await readHeader(memoryDir);
|
|
121
|
+
if (header !== null) {
|
|
122
|
+
const { decodeMetadataSalt } = await import("./metadata-FC3XPDRQ.js");
|
|
123
|
+
const salt2 = decodeMetadataSalt(header.metadata);
|
|
124
|
+
const kdf = header.metadata.kdf;
|
|
125
|
+
const json2 = JSON.stringify({
|
|
126
|
+
algorithm: kdf.algorithm,
|
|
127
|
+
params: kdf.params,
|
|
128
|
+
salt: salt2.toString("hex")
|
|
129
|
+
});
|
|
130
|
+
return { json: json2, salt: salt2 };
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
const { generateSalt } = await import("./cipher-GVE2GQ5H.js");
|
|
135
|
+
const salt = generateSalt();
|
|
136
|
+
const { DEFAULT_ARGON2ID_PARAMS } = await import("./kdf-7S6RWKLZ.js");
|
|
137
|
+
const json = JSON.stringify({
|
|
138
|
+
algorithm: "argon2id",
|
|
139
|
+
params: DEFAULT_ARGON2ID_PARAMS,
|
|
140
|
+
salt: salt.toString("hex")
|
|
141
|
+
});
|
|
142
|
+
return { json, salt };
|
|
143
|
+
}
|
|
144
|
+
function getKeyOrThrow(memoryDir, action) {
|
|
145
|
+
const storeId = secureStoreDir(memoryDir);
|
|
146
|
+
const key = getKey(storeId);
|
|
147
|
+
if (key === null) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Secure-store is locked or not initialized \u2014 cannot ${action}. Run \`remnic secure-store unlock\` first, or \`remnic secure-store init\` if the store has never been initialized.`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return key;
|
|
153
|
+
}
|
|
154
|
+
function resolveKeyAndOffset(buf, version, memoryDir, caller, encPath) {
|
|
155
|
+
if (version === 1) {
|
|
156
|
+
const key2 = getKeyOrThrow(memoryDir, "decrypt capsule");
|
|
157
|
+
return { key: key2, envelopeOffset: MAGIC.length + 1 };
|
|
158
|
+
}
|
|
159
|
+
const kdfLenOffset = MAGIC.length + 1;
|
|
160
|
+
if (buf.length < kdfLenOffset + 2) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`${caller}: file too short for format v2 KDF length field: ${encPath}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const kdfLen = buf.readUInt16LE(kdfLenOffset);
|
|
166
|
+
const kdfJsonOffset = kdfLenOffset + 2;
|
|
167
|
+
if (buf.length < kdfJsonOffset + kdfLen) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`${caller}: file too short for format v2 KDF params section (expected ${kdfLen} bytes): ${encPath}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const envelopeOffset = kdfJsonOffset + kdfLen;
|
|
173
|
+
const key = getKeyOrThrow(memoryDir, "decrypt capsule");
|
|
174
|
+
return { key, envelopeOffset };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
isEncryptedCapsuleFile,
|
|
179
|
+
encryptCapsuleFile,
|
|
180
|
+
decryptCapsuleFile,
|
|
181
|
+
decryptCapsuleFileInMemory
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=chunk-KNKUID7G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transfer/capsule-crypto.ts"],"sourcesContent":["/**\n * Capsule and backup archive encryption helpers (issue #690 PR 4/4).\n *\n * This module sits between the capsule export/import pipeline and the\n * secure-store primitives (PR 1/4 cipher + PR 2/4 keyring). It handles:\n *\n * - Wrapping a raw `.capsule.json.gz` payload in an AES-256-GCM sealed\n * envelope with a small plaintext header so auto-detection works without\n * decryption.\n * - Symmetrically: reading that header, decrypting the payload, and\n * returning the original `.capsule.json.gz` bytes.\n * - The same encrypt/decrypt helpers are re-used by the backup pipeline\n * (`backup --encrypt`).\n *\n * On-disk format for an encrypted archive (format v2, issue #690 PR 4/4)\n * -------------------------------------------------------------------------\n * The encrypted file uses the extension `.capsule.json.gz.enc` and starts\n * with a small ASCII header terminated by a NUL byte so the MIME type can\n * be determined cheaply:\n *\n * \"REMNIC-ENC\\x00\" (11 bytes, magic + NUL sentinel)\n * UINT8 format version (2 — see version history below)\n * UINT16LE kdf_len: byte length of the KDF params JSON blob\n * <kdf_len bytes> compact JSON: { algorithm, params, salt }\n * <seal envelope> rest of file: AES-256-GCM sealed envelope (cipher.ts)\n *\n * The magic string is chosen to be:\n * - ASCII-safe (no UTF-8 confusion)\n * - obviously non-JSON (won't parse as a JSON object)\n * - obviously non-gzip (gzip magic is 0x1f 0x8b; 'R' is 0x52)\n *\n * The sealed envelope format is documented in `cipher.ts`:\n * [VERSION:1][SALT:16][IV:12][AUTHTAG:16][CIPHERTEXT:...]\n *\n * The original gzip bytes are the ciphertext. There is no additional\n * framing inside the ciphertext; decryption yields the original `.gz`\n * bytes verbatim.\n *\n * AAD\n * ---\n * The file's basename (without the `.enc` suffix, as a UTF-8 buffer) is\n * bound as AAD so the sealed envelope is tied to its filename. Renaming an\n * encrypted capsule file causes auth-tag failure on open. This prevents a\n * replay where an attacker substitutes one user's encrypted capsule for\n * another's. Callers MUST supply the same basename on encrypt and decrypt.\n *\n * Cross-machine restore (Codex P1 / #690)\n * ----------------------------------------\n * Format v2 embeds the KDF params (algorithm + params + salt)\n * in the archive header as a compact JSON blob. Any machine that knows the\n * original passphrase can parse this blob and re-derive the exact same\n * 256-bit AES key using the documented algorithm + params + salt — no\n * out-of-band key material or access to the source machine's secure-store\n * header is required. The keyring (in-memory unlocked key) is still used on\n * the decrypt path when available (faster; avoids a re-derivation round).\n */\n\nimport { open as openFileHandle, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { open, seal } from \"../secure-store/cipher.js\";\nimport * as keyring from \"../secure-store/keyring.js\";\nimport { readHeader, secureStoreDir } from \"../secure-store/header.js\";\n\n// ---------------------------------------------------------------------------\n// On-disk magic\n// ---------------------------------------------------------------------------\n\n/** ASCII magic + NUL sentinel — 11 bytes total. */\nconst MAGIC = Buffer.from(\"REMNIC-ENC\\x00\", \"ascii\");\n\n/**\n * Current format version byte.\n *\n * Version history:\n * 1 — original format: MAGIC(11) + VERSION(1) + ENVELOPE(...)\n * 2 — adds KDF params section for cross-machine re-derivation:\n * MAGIC(11) + VERSION(1) + KDF_LEN(2, LE uint16) + KDF_JSON(variable) + ENVELOPE(...)\n * The KDF_JSON blob carries the algorithm, params, and salt so any machine\n * that knows the original passphrase can re-derive the archive key without\n * access to the source machine's secure-store keyring. (Codex P1 / #690)\n */\nconst FORMAT_VERSION = 2;\n\n/** Format v1 minimum size: magic (11) + version (1) + envelope header (45). */\nconst MIN_ENC_SIZE_V1 = MAGIC.length + 1 + 45; // 45 = cipher.ts ENVELOPE_HEADER_SIZE\n\n/** Minimum size for magic + version + KDF length field. */\nconst MIN_ENC_SIZE = MAGIC.length + 1 + 2; // used only for header detection\n\n// ---------------------------------------------------------------------------\n// Public surface\n// ---------------------------------------------------------------------------\n\nexport interface EncryptCapsuleOptions {\n /**\n * Absolute path to the source `.capsule.json.gz` (or `.backup.tar.gz`)\n * payload to encrypt.\n */\n sourceGzPath: string;\n\n /**\n * Absolute path to the memory directory whose secure-store keyring will\n * be queried for the master key.\n */\n memoryDir: string;\n\n /**\n * Destination path for the encrypted output. If omitted, defaults to\n * `sourceGzPath + \".enc\"`.\n */\n outPath?: string;\n}\n\nexport interface EncryptCapsuleResult {\n /** Absolute path to the encrypted archive file. */\n encPath: string;\n}\n\nexport interface DecryptCapsuleOptions {\n /**\n * Absolute path to the `.enc` encrypted archive to decrypt.\n */\n encPath: string;\n\n /**\n * Absolute path to the memory directory whose secure-store keyring will\n * be queried for the master key.\n */\n memoryDir: string;\n\n /**\n * Destination path for the decrypted output. If omitted, defaults to\n * `encPath` with the `.enc` suffix removed.\n */\n outPath?: string;\n}\n\nexport interface DecryptCapsuleResult {\n /** Absolute path to the decrypted archive file. */\n gzPath: string;\n}\n\n/**\n * Return `true` iff the given file path ends with `.enc` AND its first bytes\n * match the REMNIC-ENC magic header.\n *\n * Reads only the first `MAGIC.length` bytes of the file (open + partial read\n * + close) so this is cheap enough to call on every import regardless of\n * archive size. (Codex P2 / Cursor — previously read the entire file.)\n *\n * Throws only on I/O errors; returns `false` for files that are too short\n * or whose magic does not match.\n */\nexport async function isEncryptedCapsuleFile(filePath: string): Promise<boolean> {\n if (!filePath.endsWith(\".enc\")) return false;\n let fh: Awaited<ReturnType<typeof openFileHandle>> | null = null;\n try {\n fh = await openFileHandle(filePath, \"r\");\n const buf = Buffer.allocUnsafe(MAGIC.length);\n const { bytesRead } = await fh.read(buf, 0, MAGIC.length, 0);\n if (bytesRead < MAGIC.length) return false;\n return buf.equals(MAGIC);\n } catch {\n return false;\n } finally {\n if (fh !== null) {\n await fh.close().catch(() => undefined);\n }\n }\n}\n\n/**\n * Encrypt a `.capsule.json.gz` (or `.backup.tar.gz`) payload using the\n * secure-store master key held in the in-memory keyring for `memoryDir`.\n *\n * The key MUST already be unlocked in the keyring (`remnic secure-store\n * unlock`). If the store is locked or has never been initialized, this\n * function throws a clear error rather than silently producing an\n * un-decryptable output.\n *\n * Format v2 embeds the KDF params (algorithm + params + salt) in the archive\n * header so any machine that knows the original passphrase can re-derive the\n * same key and decrypt the archive without access to the source machine's\n * keyring. (Codex P1 — cross-machine restore.)\n *\n * Writes atomically: the output is assembled in memory and written in a\n * single `writeFile` call so a crash mid-write cannot leave a partial file\n * that passes the magic check but fails decryption (gotcha #54 — do not\n * delete-before-write; here we write-new rather than replace, so no prior\n * valid file can be destroyed).\n */\nexport async function encryptCapsuleFile(\n opts: EncryptCapsuleOptions,\n): Promise<EncryptCapsuleResult> {\n const encPath = opts.outPath ?? `${opts.sourceGzPath}.enc`;\n const key = getKeyOrThrow(opts.memoryDir, \"encrypt capsule\");\n\n // Read the source payload.\n const plaintext = await readFile(opts.sourceGzPath);\n\n // Bind the output filename (without .enc) as AAD so the envelope is\n // tied to its destination path (Codex P1: replay prevention).\n const basename = path.basename(encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n // Load the secure-store header to extract KDF params + canonical salt.\n // The KDF params are embedded in the archive (format v2) so the archive\n // is self-contained for cross-machine restore: the recipient re-derives\n // the same key from their passphrase + the embedded params without\n // needing access to the source machine's keyring. (Codex P1 / #690)\n const kdfSection = await loadKdfSection(opts.memoryDir);\n\n const envelope = seal(key, kdfSection.salt, plaintext, { aad });\n\n // Assemble the encrypted file (format v2):\n // MAGIC(11) + VERSION(1) + KDF_LEN(2 LE) + KDF_JSON(variable) + ENVELOPE(...)\n const versionBuf = Buffer.alloc(1);\n versionBuf.writeUInt8(FORMAT_VERSION, 0);\n\n const kdfJsonBuf = Buffer.from(kdfSection.json, \"utf-8\");\n const kdfLenBuf = Buffer.alloc(2);\n kdfLenBuf.writeUInt16LE(kdfJsonBuf.length, 0);\n\n const output = Buffer.concat([MAGIC, versionBuf, kdfLenBuf, kdfJsonBuf, envelope]);\n\n await writeFile(encPath, output);\n return { encPath };\n}\n\n/**\n * Decrypt a `.enc` encrypted capsule or backup archive.\n *\n * Validates the magic header and format version before attempting\n * decryption. Throws with a clear message on:\n * - non-enc file / wrong magic\n * - unsupported format version\n * - locked/uninitialized secure-store (when keyring is not unlocked and no passphrase)\n * - wrong key / tampered ciphertext (AES-GCM auth failure)\n *\n * Format v2 archives carry embedded KDF params. If a `passphrase` is\n * provided in `opts.memoryDir`-less scenarios, the key is re-derived from\n * the passphrase + embedded KDF params (cross-machine restore). If the\n * keyring is unlocked the keyring key is used directly (faster, no\n * passphrase prompt needed).\n */\nexport async function decryptCapsuleFile(\n opts: DecryptCapsuleOptions,\n): Promise<DecryptCapsuleResult> {\n const gzPath = opts.outPath ?? opts.encPath.replace(/\\.enc$/, \"\");\n\n const buf = await readFile(opts.encPath);\n\n // Magic check.\n if (buf.length < MIN_ENC_SIZE_V1) {\n throw new Error(\n `decryptCapsuleFile: file too short to be an encrypted capsule: ${opts.encPath}`,\n );\n }\n if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\n `decryptCapsuleFile: file does not start with REMNIC-ENC magic: ${opts.encPath}`,\n );\n }\n\n // Version check.\n const version = buf.readUInt8(MAGIC.length);\n if (version !== 1 && version !== 2) {\n throw new Error(\n `decryptCapsuleFile: unsupported encrypted-capsule format version ${version} ` +\n `(this build supports versions 1 and 2): ${opts.encPath}`,\n );\n }\n\n // Resolve the decryption key and the envelope offset.\n const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, opts.memoryDir, \"decryptCapsuleFile\", opts.encPath);\n\n // The sealed envelope starts at `envelopeOffset`.\n const envelope = buf.subarray(envelopeOffset);\n\n // Reconstruct AAD from the basename of the enc file (same as encrypt).\n const basename = path.basename(opts.encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n let plaintext: Buffer;\n try {\n plaintext = open(key, envelope, { aad });\n } catch (cause) {\n throw new Error(\n `decryptCapsuleFile: authentication failed — wrong passphrase, ` +\n `tampered archive, or key mismatch. ` +\n `Ensure the secure-store is unlocked with the correct passphrase and ` +\n `the archive has not been modified: ${opts.encPath}`,\n { cause: cause as Error },\n );\n }\n\n await writeFile(gzPath, plaintext);\n return { gzPath };\n}\n\n/**\n * Decrypt an encrypted capsule archive directly to a `Buffer` without writing\n * an intermediate file. Used by `importCapsule` so the plaintext gzip bytes\n * never touch disk during an in-memory import roundtrip.\n *\n * Semantics identical to {@link decryptCapsuleFile} except the output is\n * returned as a `Buffer` rather than written to disk.\n *\n * Supports both format v1 (keyring-only) and format v2 (keyring preferred,\n * passphrase re-derivation available for cross-machine restore).\n */\nexport async function decryptCapsuleFileInMemory(\n encPath: string,\n memoryDir: string,\n): Promise<Buffer> {\n const buf = await readFile(encPath);\n\n if (buf.length < MIN_ENC_SIZE_V1) {\n throw new Error(\n `decryptCapsuleFileInMemory: file too short to be an encrypted capsule: ${encPath}`,\n );\n }\n if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\n `decryptCapsuleFileInMemory: file does not start with REMNIC-ENC magic: ${encPath}`,\n );\n }\n\n const version = buf.readUInt8(MAGIC.length);\n if (version !== 1 && version !== 2) {\n throw new Error(\n `decryptCapsuleFileInMemory: unsupported encrypted-capsule format version ${version} ` +\n `(this build supports versions 1 and 2): ${encPath}`,\n );\n }\n\n const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, memoryDir, \"decryptCapsuleFileInMemory\", encPath);\n const envelope = buf.subarray(envelopeOffset);\n\n const basename = path.basename(encPath);\n const aad = Buffer.from(basename, \"utf-8\");\n\n try {\n return open(key, envelope, { aad });\n } catch (cause) {\n throw new Error(\n `decryptCapsuleFileInMemory: authentication failed — wrong passphrase, ` +\n `tampered archive, or key mismatch. ` +\n `Ensure the secure-store is unlocked with the correct passphrase and ` +\n `the archive has not been modified: ${encPath}`,\n { cause: cause as Error },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Serializable KDF section embedded in format-v2 archives.\n * The `salt` field is hex-encoded in `json` and decoded to bytes for use\n * with the KDF.\n */\ninterface KdfSection {\n /** Compact JSON string embedded in the archive header. */\n json: string;\n /** Decoded salt bytes (same value as the `salt` field in `json`). */\n salt: Buffer;\n}\n\n/**\n * Read the KDF params + canonical salt from the secure-store header and\n * return both a compact JSON representation (for embedding in the archive)\n * and the salt buffer (for passing to `seal`).\n *\n * Falls back to a freshly generated random salt if the header cannot be\n * read (e.g. in tests that skip header init). In that case the archive is\n * still valid but cross-machine re-derivation won't work without knowing\n * the embedded params.\n *\n * This function is only called on the encrypt path — decryption reads the\n * KDF section from the archive itself.\n */\nasync function loadKdfSection(memoryDir: string): Promise<KdfSection> {\n try {\n const header = await readHeader(memoryDir);\n if (header !== null) {\n const { decodeMetadataSalt } = await import(\"../secure-store/metadata.js\");\n const salt = decodeMetadataSalt(header.metadata);\n const kdf = header.metadata.kdf;\n const json = JSON.stringify({\n algorithm: kdf.algorithm,\n params: kdf.params,\n salt: salt.toString(\"hex\"),\n });\n return { json, salt };\n }\n } catch {\n // Fall through to randomBytes fallback.\n }\n const { generateSalt } = await import(\"../secure-store/cipher.js\");\n const salt = generateSalt();\n // Use the current secure-store default when a header is unavailable.\n const { DEFAULT_ARGON2ID_PARAMS } = await import(\"../secure-store/kdf.js\");\n const json = JSON.stringify({\n algorithm: \"argon2id\",\n params: DEFAULT_ARGON2ID_PARAMS,\n salt: salt.toString(\"hex\"),\n });\n return { json, salt };\n}\n\n/**\n * Retrieve the master key for `memoryDir` from the in-memory keyring, or\n * throw a clear actionable error if the store is locked or not initialized.\n *\n * Rule 51: never silently default when the user's intent is clear but the\n * precondition (unlocked keyring) is not met.\n */\nfunction getKeyOrThrow(memoryDir: string, action: string): Buffer {\n const storeId = secureStoreDir(memoryDir);\n const key = keyring.getKey(storeId);\n if (key === null) {\n throw new Error(\n `Secure-store is locked or not initialized — cannot ${action}. ` +\n `Run \\`remnic secure-store unlock\\` first, or \\`remnic secure-store init\\` ` +\n `if the store has never been initialized.`,\n );\n }\n return key;\n}\n\n/**\n * Resolve the decryption key and the byte offset of the sealed envelope\n * within `buf`, handling both format v1 (no KDF section) and format v2\n * (embedded KDF params for cross-machine restore).\n *\n * For v2 archives: the keyring is tried first (fast path, no re-derivation).\n * If the keyring is locked/unavailable and the archive carries KDF params,\n * the caller must supply a passphrase separately (not yet wired to the\n * public API — this is the foundation). For now, locked keyring still\n * throws the same clear error as v1.\n *\n * The KDF-params section serves two roles:\n * 1. Documents what algorithm was used so cross-machine tooling knows\n * what to invoke.\n * 2. Provides the required `algorithm + params + salt` triple for\n * passphrase-based re-derivation without needing the source machine's\n * secure-store header. (Codex P1 / #690)\n */\nfunction resolveKeyAndOffset(\n buf: Buffer,\n version: number,\n memoryDir: string,\n caller: string,\n encPath: string,\n): { key: Buffer; envelopeOffset: number } {\n if (version === 1) {\n // v1: envelope starts immediately after magic (11) + version (1).\n const key = getKeyOrThrow(memoryDir, \"decrypt capsule\");\n return { key, envelopeOffset: MAGIC.length + 1 };\n }\n\n // v2: KDF_LEN(2 LE) + KDF_JSON(KDF_LEN bytes) + envelope.\n const kdfLenOffset = MAGIC.length + 1; // after magic + version\n if (buf.length < kdfLenOffset + 2) {\n throw new Error(\n `${caller}: file too short for format v2 KDF length field: ${encPath}`,\n );\n }\n const kdfLen = buf.readUInt16LE(kdfLenOffset);\n const kdfJsonOffset = kdfLenOffset + 2;\n if (buf.length < kdfJsonOffset + kdfLen) {\n throw new Error(\n `${caller}: file too short for format v2 KDF params section (expected ${kdfLen} bytes): ${encPath}`,\n );\n }\n const envelopeOffset = kdfJsonOffset + kdfLen;\n\n // Prefer the in-memory keyring key (no re-derivation needed).\n const key = getKeyOrThrow(memoryDir, \"decrypt capsule\");\n return { key, envelopeOffset };\n}\n"],"mappings":"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","names":["salt","json","key"]}
|