@remnic/core 9.69.33 → 9.69.35
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/access-admin-ops-surface.d.ts +14 -11
- package/dist/access-admin-ops-surface.js +65 -60
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +14 -11
- package/dist/access-authorization-probe.js +66 -61
- package/dist/access-boundary.d.ts +14 -11
- package/dist/access-boundary.js +65 -60
- package/dist/access-cli.js +137 -133
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +3 -1
- package/dist/access-coding-context-resolution.js +3 -3
- package/dist/access-extraction-force-flush.d.ts +14 -11
- package/dist/access-extraction-force-flush.js +65 -60
- package/dist/access-health-types.d.ts +3 -1
- package/dist/access-http-briefing.d.ts +14 -11
- package/dist/access-http-briefing.js +66 -61
- package/dist/access-http-lcm-compaction.d.ts +14 -11
- package/dist/access-http-lifecycle-flush.d.ts +14 -11
- package/dist/access-http-offline-stream.d.ts +14 -11
- package/dist/access-http-query.d.ts +4 -2
- package/dist/access-http-query.js +67 -62
- package/dist/access-http.d.ts +15 -12
- package/dist/access-http.js +86 -82
- package/dist/access-identity-continuity-surface.d.ts +12 -9
- package/dist/access-identity-continuity-surface.js +65 -60
- package/dist/access-lcm-surface.d.ts +14 -11
- package/dist/access-lcm-surface.js +65 -60
- package/dist/access-mcp.d.ts +14 -11
- package/dist/access-mcp.js +74 -70
- package/dist/access-memory-search-fanout.d.ts +4 -2
- package/dist/{access-namespace-preflight-DMR-jOMS.d.ts → access-namespace-preflight-D8qri11P.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +5 -3
- package/dist/access-namespace-preflight.js +65 -60
- package/dist/access-observe-transcript.d.ts +12 -9
- package/dist/access-observe-transcript.js +3 -3
- package/dist/access-observe-write-surface.d.ts +16 -13
- package/dist/access-observe-write-surface.js +65 -60
- package/dist/access-offline-manifest.d.ts +48 -11
- package/dist/access-offline-manifest.js +18 -16
- package/dist/access-operations-batch.js +68 -64
- package/dist/access-operations.d.ts +15 -12
- package/dist/access-operations.js +73 -69
- package/dist/access-recall-concurrency.d.ts +14 -11
- package/dist/access-recall-concurrency.js +65 -60
- package/dist/access-recall-response.d.ts +14 -11
- package/dist/access-recall-response.js +65 -60
- package/dist/access-recall-surface.d.ts +14 -11
- package/dist/access-recall-surface.js +65 -60
- package/dist/access-schema.d.ts +56 -13
- package/dist/access-schema.js +15 -1
- package/dist/{access-service-CJQoQvRa.d.ts → access-service-CKu5ixg9.d.ts} +52 -50
- package/dist/access-service-helpers.d.ts +14 -11
- package/dist/access-service.d.ts +14 -11
- package/dist/access-service.js +65 -60
- package/dist/access-surface-catalog.d.ts +14 -11
- package/dist/access-surface-catalog.js +67 -62
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +5 -3
- package/dist/action-confidence.d.ts +3 -1
- package/dist/active-memory-bridge.d.ts +3 -1
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +3 -1
- package/dist/active-recall.js +12 -10
- package/dist/active-recall.js.map +1 -1
- package/dist/activity/digest.d.ts +3 -1
- package/dist/adapters/index.d.ts +46 -1
- package/dist/adapters/index.js +10 -6
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +3 -1
- package/dist/artifact-search.d.ts +3 -1
- package/dist/{auto-sync-NSHLUAQI.js → auto-sync-4YFATLFQ.js} +10 -9
- package/dist/{auto-sync-NSHLUAQI.js.map → auto-sync-4YFATLFQ.js.map} +1 -1
- package/dist/behavior-learner.d.ts +3 -1
- package/dist/behavior-signals.d.ts +3 -1
- package/dist/bootstrap.d.ts +12 -9
- package/dist/briefing-window.d.ts +4 -2
- package/dist/briefing.d.ts +4 -2
- package/dist/briefing.js +26 -25
- package/dist/buffer-surprise-report.d.ts +3 -1
- package/dist/buffer-turn-helpers.d.ts +3 -1
- package/dist/buffer.d.ts +4 -2
- package/dist/buffer.js +11 -10
- package/dist/bulk-import/index.d.ts +5 -3
- package/dist/calibration.d.ts +3 -1
- package/dist/calibration.js +3 -2
- package/dist/calibration.js.map +1 -1
- package/dist/capabilities.d.ts +3 -1
- package/dist/{capsule-merge-IPG4IOFP.js → capsule-merge-ZCXUPLNJ.js} +2 -2
- package/dist/{catalog-8O9KY9eA.d.ts → catalog-Bq1AxZwF.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +3 -1
- package/dist/causal-consolidation.d.ts +3 -1
- package/dist/causal-consolidation.js +27 -26
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +3 -1
- package/dist/{chunk-CDKHKZL5.js → chunk-2524MOWK.js} +2 -2
- package/dist/{chunk-HVAEXYPL.js → chunk-255PC37A.js} +47 -25
- package/dist/chunk-255PC37A.js.map +1 -0
- package/dist/{chunk-2C3S7J2S.js → chunk-2BQ4ZIWC.js} +741 -28
- package/dist/chunk-2BQ4ZIWC.js.map +1 -0
- package/dist/{chunk-RKBLRTNT.js → chunk-2YLMUME2.js} +2 -2
- package/dist/{chunk-QOIOACIE.js → chunk-326KUXIR.js} +15 -648
- package/dist/chunk-326KUXIR.js.map +1 -0
- package/dist/{chunk-DBQWVT2H.js → chunk-3CBI2ZSA.js} +2 -2
- package/dist/{chunk-MWFGUESQ.js → chunk-3FJKJ5UZ.js} +2 -2
- package/dist/{chunk-NZXEK3UF.js → chunk-3Q3N35W7.js} +2 -2
- package/dist/{chunk-YYGZJPOK.js → chunk-42DJ235G.js} +2 -2
- package/dist/{chunk-SO7SV523.js → chunk-4MDKNUV4.js} +1 -1
- package/dist/chunk-4MDKNUV4.js.map +1 -0
- package/dist/chunk-5HYUUFMQ.js +1280 -0
- package/dist/chunk-5HYUUFMQ.js.map +1 -0
- package/dist/{chunk-2JVJ7UHC.js → chunk-5JG5EBVL.js} +4 -2
- package/dist/chunk-5JG5EBVL.js.map +1 -0
- package/dist/{chunk-HV7OY4DM.js → chunk-5VAF4ID4.js} +643 -202
- package/dist/chunk-5VAF4ID4.js.map +1 -0
- package/dist/{chunk-N7RWREIQ.js → chunk-65RENJGB.js} +6 -1
- package/dist/chunk-65RENJGB.js.map +1 -0
- package/dist/{chunk-JTH2SE6B.js → chunk-6J6K3STG.js} +8 -8
- package/dist/{chunk-H4VH5VIB.js → chunk-776GVKL7.js} +2 -2
- package/dist/{chunk-BUTCAMJM.js → chunk-A2YQL2FF.js} +5 -5
- package/dist/chunk-A5UQ52YQ.js +211 -0
- package/dist/chunk-A5UQ52YQ.js.map +1 -0
- package/dist/{chunk-X2NFFBTO.js → chunk-A7GQBJP5.js} +4 -4
- package/dist/{chunk-CGC5UQCF.js → chunk-AKE4GGQ3.js} +2 -2
- package/dist/{chunk-B325AGLK.js → chunk-AZSKROVQ.js} +2 -2
- package/dist/{chunk-I5DZ3WGR.js → chunk-BJETIR53.js} +3 -3
- package/dist/{chunk-JT3EB7ZL.js → chunk-BNGHPYZU.js} +5 -5
- package/dist/chunk-BRZWWUCJ.js +13 -0
- package/dist/{chunk-FYDW33ZB.js.map → chunk-BRZWWUCJ.js.map} +1 -1
- package/dist/{chunk-3JVLGJCY.js → chunk-C6KRO3SU.js} +2 -2
- package/dist/{chunk-5NANRSCD.js → chunk-CNV2A557.js} +5 -5
- package/dist/{chunk-PBGVVDLY.js → chunk-DK4X5B6I.js} +2 -2
- package/dist/{chunk-MFDTVQJX.js → chunk-DVOBLPSQ.js} +22 -7
- package/dist/chunk-DVOBLPSQ.js.map +1 -0
- package/dist/{chunk-N2ZNPHA3.js → chunk-ECKG5WSI.js} +2 -2
- package/dist/{chunk-PYLL63BF.js → chunk-EEBQFG5E.js} +9 -9
- package/dist/{chunk-ET356KSB.js → chunk-F4TWWUMP.js} +2 -2
- package/dist/{chunk-RHQMKJFG.js → chunk-F6IVBYFS.js} +55 -51
- package/dist/{chunk-RHQMKJFG.js.map → chunk-F6IVBYFS.js.map} +1 -1
- package/dist/{chunk-CLLPJ6QT.js → chunk-FQXJAC3T.js} +2 -2
- package/dist/{chunk-JGHXXQ2G.js → chunk-FVJ4D6L7.js} +2 -2
- package/dist/{chunk-DD5JFCWM.js → chunk-GCBIXUPT.js} +2 -2
- package/dist/{chunk-MN3LK3KN.js → chunk-GLZH5VEN.js} +2 -2
- package/dist/{chunk-S7T2TY65.js → chunk-HC4GFLMQ.js} +3 -3
- package/dist/{chunk-EQHDH4C2.js → chunk-HUT2JR6I.js} +3 -3
- package/dist/{chunk-UUQG7HAD.js → chunk-HXSAWV3A.js} +4 -4
- package/dist/{chunk-XXIHX75O.js → chunk-J7PB5UQ4.js} +3 -3
- package/dist/{chunk-UGPUYIET.js → chunk-JHZCXUQI.js} +221 -400
- package/dist/chunk-JHZCXUQI.js.map +1 -0
- package/dist/{chunk-LTIZHLV7.js → chunk-JR6H5CYS.js} +2 -2
- package/dist/{chunk-FCSZ4K2X.js → chunk-JR6PP7UM.js} +3 -3
- package/dist/{chunk-TCUKRAMK.js → chunk-JRWW7GM6.js} +10 -10
- package/dist/{chunk-Q726HSJO.js → chunk-JSRVXI6E.js} +16 -15
- package/dist/chunk-JSRVXI6E.js.map +1 -0
- package/dist/{chunk-DB5TGMLZ.js → chunk-JZ2CHRLB.js} +6 -4
- package/dist/{chunk-DB5TGMLZ.js.map → chunk-JZ2CHRLB.js.map} +1 -1
- package/dist/{chunk-JEIXTYVG.js → chunk-L2QLDZJC.js} +46 -17
- package/dist/chunk-L2QLDZJC.js.map +1 -0
- package/dist/{chunk-PL7FYKHT.js → chunk-L2WQVSKP.js} +2 -2
- package/dist/{chunk-JSN44KIB.js → chunk-LEMD7WZJ.js} +9 -9
- package/dist/{chunk-VZWXFXLX.js → chunk-LMCD5W5B.js} +2 -2
- package/dist/{chunk-7BMXZCOT.js → chunk-LNDLXMH6.js} +3 -3
- package/dist/{chunk-3QQTXYZ6.js → chunk-LSLCFCCQ.js} +2 -1
- package/dist/chunk-LSLCFCCQ.js.map +1 -0
- package/dist/{chunk-EONF76DT.js → chunk-LYDJRF45.js} +2 -2
- package/dist/{chunk-MKD3OMPS.js → chunk-M3MYMWXG.js} +2 -2
- package/dist/{chunk-VGXM5B4H.js → chunk-MNIPH6LD.js} +2 -2
- package/dist/{chunk-A7XEPMQ6.js → chunk-MVAQ2WM3.js} +6 -6
- package/dist/chunk-MVAQ2WM3.js.map +1 -0
- package/dist/{chunk-6N3TQFZU.js → chunk-NN4JEFON.js} +3 -3
- package/dist/chunk-NPNSKE76.js +220 -0
- package/dist/chunk-NPNSKE76.js.map +1 -0
- package/dist/{chunk-MOZXTRC2.js → chunk-OQ7SSRXP.js} +19 -19
- package/dist/{chunk-XU6OEECT.js → chunk-OQQXGYMX.js} +3 -3
- package/dist/{chunk-4MHYKEOM.js → chunk-OS2AT2JU.js} +10 -10
- package/dist/{chunk-N57A4KPV.js → chunk-P3ONDDIJ.js} +2 -2
- package/dist/chunk-PCEYGOSL.js +66 -0
- package/dist/chunk-PCEYGOSL.js.map +1 -0
- package/dist/{chunk-R3HKWWUB.js → chunk-PHP3MUGF.js} +2 -2
- package/dist/{chunk-EEOUMG3J.js → chunk-PWPIERBM.js} +38 -6
- package/dist/chunk-PWPIERBM.js.map +1 -0
- package/dist/chunk-Q4AUIFUA.js +111 -0
- package/dist/chunk-Q4AUIFUA.js.map +1 -0
- package/dist/{chunk-P3SB5BNT.js → chunk-QATYVTP7.js} +2 -2
- package/dist/{chunk-LSYDG6MJ.js → chunk-QBLDCI6E.js} +2 -2
- package/dist/{chunk-KCB7F4J7.js → chunk-QURNMKME.js} +2 -2
- package/dist/{chunk-XOVKXJEP.js → chunk-R3TLVTWW.js} +3 -3
- package/dist/{chunk-XXE5P6HJ.js → chunk-RRZKTSFG.js} +2 -2
- package/dist/{chunk-44T3Y7SZ.js → chunk-RUXPVSML.js} +5 -5
- package/dist/{chunk-DCJ3YFIC.js → chunk-S2ULTQZR.js} +2 -2
- package/dist/{chunk-H272ZPQ3.js → chunk-SHEHQBCG.js} +124 -23
- package/dist/chunk-SHEHQBCG.js.map +1 -0
- package/dist/{chunk-EEC4PCG5.js → chunk-SZDLX763.js} +2 -2
- package/dist/{chunk-E2ZHGBAK.js → chunk-T2JSUEH6.js} +2 -2
- package/dist/{chunk-227UFSEQ.js → chunk-TFA6HPOA.js} +2 -2
- package/dist/{chunk-BA6WOZOT.js → chunk-TK4FHQRN.js} +4 -4
- package/dist/{chunk-W27OW7AB.js → chunk-TKFSXDOB.js} +2 -2
- package/dist/chunk-TLHNF6GA.js +647 -0
- package/dist/chunk-TLHNF6GA.js.map +1 -0
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-FDLDOEO6.js → chunk-UBG4GAEP.js} +51 -6
- package/dist/chunk-UBG4GAEP.js.map +1 -0
- package/dist/{chunk-CETXNLEX.js → chunk-UDZYNIDJ.js} +2 -2
- package/dist/{chunk-H5AFCNGA.js → chunk-UJX4I26O.js} +2 -2
- package/dist/{chunk-E6TDQRF6.js → chunk-UYUCCQ46.js} +2 -2
- package/dist/{chunk-BLUYQFRH.js → chunk-VELCIWJZ.js} +15 -11
- package/dist/chunk-VELCIWJZ.js.map +1 -0
- package/dist/{chunk-OQDPBRQ6.js → chunk-VYXDUPYE.js} +2 -2
- package/dist/{chunk-ZG74PWRW.js → chunk-VZAKYDMJ.js} +2 -2
- package/dist/chunk-W6IJMWTZ.js +72 -0
- package/dist/chunk-W6IJMWTZ.js.map +1 -0
- package/dist/{chunk-NB5BCFUY.js → chunk-WHHEPAO3.js} +4 -4
- package/dist/{chunk-H3TKENU4.js → chunk-WIKO4SCR.js} +5 -5
- package/dist/{chunk-TX2UTLXC.js → chunk-WPDKBUWX.js} +2 -2
- package/dist/{chunk-YFLLGRXO.js → chunk-X2QPKLPL.js} +2 -2
- package/dist/{chunk-PFFZWDPE.js → chunk-XCOV45MO.js} +3 -3
- package/dist/{chunk-5BCNEBEN.js → chunk-XPJNT6PI.js} +4 -4
- package/dist/chunk-XW2T4QAW.js +1 -0
- package/dist/{chunk-J7HFPA6O.js → chunk-Y63ZFP4X.js} +2 -2
- package/dist/{chunk-D223ZDQV.js → chunk-YEDVOYL2.js} +2 -2
- package/dist/{chunk-TLPZ6MKZ.js → chunk-YEN4TREG.js} +541 -5
- package/dist/chunk-YEN4TREG.js.map +1 -0
- package/dist/{chunk-22FVR2KE.js → chunk-YJ6VCDMZ.js} +6 -2
- package/dist/chunk-YJ6VCDMZ.js.map +1 -0
- package/dist/{chunk-RC5DXXWC.js → chunk-YM7YN37H.js} +2 -2
- package/dist/{chunk-BPJNF7J2.js → chunk-YNN26CIZ.js} +2 -2
- package/dist/{chunk-VLXBE57O.js → chunk-YVGXH72Y.js} +2 -2
- package/dist/{chunk-YQAXP5AC.js → chunk-YXLUTALO.js} +5 -5
- package/dist/{chunk-DGGB65KC.js → chunk-Z7ACR6MJ.js} +3 -3
- package/dist/{chunk-X35W4S3L.js → chunk-ZBEGS7OB.js} +4 -4
- package/dist/{chunk-O75CRYGF.js → chunk-ZEFVK7XC.js} +1 -1
- package/dist/chunk-ZEFVK7XC.js.map +1 -0
- package/dist/{chunk-XUE46UYW.js → chunk-ZLN7AROH.js} +6 -6
- package/dist/{chunk-E6JA6XWY.js → chunk-ZTG4P7NZ.js} +1013 -1317
- package/dist/chunk-ZTG4P7NZ.js.map +1 -0
- package/dist/{chunk-HK32G473.js → chunk-ZWEZXVYH.js} +2 -2
- package/dist/{cli-D57e2Mqt.d.ts → cli-Bk7Ctql4.d.ts} +5 -5
- package/dist/cli-fallback.d.ts +11 -4
- package/dist/cli-fallback.js +5 -1
- package/dist/cli.d.ts +16 -13
- package/dist/cli.js +107 -103
- package/dist/coding/export-okf-codegraph.d.ts +3 -1
- package/dist/coding/export-okf-codegraph.js +32 -30
- package/dist/coding/export-okf-codegraph.js.map +1 -1
- package/dist/coding/pre-action-gate.d.ts +3 -1
- package/dist/compat/checks.js +2 -2
- package/dist/compat/codex-cli-fallback.d.ts +1 -1
- package/dist/compat/codex-cli-fallback.js +5 -1
- package/dist/compat/codex-cli-fallback.js.map +1 -1
- package/dist/compounding/engine.d.ts +4 -2
- package/dist/compounding/engine.js +27 -26
- package/dist/compounding/preference-consolidator.d.ts +3 -1
- package/dist/compression-optimizer.d.ts +3 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +12 -10
- package/dist/connectors/codex-materialize-runner.d.ts +3 -1
- package/dist/connectors/codex-materialize-runner.js +26 -25
- package/dist/connectors/codex-materialize.d.ts +3 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +28 -27
- package/dist/consolidation-provenance-check.d.ts +4 -2
- package/dist/consolidation-undo.d.ts +4 -2
- package/dist/contradiction/index.d.ts +5 -3
- package/dist/contradiction/index.js +5 -5
- package/dist/{contradiction-scan-NOYMFG66.js → contradiction-scan-GVD4JJ7B.js} +3 -3
- package/dist/converge-config.d.ts +3 -1
- package/dist/convergence-refresh.d.ts +4 -2
- package/dist/convergence-refresh.js +28 -27
- package/dist/conversation-index/backend.d.ts +3 -1
- package/dist/conversation-index/backend.js +3 -3
- package/dist/conversation-index/chunker.d.ts +3 -1
- package/dist/conversation-index/faiss-adapter.d.ts +3 -1
- package/dist/conversation-index/faiss-adapter.js +2 -2
- package/dist/conversation-index/indexer.d.ts +3 -1
- package/dist/conversation-index/search.d.ts +3 -1
- package/dist/corpus-watermark.d.ts +3 -1
- package/dist/corpus-watermark.js +29 -28
- package/dist/cross-lingual-recall.d.ts +3 -1
- package/dist/day-summary.d.ts +3 -1
- package/dist/deep-recall-http-glue.d.ts +14 -11
- package/dist/deep-recall-http-glue.js +12 -2
- package/dist/deep-recall-mcp-tools.d.ts +14 -11
- package/dist/deep-recall-policy-llm.d.ts +3 -1
- package/dist/deep-recall-policy-llm.js +4 -3
- package/dist/deep-recall-seeds.d.ts +3 -1
- package/dist/delinearize.d.ts +3 -1
- package/dist/dependency-propagation-config.d.ts +3 -1
- package/dist/{dependency-propagation-delivery-CmniEsUK.d.ts → dependency-propagation-delivery-DLiAtj25.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +3 -1
- package/dist/direct-answer.d.ts +3 -1
- package/dist/embedding-fallback.d.ts +3 -1
- package/dist/enrichment/index.d.ts +3 -1
- package/dist/entity-origin-fields.d.ts +3 -1
- package/dist/entity-retrieval.d.ts +4 -2
- package/dist/entity-retrieval.js +26 -25
- package/dist/entity-schema.d.ts +3 -1
- package/dist/episodic-context.d.ts +3 -1
- package/dist/eval-trajectory-contracts.d.ts +3 -1
- package/dist/eval-trajectory-store.d.ts +3 -1
- package/dist/eval-trajectory.d.ts +3 -1
- package/dist/explicit-capture.d.ts +12 -9
- package/dist/explicit-capture.js +6 -6
- package/dist/external-wiki-access.d.ts +14 -11
- package/dist/external-wiki-access.js +66 -61
- package/dist/external-wiki-collection-registration.d.ts +3 -1
- package/dist/external-wiki-collection.d.ts +3 -1
- package/dist/external-wiki-mcp-tools.d.ts +14 -11
- package/dist/extraction-error-classification.d.ts +3 -1
- package/dist/extraction-faithfulness.d.ts +3 -1
- package/dist/extraction-faithfulness.js +4 -3
- package/dist/extraction-judge-telemetry.d.ts +3 -1
- package/dist/extraction-judge-training.d.ts +3 -1
- package/dist/extraction-judge.d.ts +3 -1
- package/dist/extraction-judge.js +5 -4
- package/dist/extraction-liveness.d.ts +3 -1
- package/dist/extraction-normalization.d.ts +3 -1
- package/dist/extraction-prompt.d.ts +3 -1
- package/dist/extraction-source-grounding-rules.d.ts +3 -1
- package/dist/extraction-source-grounding.d.ts +3 -1
- package/dist/extraction.d.ts +3 -1
- package/dist/extraction.js +38 -36
- package/dist/fallback-llm.d.ts +3 -1
- package/dist/fallback-llm.js +3 -2
- package/dist/{first-start-migration-RC345GPL.js → first-start-migration-L3UFX5CU.js} +3 -3
- package/dist/generic-recall-paths-DbitKJI5.d.ts +23 -0
- package/dist/graph-append-error.d.ts +3 -1
- package/dist/graph-dashboard-diff.d.ts +3 -1
- package/dist/graph-dashboard-key.d.ts +3 -1
- package/dist/graph-dashboard-parser.d.ts +3 -1
- package/dist/graph-edge-reinforcement.d.ts +3 -1
- package/dist/graph-jsonl.d.ts +3 -1
- package/dist/graph-path-reconstruction.d.ts +3 -1
- package/dist/graph-path-scoring.d.ts +3 -1
- package/dist/graph-snapshot.d.ts +3 -1
- package/dist/graph.d.ts +3 -1
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/importance.d.ts +3 -1
- package/dist/importers/index.d.ts +3 -1
- package/dist/importers/test-utils.d.ts +3 -1
- package/dist/in-flight-reads.d.ts +3 -1
- package/dist/{index-BTAsSkPG.d.ts → index-BINUgPFo.d.ts} +2 -2
- package/dist/index.d.ts +303 -245
- package/dist/index.js +316 -214
- package/dist/intent.d.ts +3 -1
- package/dist/lcm/engine.d.ts +3 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +3 -1
- package/dist/lcm/index.js +7 -7
- package/dist/lcm/tools.d.ts +3 -1
- package/dist/lifecycle.d.ts +3 -1
- package/dist/live-connectors-runner.d.ts +3 -1
- package/dist/local-llm-config.d.ts +26 -0
- package/dist/local-llm-config.js +1 -0
- package/dist/local-llm.d.ts +5 -1
- package/dist/local-llm.js +3 -3
- package/dist/local-model-endpoint.d.ts +3 -1
- package/dist/location/index.d.ts +5 -3
- package/dist/location/index.js +29 -28
- package/dist/maintenance/memory-governance.d.ts +3 -1
- package/dist/maintenance/memory-governance.js +26 -25
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +26 -25
- package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-projection.js +27 -26
- package/dist/{maintenance-DCvQGTzL.d.ts → maintenance-ag1gYztC.d.ts} +378 -4
- package/dist/mcp-memory-inspector-app.d.ts +14 -11
- package/dist/memory-action-policy.d.ts +3 -1
- package/dist/memory-cache.d.ts +3 -1
- package/dist/memory-controller.d.ts +3 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
- package/dist/memory-projection-store.d.ts +3 -1
- package/dist/memory-provenance.d.ts +3 -1
- package/dist/memory-snapshot.d.ts +3 -1
- package/dist/memory-subject-cli.d.ts +14 -11
- package/dist/memory-subject.d.ts +14 -11
- package/dist/memory-worth-outcomes.d.ts +4 -2
- package/dist/migrate/from-engram.js +2 -2
- package/dist/models-json.d.ts +3 -1
- package/dist/namespaces/migrate.d.ts +5 -3
- package/dist/namespaces/migrate.js +27 -26
- package/dist/namespaces/principal.d.ts +3 -1
- package/dist/namespaces/search.d.ts +3 -1
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.d.ts +5 -3
- package/dist/namespaces/storage.js +26 -25
- package/dist/native-knowledge.d.ts +3 -1
- package/dist/network/tailscale.js +2 -2
- package/dist/offline-sync-impression-drain.d.ts +3 -1
- package/dist/offline-sync-impression-drain.js +6 -6
- package/dist/operator-doctor-corpus.d.ts +3 -1
- package/dist/operator-doctor-corpus.js +30 -29
- package/dist/operator-doctor-replica.d.ts +3 -1
- package/dist/operator-toolkit.d.ts +5 -3
- package/dist/operator-toolkit.js +44 -42
- package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
- package/dist/orchestration/maintenance.d.ts +6 -4
- package/dist/orchestration/maintenance.js +44 -39
- package/dist/{orchestrator-CvCsp1tz.d.ts → orchestrator-Cf3G-3Ed.d.ts} +17 -29
- package/dist/orchestrator.d.ts +12 -9
- package/dist/orchestrator.js +141 -135
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-JAdwKBS7.d.ts → pipeline-AwB03fw_.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +3 -1
- package/dist/proactive-contention.d.ts +3 -1
- package/dist/provenance.d.ts +3 -1
- package/dist/{public-http-h-yWu9rj.d.ts → public-http-BetSQn7q.d.ts} +1 -1
- package/dist/{qmd-Cvw9RWKr.d.ts → qmd-Bfaydrfm.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +4 -2
- package/dist/qmd-recall-cache.d.ts +3 -1
- package/dist/qmd.d.ts +4 -2
- package/dist/qmd.js +2 -2
- package/dist/recall-concurrency-config.d.ts +3 -1
- package/dist/recall-disclosure-escalation.d.ts +3 -1
- package/dist/recall-explain-renderer.d.ts +3 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +3 -1
- package/dist/recall-navigate-access.d.ts +3 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +3 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +3 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +3 -1
- package/dist/recall-planner-llm.js +3 -2
- package/dist/recall-planner-llm.js.map +1 -1
- package/dist/recall-state-view-admission.d.ts +57 -0
- package/dist/recall-state-view-admission.js +39 -0
- package/dist/recall-state-view-admission.js.map +1 -0
- package/dist/recall-state-view-inject.js +2 -2
- package/dist/recall-state-view-render.js +2 -2
- package/dist/recall-state-view-widen.d.ts +18 -1
- package/dist/recall-state-view-widen.js +2 -2
- package/dist/recall-state-view-wire.d.ts +1 -1
- package/dist/recall-state-view-wire.js +3 -3
- package/dist/recall-state-view.d.ts +1 -0
- package/dist/recall-state-view.js +1 -1
- package/dist/recall-state.d.ts +3 -1
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-timings.d.ts +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +10 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +12 -2
- package/dist/reconcile/cursor.js +6 -4
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +38 -2
- package/dist/reconcile/manifest.js +15 -5
- package/dist/reconcile/plan.d.ts +3 -1
- package/dist/replay/normalizers/chatgpt.d.ts +3 -1
- package/dist/replay/normalizers/claude.d.ts +3 -1
- package/dist/replay/normalizers/openclaw.d.ts +3 -1
- package/dist/replay/normalizers/shared.d.ts +3 -1
- package/dist/replay/runner.d.ts +3 -1
- package/dist/replay/types.d.ts +3 -1
- package/dist/replica-divergence.d.ts +3 -1
- package/dist/replica-peers-config.d.ts +3 -1
- package/dist/{resolution-VKATP2HT.js → resolution-OHJZG45O.js} +6 -6
- package/dist/resolution-OHJZG45O.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +3 -1
- package/dist/resume-bundles.js +13 -11
- package/dist/retrieval-agents.d.ts +4 -2
- package/dist/retrieval-tiers.d.ts +3 -1
- package/dist/routing/engine.d.ts +3 -1
- package/dist/routing/store.d.ts +3 -1
- package/dist/runtime/child-process.d.ts +1 -1
- package/dist/runtime/child-process.js +1 -1
- package/dist/salvage-envelope.d.ts +3 -1
- package/dist/salvage-envelope.js +2 -2
- package/dist/{scope-profiles-BShpTPeV.d.ts → scope-profiles-nxTKvjE-.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +3 -1
- package/dist/search/factory.d.ts +3 -1
- package/dist/search/factory.js +7 -7
- package/dist/search/index.d.ts +3 -1
- package/dist/search/index.js +11 -11
- package/dist/search/lancedb-backend.d.ts +3 -1
- package/dist/search/meilisearch-backend.d.ts +3 -1
- package/dist/search/noop-backend.d.ts +3 -1
- package/dist/search/orama-backend.d.ts +3 -1
- package/dist/search/port.d.ts +3 -1
- package/dist/search/remote-backend.d.ts +3 -1
- package/dist/{semantic-consolidation-CusOpe9F.d.ts → semantic-consolidation-C83DVakV.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +27 -26
- package/dist/semantic-rule-promotion.js +26 -25
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +26 -25
- package/dist/{service-BbuVh1eS.d.ts → service-q-xtOoAr.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +3 -1
- package/dist/session-observer-state.d.ts +3 -1
- package/dist/shared-context/manager.d.ts +3 -1
- package/dist/signal.d.ts +3 -1
- package/dist/source-agent-qualifier.d.ts +3 -1
- package/dist/source-agent-qualifier.js +35 -33
- package/dist/standup/build.js +26 -25
- package/dist/{storage-BBLLuVTF.d.ts → storage-Ca0MbTfm.d.ts} +67 -6
- package/dist/storage.d.ts +5 -3
- package/dist/storage.js +25 -24
- package/dist/subject-config.d.ts +3 -1
- package/dist/subject-config.js +2 -2
- package/dist/summarizer.d.ts +3 -1
- package/dist/summarizer.js +6 -6
- package/dist/summary-snapshot.d.ts +3 -1
- package/dist/support-passport/index.d.ts +50 -15
- package/dist/support-passport/index.js +73 -64
- package/dist/temporal-supersession.d.ts +4 -2
- package/dist/temporal-timeline-recall.d.ts +3 -1
- package/dist/temporal-validity.d.ts +3 -1
- package/dist/threading.d.ts +3 -1
- package/dist/tier-migration.d.ts +4 -2
- package/dist/tier-routing.d.ts +3 -1
- package/dist/tier-routing.js +2 -2
- package/dist/{tier-stats-KA6OZX2C.js → tier-stats-VK5PCO2L.js} +3 -3
- package/dist/topics.d.ts +3 -1
- package/dist/transcript.d.ts +3 -1
- package/dist/transfer/capsule-import.js +1 -1
- package/dist/transfer/export-okf.d.ts +3 -1
- package/dist/transfer/export-okf.js +27 -26
- package/dist/transfer/types.d.ts +24 -24
- package/dist/trust-score-stage.d.ts +3 -1
- package/dist/trust-score.d.ts +3 -1
- package/dist/{types-igV4-sbB.d.ts → types-yDgWDkrJ.d.ts} +60 -34
- package/dist/types.d.ts +3 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +3 -1
- package/dist/verified-recall.js +26 -25
- package/dist/who-knows-cli.d.ts +14 -11
- package/dist/who-knows-cli.js +27 -26
- package/dist/who-knows.d.ts +14 -11
- package/dist/who-knows.js +26 -25
- package/dist/write-envelope.d.ts +5 -2
- package/dist/write-envelope.js +3 -1
- package/package.json +2 -2
- package/src/access-category-alias.test.ts +216 -0
- package/src/access-mcp.test.ts +73 -0
- package/src/access-mcp.ts +6 -6
- package/src/access-observe-write-surface.ts +19 -4
- package/src/access-offline-manifest.ts +297 -16
- package/src/access-recall-surface.ts +5 -5
- package/src/access-schema.ts +76 -7
- package/src/access-service.ts +11 -2
- package/src/activity/config.test.ts +124 -1
- package/src/activity/config.ts +150 -18
- package/src/activity/index.ts +3 -0
- package/src/activity/journal-extract-storage.test.ts +129 -0
- package/src/activity/journal-extract.test.ts +314 -0
- package/src/activity/journal-extract.ts +247 -0
- package/src/activity/journal-heading.test.ts +24 -1
- package/src/activity/journal-heading.ts +36 -0
- package/src/activity/journal-read.test.ts +242 -0
- package/src/activity/journal-read.ts +183 -0
- package/src/activity/journal-source.test.ts +15 -15
- package/src/activity/journal-source.ts +21 -14
- package/src/activity/journal-state.lock-worker.ts +30 -0
- package/src/activity/journal-state.test.ts +144 -0
- package/src/activity/journal-state.ts +107 -0
- package/src/activity/journal-strip.test.ts +106 -52
- package/src/activity/journal-strip.ts +35 -10
- package/src/activity/journal-vault-integration.test.ts +230 -0
- package/src/activity/journal-vault-provenance.test.ts +9 -7
- package/src/activity/journal-vault-provenance.ts +4 -10
- package/src/activity/journal-vault-read.test.ts +3 -2
- package/src/activity/journal-vault-read.ts +9 -139
- package/src/activity/journal.test.ts +74 -23
- package/src/activity/runner.test.ts +116 -1
- package/src/activity/runner.ts +25 -0
- package/src/activity/scheduler.ts +4 -0
- package/src/activity/store.test.ts +18 -0
- package/src/activity/store.ts +14 -0
- package/src/activity/sync-registration.ts +4 -0
- package/src/activity/timeline/analysis-metadata.ts +2 -0
- package/src/activity/timeline/analysis-provider.ts +140 -0
- package/src/activity/timeline/analysis-run.test.ts +419 -0
- package/src/activity/timeline/analysis-run.ts +106 -0
- package/src/activity/timeline/analysis.ts +66 -37
- package/src/activity/timeline/corrections.ts +9 -0
- package/src/activity/timeline/index.ts +3 -0
- package/src/activity/timeline/query.test.ts +71 -0
- package/src/activity/timeline/query.ts +57 -8
- package/src/activity/timeline/regenerate.test.ts +505 -0
- package/src/activity/timeline/regenerate.ts +373 -0
- package/src/activity/types.ts +40 -5
- package/src/adapters/grok-opencode.test.ts +146 -0
- package/src/adapters/grok.ts +53 -0
- package/src/adapters/index.ts +2 -0
- package/src/adapters/opencode.ts +52 -0
- package/src/adapters/registry.ts +4 -0
- package/src/cli-fallback.ts +13 -4
- package/src/config.test.ts +27 -1
- package/src/config.ts +17 -1
- package/src/dedup/merge.test.ts +732 -25
- package/src/fallback-llm.test.ts +53 -0
- package/src/fallback-llm.ts +12 -0
- package/src/index.ts +2 -0
- package/src/local-llm-config.ts +25 -0
- package/src/local-llm.ts +3 -1
- package/src/orchestration/dependency-propagation-recovery-replay.ts +1 -1
- package/src/orchestration/extraction-persist-deps.ts +9 -0
- package/src/orchestration/extraction-persist-promotion.test.ts +265 -6
- package/src/orchestration/extraction-persist-promotion.ts +42 -3
- package/src/orchestration/extraction-persist.ts +3 -3
- package/src/orchestration/harmonic-construction-persist.test.ts +115 -4
- package/src/orchestration/harmonic-construction-persist.ts +34 -6
- package/src/orchestration/maintenance.ts +1 -0
- package/src/orchestration/orchestrator-helpers.ts +6 -0
- package/src/orchestration/recall-entry.ts +16 -0
- package/src/orchestration/recall-internal-deps.ts +14 -0
- package/src/orchestration/recall-internal.ts +41 -58
- package/src/orchestration/recall-result-formatter.ts +11 -1
- package/src/orchestration/recall-search-pipeline.ts +121 -11
- package/src/orchestration/recall-state-view-pipeline.test.ts +211 -0
- package/src/orchestration/semantic-merge-commit-effects.ts +76 -17
- package/src/orchestration/semantic-merge-persist.ts +121 -16
- package/src/orchestration/semantic-merge-promotion-payload.ts +133 -54
- package/src/orchestrator.ts +7 -35
- package/src/providers/codex-subscription.test.ts +666 -0
- package/src/providers/codex-subscription.ts +743 -0
- package/src/recall-disclosure.test.ts +20 -0
- package/src/recall-state-view-admission.ts +114 -0
- package/src/recall-state-view-asof.test.ts +176 -0
- package/src/recall-state-view-call.test.ts +175 -0
- package/src/recall-state-view-config.test.ts +16 -0
- package/src/recall-state-view-widen.test.ts +70 -0
- package/src/recall-state-view-widen.ts +28 -7
- package/src/recall-state-view-wire.ts +3 -1
- package/src/recall-state-view-zero-diff.test.ts +20 -11
- package/src/recall-state-view.test.ts +142 -0
- package/src/recall-state-view.ts +72 -24
- package/src/recall-xray-renderer.test.ts +27 -0
- package/src/recall-xray-renderer.ts +4 -0
- package/src/recall-xray.ts +13 -0
- package/src/reconcile/cursor.ts +23 -33
- package/src/reconcile/manifest.ts +96 -11
- package/src/reconcile-identity-cache.test.ts +378 -0
- package/src/runtime/child-process.ts +1 -1
- package/src/storage/cas-revision-host.ts +75 -0
- package/src/storage/cas-revision-store.test.ts +459 -0
- package/src/storage/cas-revision-store.ts +661 -0
- package/src/storage/deletion-revision-store.ts +80 -6
- package/src/storage/tombstone-blocked-capture-index.ts +15 -0
- package/src/storage/tombstone-blocked-capture-mutation.ts +67 -7
- package/src/storage/tombstone-blocked-capture-sync.ts +55 -20
- package/src/storage-contract/failure-semantics.test.ts +1 -1
- package/src/storage-frontmatter-cas.test.ts +698 -1
- package/src/storage-replay.test.ts +166 -3
- package/src/storage.ts +41 -41
- package/src/support-passport/card-projection.ts +82 -33
- package/src/temporal-supersession.test.ts +10 -10
- package/src/types.ts +10 -29
- package/src/write-envelope.ts +1 -1
- package/dist/chunk-22FVR2KE.js.map +0 -1
- package/dist/chunk-2C3S7J2S.js.map +0 -1
- package/dist/chunk-2JVJ7UHC.js.map +0 -1
- package/dist/chunk-2QSZNTDO.js +0 -56
- package/dist/chunk-2QSZNTDO.js.map +0 -1
- package/dist/chunk-3QQTXYZ6.js.map +0 -1
- package/dist/chunk-5VCDKQWQ.js +0 -560
- package/dist/chunk-5VCDKQWQ.js.map +0 -1
- package/dist/chunk-A7XEPMQ6.js.map +0 -1
- package/dist/chunk-BLUYQFRH.js.map +0 -1
- package/dist/chunk-E6JA6XWY.js.map +0 -1
- package/dist/chunk-EEOUMG3J.js.map +0 -1
- package/dist/chunk-FDLDOEO6.js.map +0 -1
- package/dist/chunk-FYDW33ZB.js +0 -13
- package/dist/chunk-H272ZPQ3.js.map +0 -1
- package/dist/chunk-HV7OY4DM.js.map +0 -1
- package/dist/chunk-HVAEXYPL.js.map +0 -1
- package/dist/chunk-JEIXTYVG.js.map +0 -1
- package/dist/chunk-LRICZIGN.js +0 -52
- package/dist/chunk-LRICZIGN.js.map +0 -1
- package/dist/chunk-MFDTVQJX.js.map +0 -1
- package/dist/chunk-N7RWREIQ.js.map +0 -1
- package/dist/chunk-O75CRYGF.js.map +0 -1
- package/dist/chunk-Q726HSJO.js.map +0 -1
- package/dist/chunk-QOIOACIE.js.map +0 -1
- package/dist/chunk-SEDEKFYQ.js +0 -1
- package/dist/chunk-SO7SV523.js.map +0 -1
- package/dist/chunk-TLPZ6MKZ.js.map +0 -1
- package/dist/chunk-UGPUYIET.js.map +0 -1
- package/src/activity/journal-mode.test.ts +0 -32
- package/src/activity/journal-mode.ts +0 -20
- /package/dist/{capsule-merge-IPG4IOFP.js.map → capsule-merge-ZCXUPLNJ.js.map} +0 -0
- /package/dist/{chunk-CDKHKZL5.js.map → chunk-2524MOWK.js.map} +0 -0
- /package/dist/{chunk-RKBLRTNT.js.map → chunk-2YLMUME2.js.map} +0 -0
- /package/dist/{chunk-DBQWVT2H.js.map → chunk-3CBI2ZSA.js.map} +0 -0
- /package/dist/{chunk-MWFGUESQ.js.map → chunk-3FJKJ5UZ.js.map} +0 -0
- /package/dist/{chunk-NZXEK3UF.js.map → chunk-3Q3N35W7.js.map} +0 -0
- /package/dist/{chunk-YYGZJPOK.js.map → chunk-42DJ235G.js.map} +0 -0
- /package/dist/{chunk-JTH2SE6B.js.map → chunk-6J6K3STG.js.map} +0 -0
- /package/dist/{chunk-H4VH5VIB.js.map → chunk-776GVKL7.js.map} +0 -0
- /package/dist/{chunk-BUTCAMJM.js.map → chunk-A2YQL2FF.js.map} +0 -0
- /package/dist/{chunk-X2NFFBTO.js.map → chunk-A7GQBJP5.js.map} +0 -0
- /package/dist/{chunk-CGC5UQCF.js.map → chunk-AKE4GGQ3.js.map} +0 -0
- /package/dist/{chunk-B325AGLK.js.map → chunk-AZSKROVQ.js.map} +0 -0
- /package/dist/{chunk-I5DZ3WGR.js.map → chunk-BJETIR53.js.map} +0 -0
- /package/dist/{chunk-JT3EB7ZL.js.map → chunk-BNGHPYZU.js.map} +0 -0
- /package/dist/{chunk-3JVLGJCY.js.map → chunk-C6KRO3SU.js.map} +0 -0
- /package/dist/{chunk-5NANRSCD.js.map → chunk-CNV2A557.js.map} +0 -0
- /package/dist/{chunk-PBGVVDLY.js.map → chunk-DK4X5B6I.js.map} +0 -0
- /package/dist/{chunk-N2ZNPHA3.js.map → chunk-ECKG5WSI.js.map} +0 -0
- /package/dist/{chunk-PYLL63BF.js.map → chunk-EEBQFG5E.js.map} +0 -0
- /package/dist/{chunk-ET356KSB.js.map → chunk-F4TWWUMP.js.map} +0 -0
- /package/dist/{chunk-CLLPJ6QT.js.map → chunk-FQXJAC3T.js.map} +0 -0
- /package/dist/{chunk-JGHXXQ2G.js.map → chunk-FVJ4D6L7.js.map} +0 -0
- /package/dist/{chunk-DD5JFCWM.js.map → chunk-GCBIXUPT.js.map} +0 -0
- /package/dist/{chunk-MN3LK3KN.js.map → chunk-GLZH5VEN.js.map} +0 -0
- /package/dist/{chunk-S7T2TY65.js.map → chunk-HC4GFLMQ.js.map} +0 -0
- /package/dist/{chunk-EQHDH4C2.js.map → chunk-HUT2JR6I.js.map} +0 -0
- /package/dist/{chunk-UUQG7HAD.js.map → chunk-HXSAWV3A.js.map} +0 -0
- /package/dist/{chunk-XXIHX75O.js.map → chunk-J7PB5UQ4.js.map} +0 -0
- /package/dist/{chunk-LTIZHLV7.js.map → chunk-JR6H5CYS.js.map} +0 -0
- /package/dist/{chunk-FCSZ4K2X.js.map → chunk-JR6PP7UM.js.map} +0 -0
- /package/dist/{chunk-TCUKRAMK.js.map → chunk-JRWW7GM6.js.map} +0 -0
- /package/dist/{chunk-PL7FYKHT.js.map → chunk-L2WQVSKP.js.map} +0 -0
- /package/dist/{chunk-JSN44KIB.js.map → chunk-LEMD7WZJ.js.map} +0 -0
- /package/dist/{chunk-VZWXFXLX.js.map → chunk-LMCD5W5B.js.map} +0 -0
- /package/dist/{chunk-7BMXZCOT.js.map → chunk-LNDLXMH6.js.map} +0 -0
- /package/dist/{chunk-EONF76DT.js.map → chunk-LYDJRF45.js.map} +0 -0
- /package/dist/{chunk-MKD3OMPS.js.map → chunk-M3MYMWXG.js.map} +0 -0
- /package/dist/{chunk-VGXM5B4H.js.map → chunk-MNIPH6LD.js.map} +0 -0
- /package/dist/{chunk-6N3TQFZU.js.map → chunk-NN4JEFON.js.map} +0 -0
- /package/dist/{chunk-MOZXTRC2.js.map → chunk-OQ7SSRXP.js.map} +0 -0
- /package/dist/{chunk-XU6OEECT.js.map → chunk-OQQXGYMX.js.map} +0 -0
- /package/dist/{chunk-4MHYKEOM.js.map → chunk-OS2AT2JU.js.map} +0 -0
- /package/dist/{chunk-N57A4KPV.js.map → chunk-P3ONDDIJ.js.map} +0 -0
- /package/dist/{chunk-R3HKWWUB.js.map → chunk-PHP3MUGF.js.map} +0 -0
- /package/dist/{chunk-P3SB5BNT.js.map → chunk-QATYVTP7.js.map} +0 -0
- /package/dist/{chunk-LSYDG6MJ.js.map → chunk-QBLDCI6E.js.map} +0 -0
- /package/dist/{chunk-KCB7F4J7.js.map → chunk-QURNMKME.js.map} +0 -0
- /package/dist/{chunk-XOVKXJEP.js.map → chunk-R3TLVTWW.js.map} +0 -0
- /package/dist/{chunk-XXE5P6HJ.js.map → chunk-RRZKTSFG.js.map} +0 -0
- /package/dist/{chunk-44T3Y7SZ.js.map → chunk-RUXPVSML.js.map} +0 -0
- /package/dist/{chunk-DCJ3YFIC.js.map → chunk-S2ULTQZR.js.map} +0 -0
- /package/dist/{chunk-EEC4PCG5.js.map → chunk-SZDLX763.js.map} +0 -0
- /package/dist/{chunk-E2ZHGBAK.js.map → chunk-T2JSUEH6.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-TFA6HPOA.js.map} +0 -0
- /package/dist/{chunk-BA6WOZOT.js.map → chunk-TK4FHQRN.js.map} +0 -0
- /package/dist/{chunk-W27OW7AB.js.map → chunk-TKFSXDOB.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-CETXNLEX.js.map → chunk-UDZYNIDJ.js.map} +0 -0
- /package/dist/{chunk-H5AFCNGA.js.map → chunk-UJX4I26O.js.map} +0 -0
- /package/dist/{chunk-E6TDQRF6.js.map → chunk-UYUCCQ46.js.map} +0 -0
- /package/dist/{chunk-OQDPBRQ6.js.map → chunk-VYXDUPYE.js.map} +0 -0
- /package/dist/{chunk-ZG74PWRW.js.map → chunk-VZAKYDMJ.js.map} +0 -0
- /package/dist/{chunk-NB5BCFUY.js.map → chunk-WHHEPAO3.js.map} +0 -0
- /package/dist/{chunk-H3TKENU4.js.map → chunk-WIKO4SCR.js.map} +0 -0
- /package/dist/{chunk-TX2UTLXC.js.map → chunk-WPDKBUWX.js.map} +0 -0
- /package/dist/{chunk-YFLLGRXO.js.map → chunk-X2QPKLPL.js.map} +0 -0
- /package/dist/{chunk-PFFZWDPE.js.map → chunk-XCOV45MO.js.map} +0 -0
- /package/dist/{chunk-5BCNEBEN.js.map → chunk-XPJNT6PI.js.map} +0 -0
- /package/dist/{chunk-SEDEKFYQ.js.map → chunk-XW2T4QAW.js.map} +0 -0
- /package/dist/{chunk-J7HFPA6O.js.map → chunk-Y63ZFP4X.js.map} +0 -0
- /package/dist/{chunk-D223ZDQV.js.map → chunk-YEDVOYL2.js.map} +0 -0
- /package/dist/{chunk-RC5DXXWC.js.map → chunk-YM7YN37H.js.map} +0 -0
- /package/dist/{chunk-BPJNF7J2.js.map → chunk-YNN26CIZ.js.map} +0 -0
- /package/dist/{chunk-VLXBE57O.js.map → chunk-YVGXH72Y.js.map} +0 -0
- /package/dist/{chunk-YQAXP5AC.js.map → chunk-YXLUTALO.js.map} +0 -0
- /package/dist/{chunk-DGGB65KC.js.map → chunk-Z7ACR6MJ.js.map} +0 -0
- /package/dist/{chunk-X35W4S3L.js.map → chunk-ZBEGS7OB.js.map} +0 -0
- /package/dist/{chunk-XUE46UYW.js.map → chunk-ZLN7AROH.js.map} +0 -0
- /package/dist/{chunk-HK32G473.js.map → chunk-ZWEZXVYH.js.map} +0 -0
- /package/dist/{contradiction-scan-NOYMFG66.js.map → contradiction-scan-GVD4JJ7B.js.map} +0 -0
- /package/dist/{first-start-migration-RC345GPL.js.map → first-start-migration-L3UFX5CU.js.map} +0 -0
- /package/dist/{resolution-VKATP2HT.js.map → local-llm-config.js.map} +0 -0
- /package/dist/{tier-stats-KA6OZX2C.js.map → tier-stats-VK5PCO2L.js.map} +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { mkdir, mkdtemp, readdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import test from "node:test";
|
|
6
7
|
|
|
7
8
|
import { StorageManager } from "./storage.js";
|
|
9
|
+
import type { CasRevisionStore, CasRevisionTransaction } from "./storage/cas-revision-store.js";
|
|
8
10
|
|
|
9
11
|
async function withStorage(run: (storage: StorageManager) => Promise<void>): Promise<void> {
|
|
10
12
|
StorageManager.clearAllStaticCaches();
|
|
@@ -139,3 +141,698 @@ test("writeMemoryFrontmatterIfUnchanged preserves access-only updates", async ()
|
|
|
139
141
|
assert.equal(current.frontmatter.lastAccessed, lastAccessed);
|
|
140
142
|
});
|
|
141
143
|
});
|
|
144
|
+
test("revision minting happens inside the capture lock during frontmatter mutation", async () => {
|
|
145
|
+
await withStorage(async (storage) => {
|
|
146
|
+
const created = await storage.writeMemory("fact", "Lock atomicity test content.", { source: "test" });
|
|
147
|
+
const expected = await storage.getMemoryById(created.id);
|
|
148
|
+
assert.ok(expected);
|
|
149
|
+
|
|
150
|
+
let reservedInsideLock = false;
|
|
151
|
+
const seams = storage as unknown as {
|
|
152
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
153
|
+
};
|
|
154
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
155
|
+
seams.casRevisions.beginRevisionTransaction = async (pathname: string) => {
|
|
156
|
+
const lockIndex = (storage as any).getTombstoneBlockedCaptureIndex();
|
|
157
|
+
reservedInsideLock = lockIndex.isLocked ? lockIndex.isLocked(pathname) : true;
|
|
158
|
+
return await origBegin(pathname);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
assert.equal(await storage.writeMemoryFrontmatter(expected, { status: "archived" }), true);
|
|
162
|
+
assert.equal(reservedInsideLock, true, "the PENDING reservation was minted while holding the capture lock");
|
|
163
|
+
assert.equal(
|
|
164
|
+
(await storage.readCasRevisionStatus(expected.path)).status,
|
|
165
|
+
"present",
|
|
166
|
+
"the transaction published its COMMITTED receipt",
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("readCasRevision fails open with warning when sidecar read throws", async () => {
|
|
172
|
+
await withStorage(async (storage) => {
|
|
173
|
+
const created = await storage.writeMemory("fact", "Fail-open read test content.", { source: "test" });
|
|
174
|
+
const memory = await storage.getMemoryById(created.id);
|
|
175
|
+
assert.ok(memory);
|
|
176
|
+
|
|
177
|
+
// Force readRevision to throw an unexpected storage error
|
|
178
|
+
(storage as any).casRevisions.readRevision = async () => {
|
|
179
|
+
throw new Error("simulated disk read failure");
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const rev = await storage.readCasRevision(memory.path);
|
|
183
|
+
assert.equal(rev, undefined, "readCasRevision returns undefined fail-open on error");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("sharded per-target CAS receipt storage is O(1) and non-corpus-proportional", async () => {
|
|
188
|
+
await withStorage(async (storage) => {
|
|
189
|
+
const memoryDir = (storage as any).baseDir;
|
|
190
|
+
// Create 50 memories in the corpus
|
|
191
|
+
const memories = [];
|
|
192
|
+
for (let i = 0; i < 50; i++) {
|
|
193
|
+
memories.push(await storage.writeMemory("fact", `Corpus memory number ${i}`, { source: "test" }));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const targetMemory = await storage.getMemoryById(memories[25]!.id);
|
|
197
|
+
assert.ok(targetMemory);
|
|
198
|
+
|
|
199
|
+
// Update frontmatter of target memory
|
|
200
|
+
assert.equal(await storage.writeMemoryFrontmatter(targetMemory, { tags: ["updated"] }), true);
|
|
201
|
+
|
|
202
|
+
const shardedDir = path.join(memoryDir, ".offline-sync", "cas-revisions");
|
|
203
|
+
const { readdir } = await import("node:fs/promises");
|
|
204
|
+
const files = await readdir(shardedDir);
|
|
205
|
+
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
206
|
+
|
|
207
|
+
// Exactly 1 per-target JSON shard file should exist in the sharded directory
|
|
208
|
+
assert.equal(jsonFiles.length, 1, "only 1 per-target shard file was created for the single mutated target");
|
|
209
|
+
|
|
210
|
+
// Global file cas-revisions.v1.json should NOT exist
|
|
211
|
+
const legacyFileExists = await import("node:fs/promises")
|
|
212
|
+
.then((fs) => fs.stat(path.join(memoryDir, ".offline-sync", "cas-revisions.v1.json")))
|
|
213
|
+
.then(() => true, () => false);
|
|
214
|
+
assert.equal(legacyFileExists, false, "global cas-revisions.v1.json was not created");
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("backward-compatible legacy cas-revisions.v1.json is read when shard is absent", async () => {
|
|
219
|
+
await withStorage(async (storage) => {
|
|
220
|
+
const memoryDir = (storage as any).baseDir;
|
|
221
|
+
const created = await storage.writeMemory("fact", "Legacy map fallback content.", { source: "test" });
|
|
222
|
+
const memory = await storage.getMemoryById(created.id);
|
|
223
|
+
assert.ok(memory);
|
|
224
|
+
|
|
225
|
+
const relPath = path.relative(memoryDir, memory.path).split(path.sep).join("/");
|
|
226
|
+
const legacyToken = "2026-08-20T00:00:00.000Z";
|
|
227
|
+
|
|
228
|
+
// Write a legacy global cas-revisions.v1.json
|
|
229
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
230
|
+
const legacyPath = path.join(memoryDir, ".offline-sync", "cas-revisions.v1.json");
|
|
231
|
+
await mkdir(path.dirname(legacyPath), { recursive: true });
|
|
232
|
+
await writeFile(
|
|
233
|
+
legacyPath,
|
|
234
|
+
JSON.stringify({ version: 1, revisions: [{ path: relPath, revision: legacyToken }] }),
|
|
235
|
+
"utf8",
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Read standing revision before shard exists
|
|
239
|
+
const standing = await storage.readCasRevision(memory.path);
|
|
240
|
+
assert.equal(standing, legacyToken, "readCasRevision fell back to reading legacy global map");
|
|
241
|
+
|
|
242
|
+
// Mutate memory: should mint a new revision greater than legacyToken and write to per-target shard
|
|
243
|
+
assert.equal(await storage.writeMemoryFrontmatter(memory, { status: "archived" }), true);
|
|
244
|
+
const nextToken = await storage.readCasRevision(memory.path);
|
|
245
|
+
assert.ok(nextToken && nextToken > legacyToken, "next revision is strictly greater than legacy token");
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
function casShardPath(memoryDir: string, memoryPath: string): string {
|
|
250
|
+
const relative = path.relative(memoryDir, memoryPath).split(path.sep).join("/");
|
|
251
|
+
const hash = createHash("sha256").update(relative).digest("hex");
|
|
252
|
+
return path.join(memoryDir, ".offline-sync", "cas-revisions", `${hash}.json`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
test("readCasRevisionStatus distinguishes present, absent, and unavailable receipts (#2813 P1 A)", async () => {
|
|
256
|
+
await withStorage(async (storage) => {
|
|
257
|
+
const created = await storage.writeMemory("fact", "Status truth test content.", { source: "test" });
|
|
258
|
+
const memory = await storage.getMemoryById(created.id);
|
|
259
|
+
assert.ok(memory);
|
|
260
|
+
|
|
261
|
+
assert.deepEqual(
|
|
262
|
+
await storage.readCasRevisionStatus(memory.path),
|
|
263
|
+
{ status: "absent" },
|
|
264
|
+
"a fresh target that never minted is genuinely absent, not unavailable",
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
assert.equal(await storage.writeMemoryFrontmatter(memory, { status: "archived" }), true);
|
|
268
|
+
const standing = await storage.readCasRevision(memory.path);
|
|
269
|
+
assert.ok(standing);
|
|
270
|
+
assert.deepEqual(await storage.readCasRevisionStatus(memory.path), {
|
|
271
|
+
status: "present",
|
|
272
|
+
revision: standing,
|
|
273
|
+
committedDigest: createHash("sha256").update(await readFile(memory.path)).digest("hex"),
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// A torn shard write: the receipt EXISTS but cannot be read. That is
|
|
277
|
+
// unavailability — never absence — while the fail-open read keeps
|
|
278
|
+
// collapsing the error to undefined.
|
|
279
|
+
// Test seam: baseDir is the constructor's memoryDir (private on StorageManager).
|
|
280
|
+
const { baseDir } = storage as unknown as { baseDir: string };
|
|
281
|
+
await writeFile(casShardPath(baseDir, memory.path), "{corrupt", "utf8");
|
|
282
|
+
const unreadable = await storage.readCasRevisionStatus(memory.path);
|
|
283
|
+
assert.equal(unreadable.status, "unavailable");
|
|
284
|
+
assert.equal(
|
|
285
|
+
await storage.readCasRevision(memory.path),
|
|
286
|
+
undefined,
|
|
287
|
+
"the fail-open read still collapses the error to undefined",
|
|
288
|
+
);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test("a failed receipt mint leaves the durable memory file untouched on a content update (#2813 P1 B)", async () => {
|
|
293
|
+
await withStorage(async (storage) => {
|
|
294
|
+
const created = await storage.writeMemory("fact", "Mint failure must not mutate the record.", { source: "test" });
|
|
295
|
+
const before = await storage.getMemoryById(created.id);
|
|
296
|
+
assert.ok(before);
|
|
297
|
+
const bytesBefore = await readFile(before.path);
|
|
298
|
+
assert.equal((await storage.readCasRevisionStatus(before.path)).status, "absent");
|
|
299
|
+
|
|
300
|
+
const seams = storage as unknown as {
|
|
301
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
302
|
+
};
|
|
303
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
304
|
+
seams.casRevisions.beginRevisionTransaction = async () => {
|
|
305
|
+
throw new Error("simulated sidecar mint failure");
|
|
306
|
+
};
|
|
307
|
+
try {
|
|
308
|
+
await assert.rejects(storage.updateMemory(created.id, "This body must never land."));
|
|
309
|
+
} finally {
|
|
310
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
assert.deepEqual(
|
|
314
|
+
await readFile(before.path),
|
|
315
|
+
bytesBefore,
|
|
316
|
+
"the durable memory file is byte-identical after a failed mint",
|
|
317
|
+
);
|
|
318
|
+
const after = await storage.getMemoryById(created.id);
|
|
319
|
+
assert.ok(after);
|
|
320
|
+
assert.equal(after.content, before.content, "the indexed record still holds the original body");
|
|
321
|
+
assert.equal(after.frontmatter.updated, before.frontmatter.updated, "frontmatter business time is untouched");
|
|
322
|
+
assert.equal(
|
|
323
|
+
(await storage.readCasRevisionStatus(before.path)).status,
|
|
324
|
+
"absent",
|
|
325
|
+
"no receipt was recorded for a write that never landed",
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
test("a failed receipt mint leaves the durable memory file untouched on a semantic frontmatter write (#2813 P1 B)", async () => {
|
|
331
|
+
await withStorage(async (storage) => {
|
|
332
|
+
const created = await storage.writeMemory("fact", "Frontmatter mint failure content.", { source: "test" });
|
|
333
|
+
const before = await storage.getMemoryById(created.id);
|
|
334
|
+
assert.ok(before);
|
|
335
|
+
const bytesBefore = await readFile(before.path);
|
|
336
|
+
|
|
337
|
+
const seams = storage as unknown as {
|
|
338
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
339
|
+
};
|
|
340
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
341
|
+
seams.casRevisions.beginRevisionTransaction = async () => {
|
|
342
|
+
throw new Error("simulated sidecar mint failure");
|
|
343
|
+
};
|
|
344
|
+
try {
|
|
345
|
+
await assert.rejects(storage.writeMemoryFrontmatter(before, { status: "archived" }));
|
|
346
|
+
} finally {
|
|
347
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
assert.deepEqual(await readFile(before.path), bytesBefore);
|
|
351
|
+
const after = await storage.getMemoryById(created.id);
|
|
352
|
+
assert.ok(after);
|
|
353
|
+
assert.equal(after.frontmatter.status ?? "active", "active", "the semantic flip never landed");
|
|
354
|
+
assert.equal((await storage.readCasRevisionStatus(before.path)).status, "absent");
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("an access-only frontmatter patch bypasses the mint and still lands (#2813 P1 B)", async () => {
|
|
359
|
+
await withStorage(async (storage) => {
|
|
360
|
+
const created = await storage.writeMemory("fact", "Access telemetry mint bypass content.", { source: "test" });
|
|
361
|
+
const before = await storage.getMemoryById(created.id);
|
|
362
|
+
assert.ok(before);
|
|
363
|
+
|
|
364
|
+
const seams = storage as unknown as {
|
|
365
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
366
|
+
};
|
|
367
|
+
seams.casRevisions.beginRevisionTransaction = async () => {
|
|
368
|
+
throw new Error("access-only patches must never mint");
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const lastAccessed = "2026-08-22T00:00:00.000Z";
|
|
372
|
+
assert.equal(
|
|
373
|
+
await storage.writeMemoryFrontmatter(before, { accessCount: 9, lastAccessed }),
|
|
374
|
+
true,
|
|
375
|
+
"an access-only patch succeeds even with a broken mint — it never mints",
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
const after = await storage.getMemoryById(created.id);
|
|
379
|
+
assert.ok(after);
|
|
380
|
+
assert.equal(after.frontmatter.accessCount, 9);
|
|
381
|
+
assert.equal(after.frontmatter.lastAccessed, lastAccessed);
|
|
382
|
+
assert.equal((await storage.readCasRevisionStatus(before.path)).status, "absent");
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
test("a symlinked cas-revisions sidecar directory is rejected, never followed (#2813 P1 A)", async () => {
|
|
387
|
+
await withStorage(async (storage) => {
|
|
388
|
+
const created = await storage.writeMemory("fact", "Symlink escape guard content.", { source: "test" });
|
|
389
|
+
const memory = await storage.getMemoryById(created.id);
|
|
390
|
+
assert.ok(memory);
|
|
391
|
+
assert.equal((await storage.readCasRevisionStatus(memory.path)).status, "absent");
|
|
392
|
+
|
|
393
|
+
const { baseDir } = storage as unknown as { baseDir: string };
|
|
394
|
+
const escapeRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-cas-escape-"));
|
|
395
|
+
try {
|
|
396
|
+
const shardDir = path.join(baseDir, ".offline-sync", "cas-revisions");
|
|
397
|
+
await rm(shardDir, { recursive: true, force: true });
|
|
398
|
+
await mkdir(path.dirname(shardDir), { recursive: true });
|
|
399
|
+
await symlink(escapeRoot, shardDir);
|
|
400
|
+
|
|
401
|
+
const status = await storage.readCasRevisionStatus(memory.path);
|
|
402
|
+
assert.equal(
|
|
403
|
+
status.status,
|
|
404
|
+
"unavailable",
|
|
405
|
+
"a symlinked sidecar reads as unavailable — never as data beyond the memory root",
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
await assert.rejects(storage.updateMemory(created.id, "Body routed through a symlink."));
|
|
409
|
+
const after = await storage.getMemoryById(created.id);
|
|
410
|
+
assert.ok(after);
|
|
411
|
+
assert.equal(after.content, memory.content, "the memory file is untouched when the sidecar path is unsafe");
|
|
412
|
+
assert.deepEqual(
|
|
413
|
+
await readdir(escapeRoot),
|
|
414
|
+
[],
|
|
415
|
+
"no shard, lock, or temporary file escaped the memory root through the symlink",
|
|
416
|
+
);
|
|
417
|
+
} finally {
|
|
418
|
+
await rm(escapeRoot, { recursive: true, force: true });
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("a symlinked .offline-sync ancestor is rejected before any sidecar use (#2813 P1 A)", async () => {
|
|
424
|
+
await withStorage(async (storage) => {
|
|
425
|
+
const created = await storage.writeMemory("fact", "Offline-sync ancestor guard content.", { source: "test" });
|
|
426
|
+
const memory = await storage.getMemoryById(created.id);
|
|
427
|
+
assert.ok(memory);
|
|
428
|
+
|
|
429
|
+
const { baseDir } = storage as unknown as { baseDir: string };
|
|
430
|
+
const escapeRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-offline-sync-escape-"));
|
|
431
|
+
try {
|
|
432
|
+
const offlineSync = path.join(baseDir, ".offline-sync");
|
|
433
|
+
await rm(offlineSync, { recursive: true, force: true });
|
|
434
|
+
await symlink(escapeRoot, offlineSync);
|
|
435
|
+
|
|
436
|
+
assert.equal((await storage.readCasRevisionStatus(memory.path)).status, "unavailable");
|
|
437
|
+
await assert.rejects(storage.writeMemoryFrontmatter(memory, { status: "archived" }));
|
|
438
|
+
assert.deepEqual(await readdir(escapeRoot), [], "nothing escaped through the symlinked ancestor");
|
|
439
|
+
} finally {
|
|
440
|
+
await rm(escapeRoot, { recursive: true, force: true });
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
test("a symlinked shard file reads as unavailable and blocks minting (#2813 P1 A)", async () => {
|
|
446
|
+
await withStorage(async (storage) => {
|
|
447
|
+
const created = await storage.writeMemory("fact", "Shard link guard content.", { source: "test" });
|
|
448
|
+
const memory = await storage.getMemoryById(created.id);
|
|
449
|
+
assert.ok(memory);
|
|
450
|
+
assert.equal(await storage.writeMemoryFrontmatter(memory, { tags: ["v1"] }), true);
|
|
451
|
+
assert.ok(await storage.readCasRevision(memory.path));
|
|
452
|
+
|
|
453
|
+
const { baseDir } = storage as unknown as { baseDir: string };
|
|
454
|
+
const escapeRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-cas-shard-escape-"));
|
|
455
|
+
try {
|
|
456
|
+
const rel = path.relative(baseDir, memory.path).split(path.sep).join("/");
|
|
457
|
+
const escapeToken = "2099-01-01T00:00:00.000Z";
|
|
458
|
+
const escapeShard = path.join(escapeRoot, "shard.json");
|
|
459
|
+
await writeFile(
|
|
460
|
+
escapeShard,
|
|
461
|
+
`${JSON.stringify({ version: 1, path: rel, revision: escapeToken, state: "committed" })}\n`,
|
|
462
|
+
"utf8",
|
|
463
|
+
);
|
|
464
|
+
const shardPath = casShardPath(baseDir, memory.path);
|
|
465
|
+
await rm(shardPath);
|
|
466
|
+
await symlink(escapeShard, shardPath);
|
|
467
|
+
|
|
468
|
+
assert.equal(
|
|
469
|
+
(await storage.readCasRevisionStatus(memory.path)).status,
|
|
470
|
+
"unavailable",
|
|
471
|
+
"a shard symlink is refused — the escape target is never read as the standing receipt",
|
|
472
|
+
);
|
|
473
|
+
await assert.rejects(storage.updateMemory(created.id, "Body over a linked shard."));
|
|
474
|
+
const escaped = JSON.parse(await readFile(escapeShard, "utf8")) as { revision?: string };
|
|
475
|
+
assert.equal(escaped.revision, escapeToken, "the escape target is byte-identical — never followed nor replaced");
|
|
476
|
+
} finally {
|
|
477
|
+
await rm(escapeRoot, { recursive: true, force: true });
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
test("a memory file write failure aborts the pending receipt reservation (#2813 P1 C)", async () => {
|
|
483
|
+
await withStorage(async (storage) => {
|
|
484
|
+
const created = await storage.writeMemory("fact", "Write failure abort content.", { source: "test" });
|
|
485
|
+
const before = await storage.getMemoryById(created.id);
|
|
486
|
+
assert.ok(before);
|
|
487
|
+
const bytesBefore = await readFile(before.path);
|
|
488
|
+
assert.equal((await storage.readCasRevisionStatus(before.path)).status, "absent");
|
|
489
|
+
|
|
490
|
+
const seams = storage as unknown as {
|
|
491
|
+
writeStorageSecureFile: (pathname: string, fileContent: string) => Promise<void>;
|
|
492
|
+
};
|
|
493
|
+
const origWrite = seams.writeStorageSecureFile.bind(seams);
|
|
494
|
+
seams.writeStorageSecureFile = async () => {
|
|
495
|
+
throw new Error("simulated durable memory write failure");
|
|
496
|
+
};
|
|
497
|
+
try {
|
|
498
|
+
await assert.rejects(storage.updateMemory(created.id, "This body must not own a receipt."));
|
|
499
|
+
} finally {
|
|
500
|
+
seams.writeStorageSecureFile = origWrite;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
assert.deepEqual(await readFile(before.path), bytesBefore, "the durable memory file never changed");
|
|
504
|
+
assert.equal(
|
|
505
|
+
(await storage.readCasRevisionStatus(before.path)).status,
|
|
506
|
+
"absent",
|
|
507
|
+
"the aborted reservation left no pending marker — the failed write owns nothing",
|
|
508
|
+
);
|
|
509
|
+
const shardDir = path.join(
|
|
510
|
+
(storage as unknown as { baseDir: string }).baseDir,
|
|
511
|
+
".offline-sync",
|
|
512
|
+
"cas-revisions",
|
|
513
|
+
);
|
|
514
|
+
const leftovers = (await readdir(shardDir).catch(() => [] as string[])).filter((f) => f.endsWith(".json"));
|
|
515
|
+
assert.deepEqual(leftovers, [], "the pending shard was unlinked by the abort");
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
test("a receipt publication failure after the memory write recovers from recorded evidence (#2813 P1 C, #2807)", async () => {
|
|
520
|
+
await withStorage(async (storage) => {
|
|
521
|
+
const created = await storage.writeMemory("fact", "Publish failure ambiguity content.", { source: "test" });
|
|
522
|
+
const before = await storage.getMemoryById(created.id);
|
|
523
|
+
assert.ok(before);
|
|
524
|
+
|
|
525
|
+
const seams = storage as unknown as {
|
|
526
|
+
casRevisions: {
|
|
527
|
+
beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction>;
|
|
528
|
+
reconcilePendingRevision: (pathname: string, fileWriteLanded: boolean) => Promise<string>;
|
|
529
|
+
};
|
|
530
|
+
};
|
|
531
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
532
|
+
let reserved: string | undefined;
|
|
533
|
+
seams.casRevisions.beginRevisionTransaction = async (pathname) => {
|
|
534
|
+
const transaction = await origBegin(pathname);
|
|
535
|
+
reserved = transaction.pendingRevision;
|
|
536
|
+
return {
|
|
537
|
+
pendingRevision: transaction.pendingRevision,
|
|
538
|
+
writeLanded: transaction.writeLanded,
|
|
539
|
+
abort: transaction.abort,
|
|
540
|
+
commit: async () => {
|
|
541
|
+
throw new Error("simulated receipt publication failure");
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
try {
|
|
546
|
+
await assert.rejects(storage.updateMemory(created.id, "Body whose receipt never publishes."));
|
|
547
|
+
} finally {
|
|
548
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
549
|
+
}
|
|
550
|
+
assert.ok(reserved, "the reservation was minted before the write");
|
|
551
|
+
|
|
552
|
+
const onDisk = await readFile(before.path);
|
|
553
|
+
assert.match(onDisk.toString("utf8"), /Body whose receipt never publishes\./, "the durable memory write landed");
|
|
554
|
+
|
|
555
|
+
// #2807: writeLanded recorded evidence, so the next unlocked read
|
|
556
|
+
// publishes the reserved token with the intended file digest.
|
|
557
|
+
assert.deepEqual(await storage.readCasRevisionStatus(before.path), {
|
|
558
|
+
status: "present",
|
|
559
|
+
revision: reserved,
|
|
560
|
+
committedDigest: createHash("sha256").update(onDisk).digest("hex"),
|
|
561
|
+
});
|
|
562
|
+
assert.equal(
|
|
563
|
+
await storage.updateMemory(created.id, "Second body after evidence recovery."),
|
|
564
|
+
true,
|
|
565
|
+
"the target is writable again once the evidence published the receipt",
|
|
566
|
+
);
|
|
567
|
+
const healed = await storage.readCasRevisionStatus(before.path);
|
|
568
|
+
assert.ok(
|
|
569
|
+
healed.status === "present" && healed.revision > reserved,
|
|
570
|
+
"the post-recovery write owns a strictly greater receipt",
|
|
571
|
+
);
|
|
572
|
+
assert.equal(
|
|
573
|
+
await seams.casRevisions.reconcilePendingRevision(before.path, true),
|
|
574
|
+
"committed",
|
|
575
|
+
"manual reconcile after evidence recovery is an idempotent no-op report",
|
|
576
|
+
);
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
test("sequential writers on one target mint unique, strictly increasing receipts (#2813 P1 C)", async () => {
|
|
581
|
+
await withStorage(async (storage) => {
|
|
582
|
+
const created = await storage.writeMemory("fact", "First body.", { source: "test" });
|
|
583
|
+
const memory = await storage.getMemoryById(created.id);
|
|
584
|
+
assert.ok(memory);
|
|
585
|
+
assert.equal((await storage.readCasRevisionStatus(memory.path)).status, "absent");
|
|
586
|
+
|
|
587
|
+
assert.equal(await storage.updateMemory(created.id, "Second body."), true);
|
|
588
|
+
const receiptA = await storage.readCasRevision(memory.path);
|
|
589
|
+
assert.ok(receiptA, "writer A owns the first receipt");
|
|
590
|
+
|
|
591
|
+
assert.equal(await storage.updateMemory(created.id, "Third body."), true);
|
|
592
|
+
const receiptB = await storage.readCasRevision(memory.path);
|
|
593
|
+
assert.ok(receiptB, "writer B owns the second receipt");
|
|
594
|
+
assert.notEqual(receiptA, receiptB, "two commits never share a receipt");
|
|
595
|
+
assert.ok(receiptB > receiptA, "receipts are strictly increasing per target");
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
async function withStorageDir(run: (dir: string) => Promise<void>): Promise<void> {
|
|
600
|
+
StorageManager.clearAllStaticCaches();
|
|
601
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-cas-restart-"));
|
|
602
|
+
try {
|
|
603
|
+
await run(memoryDir);
|
|
604
|
+
} finally {
|
|
605
|
+
StorageManager.clearAllStaticCaches();
|
|
606
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
test("restart after a crash between reserve and write heals on the next mutation (#2807)", async () => {
|
|
611
|
+
await withStorageDir(async (dir) => {
|
|
612
|
+
const first = new StorageManager(dir);
|
|
613
|
+
const created = await first.writeMemory("fact", "Crash before write content.", { source: "test" });
|
|
614
|
+
const memory = await first.getMemoryById(created.id);
|
|
615
|
+
assert.ok(memory);
|
|
616
|
+
|
|
617
|
+
// Crash simulation: reserve a token, then abandon the transaction
|
|
618
|
+
// before the durable write — exactly the on-disk state a killed
|
|
619
|
+
// process leaves behind (pending marker, unchanged file).
|
|
620
|
+
const seams = first as unknown as { casRevisions: CasRevisionStore };
|
|
621
|
+
await seams.casRevisions.beginRevisionTransaction(memory.path);
|
|
622
|
+
StorageManager.clearAllStaticCaches();
|
|
623
|
+
|
|
624
|
+
const restarted = new StorageManager(dir);
|
|
625
|
+
const firstRead = await restarted.readCasRevisionStatus(memory.path);
|
|
626
|
+
assert.equal(
|
|
627
|
+
firstRead.status,
|
|
628
|
+
"unavailable",
|
|
629
|
+
"an unlocked read will not abort a reserve-only marker — a live owner may be between reserve and write",
|
|
630
|
+
);
|
|
631
|
+
assert.equal(
|
|
632
|
+
await restarted.updateMemory(created.id, "Body after crash recovery."),
|
|
633
|
+
true,
|
|
634
|
+
"the next mutation recovers the orphaned reservation under the path lock — the target is writable again",
|
|
635
|
+
);
|
|
636
|
+
assert.equal(
|
|
637
|
+
(await restarted.readCasRevisionStatus(memory.path)).status,
|
|
638
|
+
"present",
|
|
639
|
+
"the post-restart write owns a committed receipt",
|
|
640
|
+
);
|
|
641
|
+
assert.ok(await restarted.readCasRevision(memory.path));
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
test("restart after a crash between write and commit publishes the reserved receipt (#2807)", async () => {
|
|
646
|
+
await withStorageDir(async (dir) => {
|
|
647
|
+
const first = new StorageManager(dir);
|
|
648
|
+
const created = await first.writeMemory("fact", "Crash after write content.", { source: "test" });
|
|
649
|
+
const memory = await first.getMemoryById(created.id);
|
|
650
|
+
assert.ok(memory);
|
|
651
|
+
|
|
652
|
+
let reserved: string | undefined;
|
|
653
|
+
const seams = first as unknown as {
|
|
654
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
655
|
+
};
|
|
656
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
657
|
+
seams.casRevisions.beginRevisionTransaction = async (pathname) => {
|
|
658
|
+
const transaction = await origBegin(pathname);
|
|
659
|
+
reserved = transaction.pendingRevision;
|
|
660
|
+
return {
|
|
661
|
+
pendingRevision: transaction.pendingRevision,
|
|
662
|
+
writeLanded: transaction.writeLanded,
|
|
663
|
+
abort: transaction.abort,
|
|
664
|
+
commit: async () => {
|
|
665
|
+
throw new Error("simulated crash before receipt publication");
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
};
|
|
669
|
+
try {
|
|
670
|
+
await assert.rejects(first.updateMemory(created.id, "Body whose commit never runs."));
|
|
671
|
+
} finally {
|
|
672
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
673
|
+
}
|
|
674
|
+
assert.ok(reserved);
|
|
675
|
+
StorageManager.clearAllStaticCaches();
|
|
676
|
+
|
|
677
|
+
const restarted = new StorageManager(dir);
|
|
678
|
+
const landedBytes = await readFile(memory.path);
|
|
679
|
+
assert.deepEqual(
|
|
680
|
+
await restarted.readCasRevisionStatus(memory.path),
|
|
681
|
+
{
|
|
682
|
+
status: "present",
|
|
683
|
+
revision: reserved,
|
|
684
|
+
committedDigest: createHash("sha256").update(landedBytes).digest("hex"),
|
|
685
|
+
},
|
|
686
|
+
"the first read after restart publishes the reserved token from writeLanded evidence",
|
|
687
|
+
);
|
|
688
|
+
assert.equal(
|
|
689
|
+
await restarted.updateMemory(created.id, "Body after evidence-published restart."),
|
|
690
|
+
true,
|
|
691
|
+
"the memory stays writable after the crash-after-write restart",
|
|
692
|
+
);
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
test("restart with an ambiguous durable change fails closed with actionable recovery (#2807)", async () => {
|
|
697
|
+
await withStorageDir(async (dir) => {
|
|
698
|
+
const first = new StorageManager(dir);
|
|
699
|
+
const created = await first.writeMemory("fact", "Ambiguous restart content.", { source: "test" });
|
|
700
|
+
const memory = await first.getMemoryById(created.id);
|
|
701
|
+
assert.ok(memory);
|
|
702
|
+
|
|
703
|
+
const seams = first as unknown as {
|
|
704
|
+
casRevisions: { beginRevisionTransaction: (pathname: string) => Promise<CasRevisionTransaction> };
|
|
705
|
+
};
|
|
706
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
707
|
+
seams.casRevisions.beginRevisionTransaction = async (pathname) => {
|
|
708
|
+
const transaction = await origBegin(pathname);
|
|
709
|
+
return {
|
|
710
|
+
pendingRevision: transaction.pendingRevision,
|
|
711
|
+
writeLanded: transaction.writeLanded,
|
|
712
|
+
abort: transaction.abort,
|
|
713
|
+
commit: async () => {
|
|
714
|
+
throw new Error("simulated crash before receipt publication");
|
|
715
|
+
},
|
|
716
|
+
};
|
|
717
|
+
};
|
|
718
|
+
try {
|
|
719
|
+
await assert.rejects(first.updateMemory(created.id, "Body before the unexplained change."));
|
|
720
|
+
} finally {
|
|
721
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
722
|
+
}
|
|
723
|
+
// After the crash, the durable file changes in a way the reservation
|
|
724
|
+
// can neither claim nor disown — still a valid record, so the next
|
|
725
|
+
// semantic mutation reaches the mint and must fail closed there.
|
|
726
|
+
const crashed = await readFile(memory.path, "utf8");
|
|
727
|
+
await writeFile(
|
|
728
|
+
memory.path,
|
|
729
|
+
crashed.replace("Body before the unexplained change.", "Body silently rewritten by a third party."),
|
|
730
|
+
"utf8",
|
|
731
|
+
);
|
|
732
|
+
StorageManager.clearAllStaticCaches();
|
|
733
|
+
|
|
734
|
+
const restarted = new StorageManager(dir);
|
|
735
|
+
const status = await restarted.readCasRevisionStatus(memory.path);
|
|
736
|
+
assert.equal(status.status, "unavailable", "an ambiguous marker reads as unavailable, never as presence or absence");
|
|
737
|
+
assert.match(
|
|
738
|
+
status.status === "unavailable" ? status.reason : "",
|
|
739
|
+
/ambiguous[\s\S]{0,512}Refusing to guess/,
|
|
740
|
+
"the reason names the ambiguity and the refusal",
|
|
741
|
+
);
|
|
742
|
+
await assert.rejects(
|
|
743
|
+
restarted.updateMemory(created.id, "Write into an ambiguous target."),
|
|
744
|
+
"a semantic mutation fails closed while the marker is ambiguous",
|
|
745
|
+
);
|
|
746
|
+
assert.match(
|
|
747
|
+
await readFile(memory.path, "utf8"),
|
|
748
|
+
/Body silently rewritten by a third party\./,
|
|
749
|
+
"the refused mutation never touched the durable file",
|
|
750
|
+
);
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
test("crash after memory write before writeLanded recovers from host-forwarded expected bytes (#2813 P1)", async () => {
|
|
755
|
+
await withStorageDir(async (dir) => {
|
|
756
|
+
const first = new StorageManager(dir);
|
|
757
|
+
const created = await first.writeMemory("fact", "Baseline before the writeLanded crash window.", { source: "test" });
|
|
758
|
+
const memory = await first.getMemoryById(created.id);
|
|
759
|
+
assert.ok(memory);
|
|
760
|
+
|
|
761
|
+
let reserved: string | undefined;
|
|
762
|
+
let forwardedExpected: string | Buffer | null | undefined;
|
|
763
|
+
const seams = first as unknown as {
|
|
764
|
+
casRevisions: {
|
|
765
|
+
beginRevisionTransaction: (
|
|
766
|
+
pathname: string,
|
|
767
|
+
expectedContent?: string | Buffer | null,
|
|
768
|
+
) => Promise<CasRevisionTransaction>;
|
|
769
|
+
};
|
|
770
|
+
};
|
|
771
|
+
const origBegin = seams.casRevisions.beginRevisionTransaction.bind(seams.casRevisions);
|
|
772
|
+
seams.casRevisions.beginRevisionTransaction = async (pathname, expectedContent) => {
|
|
773
|
+
forwardedExpected = expectedContent;
|
|
774
|
+
const transaction = await origBegin(pathname, expectedContent);
|
|
775
|
+
reserved = transaction.pendingRevision;
|
|
776
|
+
return {
|
|
777
|
+
pendingRevision: transaction.pendingRevision,
|
|
778
|
+
writeLanded: async () => {
|
|
779
|
+
throw new Error("simulated crash before writeLanded");
|
|
780
|
+
},
|
|
781
|
+
abort: transaction.abort,
|
|
782
|
+
commit: async () => {
|
|
783
|
+
throw new Error("simulated crash before receipt publication");
|
|
784
|
+
},
|
|
785
|
+
};
|
|
786
|
+
};
|
|
787
|
+
try {
|
|
788
|
+
await assert.rejects(first.updateMemory(created.id, "Body that landed without writeLanded."));
|
|
789
|
+
} finally {
|
|
790
|
+
seams.casRevisions.beginRevisionTransaction = origBegin;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
assert.ok(reserved, "the reservation was minted before the write");
|
|
794
|
+
assert.equal(
|
|
795
|
+
typeof forwardedExpected,
|
|
796
|
+
"string",
|
|
797
|
+
"the revision host must forward the intended payload bytes",
|
|
798
|
+
);
|
|
799
|
+
assert.match(
|
|
800
|
+
String(forwardedExpected),
|
|
801
|
+
/Body that landed without writeLanded\./,
|
|
802
|
+
"forwarded bytes are the durable file payload, not only the target path",
|
|
803
|
+
);
|
|
804
|
+
|
|
805
|
+
const shard = JSON.parse(await readFile(casShardPath(dir, memory.path), "utf8")) as {
|
|
806
|
+
state?: string;
|
|
807
|
+
expectedDigest?: string;
|
|
808
|
+
writeLanded?: boolean;
|
|
809
|
+
};
|
|
810
|
+
assert.equal(shard.state, "pending");
|
|
811
|
+
assert.equal(shard.writeLanded, false, "writeLanded never ran, so the marker is not landed");
|
|
812
|
+
assert.equal(
|
|
813
|
+
typeof shard.expectedDigest,
|
|
814
|
+
"string",
|
|
815
|
+
"expectedDigest must be recorded at reserve time so crash-before-writeLanded is decidable",
|
|
816
|
+
);
|
|
817
|
+
|
|
818
|
+
StorageManager.clearAllStaticCaches();
|
|
819
|
+
const restarted = new StorageManager(dir);
|
|
820
|
+
const unlocked = await restarted.readCasRevisionStatus(memory.path);
|
|
821
|
+
assert.equal(
|
|
822
|
+
unlocked.status,
|
|
823
|
+
"unavailable",
|
|
824
|
+
"an unlocked read must not publish a not-yet-landed reservation",
|
|
825
|
+
);
|
|
826
|
+
assert.equal(
|
|
827
|
+
await restarted.updateMemory(created.id, "Writable after expected-bytes recovery."),
|
|
828
|
+
true,
|
|
829
|
+
"the path-locked write recovers from the host-forwarded expected bytes",
|
|
830
|
+
);
|
|
831
|
+
const recovered = await restarted.readCasRevisionStatus(memory.path);
|
|
832
|
+
assert.equal(recovered.status, "present");
|
|
833
|
+
assert.ok(
|
|
834
|
+
recovered.status === "present" && recovered.revision > reserved,
|
|
835
|
+
"the post-recovery write owns a strictly greater receipt",
|
|
836
|
+
);
|
|
837
|
+
});
|
|
838
|
+
});
|