@remnic/core 9.69.32 → 9.69.34
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 +13 -11
- package/dist/access-admin-ops-surface.js +64 -59
- package/dist/access-authorization-probe.d.ts +13 -11
- package/dist/access-authorization-probe.js +65 -60
- package/dist/access-boundary.d.ts +13 -11
- package/dist/access-boundary.js +64 -59
- package/dist/access-cli.js +140 -136
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +2 -1
- package/dist/access-coding-context-resolution.js +3 -3
- package/dist/access-extraction-force-flush.d.ts +13 -11
- package/dist/access-extraction-force-flush.js +64 -59
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-briefing.d.ts +13 -11
- package/dist/access-http-briefing.js +65 -60
- package/dist/access-http-lcm-compaction.d.ts +13 -11
- package/dist/access-http-lifecycle-flush.d.ts +13 -11
- package/dist/access-http-offline-stream.d.ts +13 -11
- package/dist/access-http-query.d.ts +3 -2
- package/dist/access-http-query.js +66 -61
- package/dist/access-http.d.ts +14 -12
- package/dist/access-http.js +86 -82
- package/dist/access-identity-continuity-surface.d.ts +11 -9
- package/dist/access-identity-continuity-surface.js +64 -59
- package/dist/access-lcm-surface.d.ts +13 -11
- package/dist/access-lcm-surface.js +64 -59
- package/dist/access-mcp.d.ts +13 -11
- package/dist/access-mcp.js +73 -69
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-BsvmyENS.d.ts → access-namespace-preflight-kXG8MvYx.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +64 -59
- package/dist/access-observe-transcript.d.ts +11 -9
- package/dist/access-observe-transcript.js +3 -3
- package/dist/access-observe-write-surface.d.ts +15 -13
- package/dist/access-observe-write-surface.js +64 -59
- package/dist/access-offline-manifest.d.ts +47 -11
- package/dist/access-offline-manifest.js +18 -16
- package/dist/access-operations-batch.js +67 -63
- package/dist/access-operations.d.ts +18 -16
- package/dist/access-operations.js +72 -68
- package/dist/access-recall-concurrency.d.ts +13 -11
- package/dist/access-recall-concurrency.js +64 -59
- package/dist/access-recall-response.d.ts +13 -11
- package/dist/access-recall-response.js +64 -59
- package/dist/access-recall-surface.d.ts +13 -11
- package/dist/access-recall-surface.js +64 -59
- package/dist/access-schema.d.ts +138 -96
- package/dist/access-schema.js +15 -1
- package/dist/{access-service-CCpOuS46.d.ts → access-service-WUm2LnXZ.d.ts} +110 -108
- package/dist/access-service-helpers.d.ts +13 -11
- package/dist/access-service.d.ts +13 -11
- package/dist/access-service.js +64 -59
- package/dist/access-surface-catalog.d.ts +13 -11
- package/dist/access-surface-catalog.js +66 -61
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +4 -3
- package/dist/action-confidence.d.ts +2 -1
- package/dist/active-memory-bridge.d.ts +2 -1
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +2 -1
- package/dist/active-recall.js +14 -12
- package/dist/active-recall.js.map +1 -1
- package/dist/activity/digest.d.ts +56 -0
- package/dist/activity/digest.js +32 -0
- package/dist/adapters/index.d.ts +46 -1
- package/dist/adapters/index.js +13 -9
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +2 -1
- package/dist/artifact-search.d.ts +2 -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 +2 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +11 -9
- package/dist/briefing-window.d.ts +3 -2
- package/dist/briefing.d.ts +3 -2
- package/dist/briefing.js +28 -27
- package/dist/buffer-surprise-report.d.ts +2 -1
- package/dist/buffer-turn-helpers.d.ts +2 -1
- package/dist/buffer.d.ts +3 -2
- package/dist/buffer.js +12 -11
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/calibration.js +3 -2
- package/dist/calibration.js.map +1 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-merge-IPG4IOFP.js → capsule-merge-ZCXUPLNJ.js} +2 -2
- package/dist/{catalog-CDZLyiXL.d.ts → catalog-BaCx29iv.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +2 -1
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +29 -28
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +2 -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-IY2FVXM6.js → chunk-2AU4D4HQ.js} +3 -3
- package/dist/{chunk-QDY6KYTN.js → chunk-2JCA2PQT.js} +3 -3
- package/dist/{chunk-RSVEP77Y.js → chunk-2UZ5ZH6W.js} +3 -3
- package/dist/{chunk-XQ2Q43XD.js → chunk-326KUXIR.js} +15 -648
- package/dist/chunk-326KUXIR.js.map +1 -0
- package/dist/{chunk-NWWXSJX5.js → chunk-34QW2LK2.js} +2 -2
- package/dist/{chunk-S7DPKM5W.js → chunk-353C5UNV.js} +1 -1
- package/dist/{chunk-GQOMZ3MK.js → chunk-36UBSLFN.js} +2 -2
- package/dist/{chunk-DBQWVT2H.js → chunk-3CBI2ZSA.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-7VJXIDOC.js → chunk-4JVQRFZD.js} +9 -9
- package/dist/{chunk-22FVR2KE.js → chunk-4MIS4CQW.js} +6 -2
- package/dist/chunk-4MIS4CQW.js.map +1 -0
- package/dist/{chunk-WHBVXTUI.js → chunk-4PB2MBY6.js} +9 -9
- package/dist/{chunk-TEYN7ZYF.js → chunk-4WCNPQQ5.js} +4 -4
- package/dist/{chunk-Z4PCVRTN.js → chunk-5A7ZUOBA.js} +217 -396
- package/dist/chunk-5A7ZUOBA.js.map +1 -0
- package/dist/chunk-5HYUUFMQ.js +1280 -0
- package/dist/chunk-5HYUUFMQ.js.map +1 -0
- package/dist/{chunk-RBGREYVJ.js → chunk-5QBDLMGG.js} +2 -2
- package/dist/{chunk-RKBLRTNT.js → chunk-5SDSVX7N.js} +2 -2
- package/dist/{chunk-LPECRQO4.js → chunk-5THU7NFP.js} +3 -3
- package/dist/{chunk-N7RWREIQ.js → chunk-65RENJGB.js} +6 -1
- package/dist/chunk-65RENJGB.js.map +1 -0
- package/dist/{chunk-LWA7MDVO.js → chunk-6CCRSQWT.js} +2 -2
- package/dist/{chunk-TIT2C6WX.js → chunk-6XYC7NM4.js} +2 -2
- package/dist/{chunk-FHQSPTPZ.js → chunk-6YAIN5XJ.js} +2 -2
- package/dist/{chunk-PV36INNL.js → chunk-757NP436.js} +3 -3
- package/dist/{chunk-WJBZMNNS.js → chunk-7CAY3YKP.js} +742 -29
- package/dist/chunk-7CAY3YKP.js.map +1 -0
- package/dist/{chunk-6H5JYDOM.js → chunk-7J2CGXG3.js} +2 -2
- package/dist/{chunk-FBMYGNOC.js → chunk-A2YQL2FF.js} +6 -6
- 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-MPYD657E.js → chunk-A7WOWDZK.js} +2 -2
- package/dist/{chunk-C4OTC6WY.js → chunk-AIKTQVV3.js} +3 -3
- package/dist/{chunk-CGC5UQCF.js → chunk-AKE4GGQ3.js} +2 -2
- package/dist/{chunk-VP67GZ7T.js → chunk-APFKZVJS.js} +2 -2
- package/dist/{chunk-M75RYSHS.js → chunk-AQIRQUCP.js} +2 -2
- package/dist/{chunk-S7T2TY65.js → chunk-AXFR2NQ5.js} +3 -3
- package/dist/{chunk-PSPABFN2.js → chunk-BD7JTBYP.js} +4 -4
- package/dist/{chunk-FCSZ4K2X.js → chunk-BJJWRWER.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-MFJBANPX.js → chunk-C2BFTYD7.js} +2 -2
- package/dist/{chunk-3JVLGJCY.js → chunk-C6KRO3SU.js} +2 -2
- package/dist/{chunk-Q3O3VKRB.js → chunk-CRUFVJOX.js} +16 -15
- package/dist/chunk-CRUFVJOX.js.map +1 -0
- package/dist/{chunk-AOCP6JA7.js → chunk-D3IZCN5P.js} +4 -4
- package/dist/{chunk-ROKKIMON.js → chunk-EJIEQOPB.js} +5 -5
- package/dist/{chunk-ET356KSB.js → chunk-F4TWWUMP.js} +2 -2
- package/dist/{chunk-CLLPJ6QT.js → chunk-FQXJAC3T.js} +2 -2
- package/dist/{chunk-DD5JFCWM.js → chunk-GCBIXUPT.js} +2 -2
- package/dist/{chunk-ROGRI25A.js → chunk-I3H5LFOI.js} +2 -2
- package/dist/{chunk-S65WXHNK.js → chunk-IFFLUCCU.js} +2 -2
- package/dist/{chunk-MYMNC6O5.js → chunk-ISYZ5DUI.js} +64 -60
- package/dist/{chunk-MYMNC6O5.js.map → chunk-ISYZ5DUI.js.map} +1 -1
- package/dist/{chunk-D5LORF7A.js → chunk-JZDH2ZZK.js} +3 -3
- package/dist/{chunk-2GPE5UCR.js → chunk-K6IPSW5B.js} +2 -2
- package/dist/{chunk-HG6HXVHQ.js → chunk-KDJHLOZP.js} +10 -10
- package/dist/{chunk-I27RSQRR.js → chunk-KYGOQV37.js} +2 -2
- package/dist/{chunk-JEIXTYVG.js → chunk-L2QLDZJC.js} +46 -17
- package/dist/chunk-L2QLDZJC.js.map +1 -0
- package/dist/{chunk-A7XEPMQ6.js → chunk-LAVJC57X.js} +3 -3
- package/dist/chunk-LAVJC57X.js.map +1 -0
- package/dist/{chunk-VZWXFXLX.js → chunk-LMCD5W5B.js} +2 -2
- package/dist/{chunk-3QQTXYZ6.js → chunk-LSLCFCCQ.js} +2 -1
- package/dist/chunk-LSLCFCCQ.js.map +1 -0
- package/dist/{chunk-MKD3OMPS.js → chunk-M3MYMWXG.js} +2 -2
- package/dist/{chunk-DITMGZOL.js → chunk-MMG5K6XJ.js} +2 -2
- package/dist/{chunk-VGXM5B4H.js → chunk-MNIPH6LD.js} +2 -2
- package/dist/{chunk-CZYYJZB6.js → chunk-ND2O2PVN.js} +1014 -1318
- package/dist/chunk-ND2O2PVN.js.map +1 -0
- package/dist/chunk-NPNSKE76.js +220 -0
- package/dist/chunk-NPNSKE76.js.map +1 -0
- package/dist/{chunk-MKWKYHXJ.js → chunk-OB3XMWX5.js} +4 -4
- package/dist/{chunk-XU6OEECT.js → chunk-OQQXGYMX.js} +3 -3
- package/dist/{chunk-GTWHVXPA.js → chunk-OZUXKUPD.js} +6 -4
- package/dist/{chunk-GTWHVXPA.js.map → chunk-OZUXKUPD.js.map} +1 -1
- package/dist/chunk-PCEYGOSL.js +66 -0
- package/dist/chunk-PCEYGOSL.js.map +1 -0
- package/dist/{chunk-47DEYNMR.js → chunk-PEXW2JCK.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-SO7SV523.js → chunk-Q6LCCIZN.js} +1 -1
- package/dist/chunk-Q6LCCIZN.js.map +1 -0
- package/dist/{chunk-42SDNZCU.js → chunk-QF4J3KMV.js} +19 -19
- package/dist/{chunk-SB6PSOP7.js → chunk-QLJ6762U.js} +2 -2
- package/dist/{chunk-XOVKXJEP.js → chunk-R3TLVTWW.js} +3 -3
- package/dist/{chunk-PHNAB54Q.js → chunk-RQO3J4MR.js} +2 -2
- package/dist/{chunk-5N53UBH2.js → chunk-RR7G2X7C.js} +5 -5
- package/dist/{chunk-DCJ3YFIC.js → chunk-S2ULTQZR.js} +2 -2
- package/dist/{chunk-GY5WZBA6.js → chunk-S76KRJDG.js} +3 -3
- 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-SQJ3SDIW.js → chunk-SZWEDG3H.js} +13 -7
- package/dist/chunk-SZWEDG3H.js.map +1 -0
- package/dist/{chunk-E2ZHGBAK.js → chunk-T2JSUEH6.js} +2 -2
- package/dist/{chunk-QMGXMJ2O.js → chunk-T2YFZ27G.js} +9 -9
- package/dist/{chunk-LEPOP46W.js → chunk-TFA6HPOA.js} +4 -4
- package/dist/{chunk-BA6WOZOT.js → chunk-TK4FHQRN.js} +4 -4
- package/dist/chunk-TLHNF6GA.js +647 -0
- package/dist/chunk-TLHNF6GA.js.map +1 -0
- package/dist/{chunk-ZNJSBIP4.js → chunk-TNSCIPBQ.js} +4 -4
- package/dist/{chunk-YUMDFDUA.js → chunk-TWYTGIBR.js} +4 -4
- package/dist/{chunk-FDLDOEO6.js → chunk-UBG4GAEP.js} +51 -6
- package/dist/chunk-UBG4GAEP.js.map +1 -0
- package/dist/{chunk-EZZV7OQL.js → chunk-UEZKN6VR.js} +2 -2
- package/dist/{chunk-HY55QQD7.js → chunk-UJX4I26O.js} +2 -2
- package/dist/{chunk-BLUYQFRH.js → chunk-VELCIWJZ.js} +15 -11
- package/dist/chunk-VELCIWJZ.js.map +1 -0
- package/dist/{chunk-CBCNKKZD.js → chunk-VIZR45AN.js} +2 -2
- package/dist/{chunk-ZG74PWRW.js → chunk-VZAKYDMJ.js} +2 -2
- package/dist/{chunk-ITPS5DDH.js → chunk-W5BLTZZJ.js} +8 -8
- package/dist/chunk-W6IJMWTZ.js +72 -0
- package/dist/chunk-W6IJMWTZ.js.map +1 -0
- package/dist/{chunk-H3TKENU4.js → chunk-WIKO4SCR.js} +5 -5
- package/dist/{chunk-YFLLGRXO.js → chunk-X2QPKLPL.js} +2 -2
- package/dist/{chunk-FGGYSN4P.js → chunk-X424T5JQ.js} +2 -2
- package/dist/{chunk-NAXDPKVM.js → chunk-XPJNT6PI.js} +4 -4
- package/dist/{chunk-2JVJ7UHC.js → chunk-XQU3CPF2.js} +4 -2
- package/dist/chunk-XQU3CPF2.js.map +1 -0
- package/dist/chunk-XW2T4QAW.js +1 -0
- package/dist/{chunk-VED2YHUD.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-RC5DXXWC.js → chunk-YM7YN37H.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-565C6ZFO.js → chunk-Z7YDVHDI.js} +2 -2
- 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-GVG3JYBI.js → chunk-ZMKYCFJ7.js} +640 -199
- package/dist/chunk-ZMKYCFJ7.js.map +1 -0
- package/dist/{chunk-HK32G473.js → chunk-ZWEZXVYH.js} +2 -2
- package/dist/{cli-NEEdq5Rt.d.ts → cli-5mTYh1Tn.d.ts} +5 -5
- package/dist/cli-fallback.d.ts +11 -4
- package/dist/cli-fallback.js +5 -1
- package/dist/cli.d.ts +15 -13
- package/dist/cli.js +110 -106
- package/dist/coding/export-okf-codegraph.d.ts +2 -1
- package/dist/coding/export-okf-codegraph.js +34 -32
- package/dist/coding/export-okf-codegraph.js.map +1 -1
- package/dist/coding/pre-action-gate.d.ts +2 -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 +3 -2
- package/dist/compounding/engine.js +29 -28
- package/dist/compounding/preference-consolidator.d.ts +2 -1
- package/dist/compression-optimizer.d.ts +2 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.js +14 -12
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +28 -27
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +30 -29
- package/dist/consolidation-provenance-check.d.ts +3 -2
- package/dist/consolidation-undo.d.ts +3 -2
- package/dist/contradiction/index.d.ts +4 -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 +2 -1
- package/dist/convergence-refresh.d.ts +3 -2
- package/dist/convergence-refresh.js +30 -29
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/backend.js +3 -3
- package/dist/conversation-index/chunker.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.js +2 -2
- package/dist/conversation-index/indexer.d.ts +2 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/corpus-watermark.d.ts +2 -1
- package/dist/corpus-watermark.js +31 -30
- package/dist/cross-lingual-recall.d.ts +2 -1
- package/dist/day-summary.d.ts +2 -1
- package/dist/deep-recall-http-glue.d.ts +13 -11
- package/dist/deep-recall-http-glue.js +12 -2
- package/dist/deep-recall-mcp-tools.d.ts +13 -11
- package/dist/deep-recall-policy-llm.d.ts +2 -1
- package/dist/deep-recall-policy-llm.js +4 -3
- package/dist/deep-recall-seeds.d.ts +2 -1
- package/dist/delinearize.d.ts +2 -1
- package/dist/dependency-propagation-config.d.ts +2 -1
- package/dist/{dependency-propagation-delivery-CQPCu0o5.d.ts → dependency-propagation-delivery-CDQCxNll.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-origin-fields.d.ts +2 -1
- package/dist/entity-retrieval.d.ts +3 -2
- package/dist/entity-retrieval.js +28 -27
- package/dist/entity-schema.d.ts +2 -1
- package/dist/episodic-context.d.ts +2 -1
- package/dist/eval-trajectory-contracts.d.ts +2 -1
- package/dist/eval-trajectory-store.d.ts +2 -1
- package/dist/eval-trajectory.d.ts +2 -1
- package/dist/explicit-capture.d.ts +11 -9
- package/dist/explicit-capture.js +6 -6
- package/dist/external-wiki-access.d.ts +13 -11
- package/dist/external-wiki-access.js +65 -60
- package/dist/external-wiki-collection-registration.d.ts +2 -1
- package/dist/external-wiki-collection.d.ts +2 -1
- package/dist/external-wiki-mcp-tools.d.ts +13 -11
- package/dist/extraction-error-classification.d.ts +2 -1
- package/dist/extraction-faithfulness.d.ts +2 -1
- package/dist/extraction-faithfulness.js +4 -3
- package/dist/extraction-judge-telemetry.d.ts +2 -1
- package/dist/extraction-judge-training.d.ts +2 -1
- package/dist/extraction-judge.d.ts +2 -1
- package/dist/extraction-judge.js +5 -4
- package/dist/extraction-liveness.d.ts +2 -1
- package/dist/extraction-normalization.d.ts +2 -1
- package/dist/extraction-prompt.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +40 -38
- package/dist/fallback-llm.d.ts +2 -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-CqAZyXKX.d.ts +23 -0
- package/dist/graph-append-error.d.ts +2 -1
- package/dist/graph-dashboard-diff.d.ts +2 -1
- package/dist/graph-dashboard-key.d.ts +2 -1
- package/dist/graph-dashboard-parser.d.ts +2 -1
- package/dist/graph-edge-reinforcement.d.ts +2 -1
- package/dist/graph-jsonl.d.ts +2 -1
- package/dist/graph-path-reconstruction.d.ts +2 -1
- package/dist/graph-path-scoring.d.ts +2 -1
- package/dist/graph-snapshot.d.ts +2 -1
- package/dist/graph.d.ts +2 -1
- package/dist/harmonic-retrieval.js +2 -2
- package/dist/importance.d.ts +2 -1
- package/dist/importers/index.d.ts +2 -1
- package/dist/importers/test-utils.d.ts +2 -1
- package/dist/in-flight-reads.d.ts +2 -1
- package/dist/{index-C9VXenR8.d.ts → index-BNluTxBp.d.ts} +2 -2
- package/dist/index.d.ts +963 -945
- package/dist/index.js +323 -221
- package/dist/intent.d.ts +2 -1
- package/dist/lcm/engine.d.ts +2 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +2 -1
- package/dist/lcm/index.js +7 -7
- package/dist/lcm/tools.d.ts +2 -1
- package/dist/lifecycle.d.ts +2 -1
- package/dist/live-connectors-runner.d.ts +2 -1
- package/dist/local-llm.d.ts +4 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/location/index.d.ts +4 -3
- package/dist/location/index.js +33 -32
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +28 -27
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -27
- package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +29 -28
- package/dist/{maintenance-C14sorKa.d.ts → maintenance-8hmWOMY_.d.ts} +378 -4
- package/dist/mcp-memory-inspector-app.d.ts +13 -11
- package/dist/memory-action-policy.d.ts +2 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-controller.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -1
- package/dist/memory-snapshot.d.ts +2 -1
- package/dist/memory-subject-cli.d.ts +13 -11
- package/dist/memory-subject.d.ts +13 -11
- package/dist/memory-worth-outcomes.d.ts +3 -2
- package/dist/migrate/from-engram.js +2 -2
- package/dist/models-json.d.ts +2 -1
- package/dist/namespaces/migrate.d.ts +4 -3
- package/dist/namespaces/migrate.js +29 -28
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +11 -11
- package/dist/namespaces/storage.d.ts +4 -3
- package/dist/namespaces/storage.js +28 -27
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/network/tailscale.js +2 -2
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +6 -6
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +32 -31
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-toolkit.d.ts +4 -3
- package/dist/operator-toolkit.js +48 -46
- package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
- package/dist/orchestration/maintenance.d.ts +5 -4
- package/dist/orchestration/maintenance.js +47 -42
- package/dist/{orchestrator-kqSzGv7e.d.ts → orchestrator-BUd_3Q86.d.ts} +17 -29
- package/dist/orchestrator.d.ts +11 -9
- package/dist/orchestrator.js +144 -138
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-DRUwHb1X.d.ts → pipeline-Dv1Bv0ma.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/{public-http-CW3l0g3P.d.ts → public-http-L-IymRBN.d.ts} +1 -1
- package/dist/{qmd-BVWlg1YS.d.ts → qmd-Mj508lHA.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +3 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +3 -2
- package/dist/qmd.js +2 -2
- package/dist/recall-concurrency-config.d.ts +2 -1
- package/dist/recall-disclosure-escalation.d.ts +2 -1
- package/dist/recall-explain-renderer.d.ts +2 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -1
- package/dist/recall-navigate-access.d.ts +2 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +2 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +2 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +2 -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 +56 -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 +2 -1
- package/dist/recall-tag-filter.d.ts +2 -1
- package/dist/recall-timings.d.ts +2 -1
- package/dist/recall-xray-cli.d.ts +2 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +9 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +11 -2
- package/dist/reconcile/cursor.js +6 -4
- package/dist/reconcile/cursor.js.map +1 -1
- package/dist/reconcile/manifest.d.ts +37 -2
- package/dist/reconcile/manifest.js +15 -5
- package/dist/reconcile/plan.d.ts +2 -1
- package/dist/replay/normalizers/chatgpt.d.ts +2 -1
- package/dist/replay/normalizers/claude.d.ts +2 -1
- package/dist/replay/normalizers/openclaw.d.ts +2 -1
- package/dist/replay/normalizers/shared.d.ts +2 -1
- package/dist/replay/runner.d.ts +2 -1
- package/dist/replay/types.d.ts +2 -1
- package/dist/replica-divergence.d.ts +2 -1
- package/dist/replica-peers-config.d.ts +2 -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 +2 -1
- package/dist/resume-bundles.js +15 -13
- package/dist/retrieval-agents.d.ts +3 -2
- package/dist/retrieval-tiers.d.ts +2 -1
- package/dist/routing/engine.d.ts +2 -1
- package/dist/routing/store.d.ts +2 -1
- package/dist/runtime/child-process.d.ts +1 -1
- package/dist/runtime/child-process.js +1 -1
- package/dist/salvage-envelope.d.ts +2 -1
- package/dist/salvage-envelope.js +2 -2
- package/dist/schemas.d.ts +176 -176
- package/dist/{scope-profiles-Vl00B1KU.d.ts → scope-profiles-B6BGVbxm.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/factory.d.ts +2 -1
- package/dist/search/factory.js +10 -10
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +14 -14
- package/dist/search/lancedb-backend.d.ts +2 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +2 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +2 -1
- package/dist/search/orama-backend.d.ts +2 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +2 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/{semantic-consolidation-BC9-GFuT.d.ts → semantic-consolidation-J-598F5M.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +29 -28
- package/dist/semantic-rule-promotion.js +28 -27
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +28 -27
- package/dist/{service-BOy6dHfc.d.ts → service-ZQkJ52cz.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -1
- package/dist/session-observer-state.d.ts +2 -1
- package/dist/shared-context/manager.d.ts +8 -7
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +38 -36
- package/dist/standup/build.js +29 -28
- package/dist/{storage-BLJRnFi6.d.ts → storage-CU_hZUgP.d.ts} +67 -6
- package/dist/storage.d.ts +4 -3
- package/dist/storage.js +27 -26
- package/dist/subject-config.d.ts +2 -1
- package/dist/subject-config.js +2 -2
- package/dist/summarizer.d.ts +2 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +2 -1
- package/dist/support-passport/index.d.ts +49 -15
- package/dist/support-passport/index.js +72 -63
- package/dist/temporal-supersession.d.ts +3 -2
- package/dist/temporal-timeline-recall.d.ts +2 -1
- package/dist/temporal-validity.d.ts +2 -1
- package/dist/threading.d.ts +2 -1
- package/dist/tier-migration.d.ts +3 -2
- package/dist/tier-routing.d.ts +2 -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 +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/capsule-import.js +1 -1
- package/dist/transfer/export-okf.d.ts +2 -1
- package/dist/transfer/export-okf.js +29 -28
- package/dist/transfer/types.d.ts +102 -102
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/{types-YY-eKKU7.d.ts → types-BGxTvLBO.d.ts} +58 -13
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/verified-recall.js +28 -27
- package/dist/who-knows-cli.d.ts +13 -11
- package/dist/who-knows-cli.js +29 -28
- package/dist/who-knows.d.ts +13 -11
- package/dist/who-knows.js +28 -27
- package/dist/write-envelope.d.ts +4 -2
- package/dist/write-envelope.js +3 -1
- package/package.json +12 -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 +3 -1
- package/src/config.ts +4 -0
- 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.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 +7 -7
- package/src/write-envelope.ts +1 -1
- package/dist/chunk-22FVR2KE.js.map +0 -1
- package/dist/chunk-2JVJ7UHC.js.map +0 -1
- package/dist/chunk-3QQTXYZ6.js.map +0 -1
- package/dist/chunk-4UDQUPT5.js +0 -560
- package/dist/chunk-4UDQUPT5.js.map +0 -1
- package/dist/chunk-A7XEPMQ6.js.map +0 -1
- package/dist/chunk-AU7Q3LSC.js +0 -56
- package/dist/chunk-AU7Q3LSC.js.map +0 -1
- package/dist/chunk-BLUYQFRH.js.map +0 -1
- package/dist/chunk-CZYYJZB6.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-GVG3JYBI.js.map +0 -1
- package/dist/chunk-H272ZPQ3.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-N7RWREIQ.js.map +0 -1
- package/dist/chunk-O75CRYGF.js.map +0 -1
- package/dist/chunk-Q3O3VKRB.js.map +0 -1
- package/dist/chunk-SEDEKFYQ.js +0 -1
- package/dist/chunk-SO7SV523.js.map +0 -1
- package/dist/chunk-SQJ3SDIW.js.map +0 -1
- package/dist/chunk-TLPZ6MKZ.js.map +0 -1
- package/dist/chunk-WJBZMNNS.js.map +0 -1
- package/dist/chunk-XQ2Q43XD.js.map +0 -1
- package/dist/chunk-Z4PCVRTN.js.map +0 -1
- package/src/activity/journal-mode.test.ts +0 -32
- package/src/activity/journal-mode.ts +0 -20
- /package/dist/{chunk-SEDEKFYQ.js.map → activity/digest.js.map} +0 -0
- /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-IY2FVXM6.js.map → chunk-2AU4D4HQ.js.map} +0 -0
- /package/dist/{chunk-QDY6KYTN.js.map → chunk-2JCA2PQT.js.map} +0 -0
- /package/dist/{chunk-RSVEP77Y.js.map → chunk-2UZ5ZH6W.js.map} +0 -0
- /package/dist/{chunk-NWWXSJX5.js.map → chunk-34QW2LK2.js.map} +0 -0
- /package/dist/{chunk-S7DPKM5W.js.map → chunk-353C5UNV.js.map} +0 -0
- /package/dist/{chunk-GQOMZ3MK.js.map → chunk-36UBSLFN.js.map} +0 -0
- /package/dist/{chunk-DBQWVT2H.js.map → chunk-3CBI2ZSA.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-7VJXIDOC.js.map → chunk-4JVQRFZD.js.map} +0 -0
- /package/dist/{chunk-WHBVXTUI.js.map → chunk-4PB2MBY6.js.map} +0 -0
- /package/dist/{chunk-TEYN7ZYF.js.map → chunk-4WCNPQQ5.js.map} +0 -0
- /package/dist/{chunk-RBGREYVJ.js.map → chunk-5QBDLMGG.js.map} +0 -0
- /package/dist/{chunk-RKBLRTNT.js.map → chunk-5SDSVX7N.js.map} +0 -0
- /package/dist/{chunk-LPECRQO4.js.map → chunk-5THU7NFP.js.map} +0 -0
- /package/dist/{chunk-LWA7MDVO.js.map → chunk-6CCRSQWT.js.map} +0 -0
- /package/dist/{chunk-TIT2C6WX.js.map → chunk-6XYC7NM4.js.map} +0 -0
- /package/dist/{chunk-FHQSPTPZ.js.map → chunk-6YAIN5XJ.js.map} +0 -0
- /package/dist/{chunk-PV36INNL.js.map → chunk-757NP436.js.map} +0 -0
- /package/dist/{chunk-6H5JYDOM.js.map → chunk-7J2CGXG3.js.map} +0 -0
- /package/dist/{chunk-FBMYGNOC.js.map → chunk-A2YQL2FF.js.map} +0 -0
- /package/dist/{chunk-X2NFFBTO.js.map → chunk-A7GQBJP5.js.map} +0 -0
- /package/dist/{chunk-MPYD657E.js.map → chunk-A7WOWDZK.js.map} +0 -0
- /package/dist/{chunk-C4OTC6WY.js.map → chunk-AIKTQVV3.js.map} +0 -0
- /package/dist/{chunk-CGC5UQCF.js.map → chunk-AKE4GGQ3.js.map} +0 -0
- /package/dist/{chunk-VP67GZ7T.js.map → chunk-APFKZVJS.js.map} +0 -0
- /package/dist/{chunk-M75RYSHS.js.map → chunk-AQIRQUCP.js.map} +0 -0
- /package/dist/{chunk-S7T2TY65.js.map → chunk-AXFR2NQ5.js.map} +0 -0
- /package/dist/{chunk-PSPABFN2.js.map → chunk-BD7JTBYP.js.map} +0 -0
- /package/dist/{chunk-FCSZ4K2X.js.map → chunk-BJJWRWER.js.map} +0 -0
- /package/dist/{chunk-JT3EB7ZL.js.map → chunk-BNGHPYZU.js.map} +0 -0
- /package/dist/{chunk-MFJBANPX.js.map → chunk-C2BFTYD7.js.map} +0 -0
- /package/dist/{chunk-3JVLGJCY.js.map → chunk-C6KRO3SU.js.map} +0 -0
- /package/dist/{chunk-AOCP6JA7.js.map → chunk-D3IZCN5P.js.map} +0 -0
- /package/dist/{chunk-ROKKIMON.js.map → chunk-EJIEQOPB.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-DD5JFCWM.js.map → chunk-GCBIXUPT.js.map} +0 -0
- /package/dist/{chunk-ROGRI25A.js.map → chunk-I3H5LFOI.js.map} +0 -0
- /package/dist/{chunk-S65WXHNK.js.map → chunk-IFFLUCCU.js.map} +0 -0
- /package/dist/{chunk-D5LORF7A.js.map → chunk-JZDH2ZZK.js.map} +0 -0
- /package/dist/{chunk-2GPE5UCR.js.map → chunk-K6IPSW5B.js.map} +0 -0
- /package/dist/{chunk-HG6HXVHQ.js.map → chunk-KDJHLOZP.js.map} +0 -0
- /package/dist/{chunk-I27RSQRR.js.map → chunk-KYGOQV37.js.map} +0 -0
- /package/dist/{chunk-VZWXFXLX.js.map → chunk-LMCD5W5B.js.map} +0 -0
- /package/dist/{chunk-MKD3OMPS.js.map → chunk-M3MYMWXG.js.map} +0 -0
- /package/dist/{chunk-DITMGZOL.js.map → chunk-MMG5K6XJ.js.map} +0 -0
- /package/dist/{chunk-VGXM5B4H.js.map → chunk-MNIPH6LD.js.map} +0 -0
- /package/dist/{chunk-MKWKYHXJ.js.map → chunk-OB3XMWX5.js.map} +0 -0
- /package/dist/{chunk-XU6OEECT.js.map → chunk-OQQXGYMX.js.map} +0 -0
- /package/dist/{chunk-47DEYNMR.js.map → chunk-PEXW2JCK.js.map} +0 -0
- /package/dist/{chunk-42SDNZCU.js.map → chunk-QF4J3KMV.js.map} +0 -0
- /package/dist/{chunk-SB6PSOP7.js.map → chunk-QLJ6762U.js.map} +0 -0
- /package/dist/{chunk-XOVKXJEP.js.map → chunk-R3TLVTWW.js.map} +0 -0
- /package/dist/{chunk-PHNAB54Q.js.map → chunk-RQO3J4MR.js.map} +0 -0
- /package/dist/{chunk-5N53UBH2.js.map → chunk-RR7G2X7C.js.map} +0 -0
- /package/dist/{chunk-DCJ3YFIC.js.map → chunk-S2ULTQZR.js.map} +0 -0
- /package/dist/{chunk-GY5WZBA6.js.map → chunk-S76KRJDG.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-QMGXMJ2O.js.map → chunk-T2YFZ27G.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-TFA6HPOA.js.map} +0 -0
- /package/dist/{chunk-BA6WOZOT.js.map → chunk-TK4FHQRN.js.map} +0 -0
- /package/dist/{chunk-ZNJSBIP4.js.map → chunk-TNSCIPBQ.js.map} +0 -0
- /package/dist/{chunk-YUMDFDUA.js.map → chunk-TWYTGIBR.js.map} +0 -0
- /package/dist/{chunk-EZZV7OQL.js.map → chunk-UEZKN6VR.js.map} +0 -0
- /package/dist/{chunk-HY55QQD7.js.map → chunk-UJX4I26O.js.map} +0 -0
- /package/dist/{chunk-CBCNKKZD.js.map → chunk-VIZR45AN.js.map} +0 -0
- /package/dist/{chunk-ZG74PWRW.js.map → chunk-VZAKYDMJ.js.map} +0 -0
- /package/dist/{chunk-ITPS5DDH.js.map → chunk-W5BLTZZJ.js.map} +0 -0
- /package/dist/{chunk-H3TKENU4.js.map → chunk-WIKO4SCR.js.map} +0 -0
- /package/dist/{chunk-YFLLGRXO.js.map → chunk-X2QPKLPL.js.map} +0 -0
- /package/dist/{chunk-FGGYSN4P.js.map → chunk-X424T5JQ.js.map} +0 -0
- /package/dist/{chunk-NAXDPKVM.js.map → chunk-XPJNT6PI.js.map} +0 -0
- /package/dist/{contradiction-scan-NOYMFG66.js.map → chunk-XW2T4QAW.js.map} +0 -0
- /package/dist/{chunk-VED2YHUD.js.map → chunk-YEDVOYL2.js.map} +0 -0
- /package/dist/{chunk-RC5DXXWC.js.map → chunk-YM7YN37H.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-565C6ZFO.js.map → chunk-Z7YDVHDI.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/{resolution-VKATP2HT.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/{tier-stats-KA6OZX2C.js.map → tier-stats-VK5PCO2L.js.map} +0 -0
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, open, readFile, rename, unlink, type FileHandle } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveSafeStoragePath } from "../storage-paths.js";
|
|
5
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
6
|
+
import { withHeldFileLock, type HeldFileLockController } from "../utils/serialize-mutations.js";
|
|
7
|
+
import { log } from "../logger.js";
|
|
8
|
+
import { isValidManagedStoragePath, nextCasRevisionIso } from "./deletion-revision-store.js";
|
|
9
|
+
|
|
10
|
+
type CasRevisionShard = {
|
|
11
|
+
version: 1;
|
|
12
|
+
path: string;
|
|
13
|
+
revision: string;
|
|
14
|
+
/** Two-phase receipt state (#2813 P1 C). Absent on pre-two-phase shards,
|
|
15
|
+
* which read as committed. */
|
|
16
|
+
state?: "pending" | "committed";
|
|
17
|
+
/** The standing COMMITTED token the pending reservation replaced. An
|
|
18
|
+
* abort restores it, so a discarded reservation never erases the
|
|
19
|
+
* target's receipt history. */
|
|
20
|
+
previous?: string;
|
|
21
|
+
/** #2807 crash-recovery evidence, pending markers only. sha256 of the
|
|
22
|
+
* durable memory file's BYTES — a fingerprint, never memory content.
|
|
23
|
+
* `baselineDigest` is the fingerprint captured at reserve time; null
|
|
24
|
+
* means the file was absent. Absent on legacy pending markers, which
|
|
25
|
+
* carry no evidence. */
|
|
26
|
+
baselineDigest?: string | null;
|
|
27
|
+
/** #2807: the fingerprint the durable file shows once the reserved
|
|
28
|
+
* write has landed; recorded by `writeLanded` before `commit` publishes.
|
|
29
|
+
* null means the file was absent when the write landed. May also be
|
|
30
|
+
* pre-recorded at reserve from the caller's expected bytes. */
|
|
31
|
+
expectedDigest?: string | null;
|
|
32
|
+
/** True after `writeLanded()` verifies the durable write. New pending
|
|
33
|
+
* markers write false. Absent on legacy pending shards: those treat
|
|
34
|
+
* a present `expectedDigest` as already landed. */
|
|
35
|
+
writeLanded?: boolean;
|
|
36
|
+
/** #2813 (P1 B): sha256 hex digest of the durable memory file when committed. */
|
|
37
|
+
committedDigest?: string | null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type CasRevisionMetadata = {
|
|
41
|
+
version: 1;
|
|
42
|
+
revisions: Array<{ path: string; revision: string }>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** #2813 (P1 A): truthful outcome of a standing-receipt read.
|
|
46
|
+
* - `present` — the target's standing receipt token.
|
|
47
|
+
* - `absent` — no receipt was ever minted (a pre-sidecar legacy record, or
|
|
48
|
+
* a fresh target); `undefined` semantics stay correct for those.
|
|
49
|
+
* - `unavailable` — the sidecar could not be read (unreadable, unsafe, or
|
|
50
|
+
* PENDING finalization), so receipt identity is UNKNOWN. The fail-open
|
|
51
|
+
* `readRevision` collapses this into `undefined`; callers that transact
|
|
52
|
+
* on receipt identity MUST refuse instead. */
|
|
53
|
+
export type CasRevisionReadStatus =
|
|
54
|
+
| { status: "present"; revision: string; committedDigest?: string }
|
|
55
|
+
| { status: "absent" }
|
|
56
|
+
| { status: "unavailable"; reason: string };
|
|
57
|
+
|
|
58
|
+
/** #2813 (P1 C): a write-ahead receipt transaction. `pendingRevision` is a
|
|
59
|
+
* RESERVATION, never ownership: no reader may attribute the record from it
|
|
60
|
+
* while the marker is pending. `commit` publishes the COMMITTED receipt
|
|
61
|
+
* after the durable memory write lands; `abort` discards the reservation
|
|
62
|
+
* (restoring the previous standing token) when the write failed. If
|
|
63
|
+
* `commit` itself fails after the write, the pending marker REMAINS so
|
|
64
|
+
* readers report recovery-needed and promotion/rollback refuse until
|
|
65
|
+
* {@link CasRevisionStore.reconcilePendingRevision} runs with the known
|
|
66
|
+
* write outcome or {@link CasRevisionStore.recoverPendingRevision} decides
|
|
67
|
+
* from the recorded evidence (#2807). */
|
|
68
|
+
export interface CasRevisionTransaction {
|
|
69
|
+
readonly pendingRevision: string;
|
|
70
|
+
/** #2807: record the durable file's post-write fingerprint in the
|
|
71
|
+
* PENDING marker — the crash evidence recovery compares. Call immediately
|
|
72
|
+
* after the durable write lands, before `commit`. */
|
|
73
|
+
writeLanded(): Promise<void>;
|
|
74
|
+
commit(): Promise<void>;
|
|
75
|
+
abort(): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type CasShardView =
|
|
79
|
+
| { kind: "missing" }
|
|
80
|
+
| { kind: "foreign" }
|
|
81
|
+
| { kind: "committed"; revision: string; committedDigest?: string; foreign: boolean }
|
|
82
|
+
| {
|
|
83
|
+
kind: "pending";
|
|
84
|
+
revision: string;
|
|
85
|
+
previous?: string;
|
|
86
|
+
foreign: boolean;
|
|
87
|
+
baselineDigest?: string | null;
|
|
88
|
+
expectedDigest?: string | null;
|
|
89
|
+
writeLanded?: boolean;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const CAS_REVISION_LOCK_STALE_MS = 60_000;
|
|
93
|
+
const CAS_REVISION_LOCK_MAX_WAIT_MS = 120_000;
|
|
94
|
+
const SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
95
|
+
|
|
96
|
+
function isDigestOrNullOrUndefined(value: unknown): boolean {
|
|
97
|
+
if (value === undefined || value === null) return true;
|
|
98
|
+
return typeof value === "string" && SHA256_HEX.test(value);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function pendingWriteHasLanded(view: {
|
|
102
|
+
writeLanded?: boolean;
|
|
103
|
+
expectedDigest?: string | null;
|
|
104
|
+
}): boolean {
|
|
105
|
+
if (view.writeLanded === true) return true;
|
|
106
|
+
if (view.writeLanded === false) return false;
|
|
107
|
+
return view.expectedDigest !== undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* #2813 (P1, #2807 CI repair): durable per-target CAS receipt identity,
|
|
113
|
+
* SEPARATE from public `frontmatter.updated` (business/event time — the
|
|
114
|
+
* support-passport contract keeps caller values verbatim). A receipt minted
|
|
115
|
+
* here is unique and strictly monotonic per target across content commits
|
|
116
|
+
* and semantic frontmatter writes; rollback ownership compares ONLY this
|
|
117
|
+
* token. Attribution scope is per-path in-process serialization (the
|
|
118
|
+
* capture locks around every CAS); the memory files themselves carry no
|
|
119
|
+
* cross-process write lock, so a cross-process same-path race keeps the
|
|
120
|
+
* last-write-wins outcome the corpus already has.
|
|
121
|
+
*
|
|
122
|
+
* Receipts publish through a TWO-PHASE transaction (#2813 P1 C), because
|
|
123
|
+
* neither single-phase ordering is safe: mint-before-write publishes
|
|
124
|
+
* ownership for a write that can still fail, and mint-after-write leaves a
|
|
125
|
+
* written record with no receipt. Under the per-target shard lock:
|
|
126
|
+
* 1. reserve — the next token is minted and durably recorded as a
|
|
127
|
+
* PENDING marker (write-ahead), carrying the standing token it
|
|
128
|
+
* replaced;
|
|
129
|
+
* 2. write — the caller performs the durable memory write;
|
|
130
|
+
* 3. publish — the marker is atomically rewritten COMMITTED.
|
|
131
|
+
* A failed write aborts the reservation (restoring the previous token); a
|
|
132
|
+
* failed publish leaves the PENDING marker standing, which readers must
|
|
133
|
+
* treat as unavailable/recovery-needed — never ownership, never absence —
|
|
134
|
+
* so promotion and rollback refuse until recovery reconciles.
|
|
135
|
+
*
|
|
136
|
+
* Every sidecar path (shard, lock, temporary) is resolved through
|
|
137
|
+
* {@link resolveSafeStoragePath} (#2813 P1 A): a symlinked
|
|
138
|
+
* `.offline-sync/cas-revisions` directory — or any symlinked ancestor that
|
|
139
|
+
* escapes the memory root — is rejected before any lock, read, rename, or
|
|
140
|
+
* unlink, so sidecar traffic can never be redirected outside the root.
|
|
141
|
+
*/
|
|
142
|
+
export class CasRevisionStore {
|
|
143
|
+
private readonly baseDir: string;
|
|
144
|
+
private readonly legacyMetadataPath: string;
|
|
145
|
+
|
|
146
|
+
constructor(baseDir: string) {
|
|
147
|
+
this.baseDir = baseDir;
|
|
148
|
+
// Legacy global metadata location for backward-compatible fallback reads.
|
|
149
|
+
this.legacyMetadataPath = path.join(baseDir, ".offline-sync", "cas-revisions.v1.json");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private parseCasRevisionMetadata(raw: string): Map<string, string> {
|
|
153
|
+
let parsed: unknown;
|
|
154
|
+
try {
|
|
155
|
+
parsed = JSON.parse(raw);
|
|
156
|
+
} catch {
|
|
157
|
+
throw new Error("CAS revision metadata is invalid.");
|
|
158
|
+
}
|
|
159
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
160
|
+
throw new Error("CAS revision metadata is invalid.");
|
|
161
|
+
}
|
|
162
|
+
const root = parsed as Record<string, unknown>;
|
|
163
|
+
if (
|
|
164
|
+
Object.keys(root).sort().join(",") !== "revisions,version" ||
|
|
165
|
+
root.version !== 1 ||
|
|
166
|
+
!Array.isArray(root.revisions)
|
|
167
|
+
) {
|
|
168
|
+
throw new Error("CAS revision metadata is invalid.");
|
|
169
|
+
}
|
|
170
|
+
const revisions = new Map<string, string>();
|
|
171
|
+
for (const rawEntry of root.revisions) {
|
|
172
|
+
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
|
|
173
|
+
throw new Error("CAS revision metadata is invalid.");
|
|
174
|
+
}
|
|
175
|
+
const entry = rawEntry as Record<string, unknown>;
|
|
176
|
+
if (
|
|
177
|
+
Object.keys(entry).sort().join(",") !== "path,revision" ||
|
|
178
|
+
typeof entry.path !== "string" ||
|
|
179
|
+
!isValidManagedStoragePath(entry.path) ||
|
|
180
|
+
typeof entry.revision !== "string" ||
|
|
181
|
+
entry.revision.length === 0 ||
|
|
182
|
+
revisions.has(entry.path)
|
|
183
|
+
) {
|
|
184
|
+
throw new Error("CAS revision metadata is invalid.");
|
|
185
|
+
}
|
|
186
|
+
revisions.set(entry.path, entry.revision);
|
|
187
|
+
}
|
|
188
|
+
return revisions;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private async readLegacyMetadata(): Promise<Map<string, string>> {
|
|
192
|
+
const baseDir = path.resolve(this.baseDir);
|
|
193
|
+
const legacyPath = await resolveSafeStoragePath(baseDir, path.relative(baseDir, this.legacyMetadataPath));
|
|
194
|
+
let raw: string;
|
|
195
|
+
try {
|
|
196
|
+
raw = await readFile(legacyPath, "utf8");
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (isErrnoCode(error, "ENOENT")) return new Map();
|
|
199
|
+
throw new Error("CAS revision metadata is unavailable.");
|
|
200
|
+
}
|
|
201
|
+
return this.parseCasRevisionMetadata(raw);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** #2813 (P1 A): every sidecar path is resolved (and symlink-audited)
|
|
205
|
+
* inside the memory root before it is used for a lock, read, rename, or
|
|
206
|
+
* unlink. A symlinked `.offline-sync`, `.offline-sync/cas-revisions`, or
|
|
207
|
+
* shard file makes this throw, so no sidecar traffic can follow a link
|
|
208
|
+
* out of the root. */
|
|
209
|
+
private async getSafeShardInfo(relativePath: string): Promise<{ shardPath: string; lockPath: string }> {
|
|
210
|
+
const baseDir = path.resolve(this.baseDir);
|
|
211
|
+
const hash = createHash("sha256").update(relativePath).digest("hex");
|
|
212
|
+
const shardPath = await resolveSafeStoragePath(baseDir, ".offline-sync", "cas-revisions", `${hash}.json`);
|
|
213
|
+
const lockPath = await resolveSafeStoragePath(baseDir, ".offline-sync", "cas-revisions", `${hash}.json.lock`);
|
|
214
|
+
return { shardPath, lockPath };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private async readShardView(shardPath: string, relativePath: string): Promise<CasShardView> {
|
|
218
|
+
let raw: string;
|
|
219
|
+
try {
|
|
220
|
+
raw = await readFile(shardPath, "utf8");
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (isErrnoCode(error, "ENOENT")) return { kind: "missing" };
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
let parsed: unknown;
|
|
226
|
+
try {
|
|
227
|
+
parsed = JSON.parse(raw);
|
|
228
|
+
} catch {
|
|
229
|
+
throw new Error("CAS revision shard is unreadable.");
|
|
230
|
+
}
|
|
231
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
232
|
+
return { kind: "foreign" };
|
|
233
|
+
}
|
|
234
|
+
const root = parsed as Record<string, unknown>;
|
|
235
|
+
if (root.state !== undefined) {
|
|
236
|
+
// Two-phase shard: strict shape. A state-bearing shard that does not
|
|
237
|
+
// validate is corruption — unavailability, never a usable identity.
|
|
238
|
+
if (
|
|
239
|
+
root.version !== 1 ||
|
|
240
|
+
typeof root.path !== "string" ||
|
|
241
|
+
typeof root.revision !== "string" ||
|
|
242
|
+
root.revision.length === 0 ||
|
|
243
|
+
(root.state !== "pending" && root.state !== "committed") ||
|
|
244
|
+
(root.previous !== undefined &&
|
|
245
|
+
(typeof root.previous !== "string" || root.previous.length === 0)) ||
|
|
246
|
+
!isDigestOrNullOrUndefined(root.baselineDigest) ||
|
|
247
|
+
!isDigestOrNullOrUndefined(root.expectedDigest) ||
|
|
248
|
+
(root.writeLanded !== undefined && typeof root.writeLanded !== "boolean")
|
|
249
|
+
) {
|
|
250
|
+
throw new Error("CAS revision shard is unreadable.");
|
|
251
|
+
}
|
|
252
|
+
const foreign = root.path !== relativePath;
|
|
253
|
+
const committedDigest =
|
|
254
|
+
typeof root.committedDigest === "string" ? root.committedDigest : undefined;
|
|
255
|
+
return root.state === "pending"
|
|
256
|
+
? {
|
|
257
|
+
kind: "pending",
|
|
258
|
+
revision: root.revision,
|
|
259
|
+
previous: root.previous,
|
|
260
|
+
foreign,
|
|
261
|
+
baselineDigest: root.baselineDigest as string | null | undefined,
|
|
262
|
+
expectedDigest: root.expectedDigest as string | null | undefined,
|
|
263
|
+
...(typeof root.writeLanded === "boolean" ? { writeLanded: root.writeLanded } : {}),
|
|
264
|
+
}
|
|
265
|
+
: { kind: "committed", revision: root.revision, committedDigest, foreign };
|
|
266
|
+
}
|
|
267
|
+
// Pre-two-phase shard: a full-shape match reads as committed; anything
|
|
268
|
+
// else keeps the legacy fall-through (legacy metadata, then absence).
|
|
269
|
+
if (
|
|
270
|
+
root.version === 1 &&
|
|
271
|
+
root.path === relativePath &&
|
|
272
|
+
typeof root.revision === "string" &&
|
|
273
|
+
root.revision.length > 0
|
|
274
|
+
) {
|
|
275
|
+
const committedDigest =
|
|
276
|
+
typeof root.committedDigest === "string" ? root.committedDigest : undefined;
|
|
277
|
+
return { kind: "committed", revision: root.revision, committedDigest, foreign: false };
|
|
278
|
+
}
|
|
279
|
+
return { kind: "foreign" };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private async readStandingRevision(relativePath: string): Promise<string | undefined> {
|
|
283
|
+
try {
|
|
284
|
+
return (await this.readStandingRevisionStrict(relativePath))?.revision;
|
|
285
|
+
} catch (error) {
|
|
286
|
+
log.warn(`CasRevisionStore failed to read standing revision for ${relativePath}: ${error}`);
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** #2813 (P1 A): strict core of {@link readStandingRevision}. Returns
|
|
292
|
+
* undefined ONLY when no receipt exists for the target — the shard is
|
|
293
|
+
* absent (or names another target) and the legacy metadata holds no
|
|
294
|
+
* entry. THROWS when the standing receipt cannot be determined: an
|
|
295
|
+
* unreadable or corrupt shard, a PENDING reservation awaiting
|
|
296
|
+
* finalization or recovery, or unreadable or invalid legacy metadata.
|
|
297
|
+
* Fail-open callers collapse the throw into undefined; truthful callers
|
|
298
|
+
* ({@link readRevisionStatus}) report `unavailable` so a transaction can
|
|
299
|
+
* refuse instead of mistaking the failure for absence. */
|
|
300
|
+
private async readStandingRevisionStrict(
|
|
301
|
+
relativePath: string,
|
|
302
|
+
): Promise<{ revision: string; committedDigest?: string } | undefined> {
|
|
303
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
304
|
+
const view = await this.readShardView(shardPath, relativePath);
|
|
305
|
+
if (view.kind === "pending") {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`CAS revision receipt for ${relativePath} is pending finalization (recovery needed).`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
if (view.kind === "committed" && !view.foreign) {
|
|
311
|
+
return { revision: view.revision, committedDigest: view.committedDigest };
|
|
312
|
+
}
|
|
313
|
+
const legacyMap = await this.readLegacyMetadata();
|
|
314
|
+
const legacyRev = legacyMap.get(relativePath);
|
|
315
|
+
return legacyRev === undefined ? undefined : { revision: legacyRev };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private async writeShard(
|
|
319
|
+
shardPath: string,
|
|
320
|
+
relativePath: string,
|
|
321
|
+
revision: string,
|
|
322
|
+
lock: HeldFileLockController,
|
|
323
|
+
state: "pending" | "committed",
|
|
324
|
+
previous?: string,
|
|
325
|
+
evidence?: {
|
|
326
|
+
baselineDigest?: string | null;
|
|
327
|
+
expectedDigest?: string | null;
|
|
328
|
+
committedDigest?: string | null;
|
|
329
|
+
writeLanded?: boolean;
|
|
330
|
+
},
|
|
331
|
+
): Promise<void> {
|
|
332
|
+
let payload: CasRevisionShard;
|
|
333
|
+
if (state === "committed") {
|
|
334
|
+
payload = { version: 1, path: relativePath, revision, state };
|
|
335
|
+
if (evidence?.committedDigest !== undefined) {
|
|
336
|
+
payload.committedDigest = evidence.committedDigest;
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
payload = { version: 1, path: relativePath, revision, state };
|
|
340
|
+
if (previous !== undefined) payload.previous = previous;
|
|
341
|
+
if (evidence !== undefined) {
|
|
342
|
+
if (evidence.baselineDigest !== undefined) payload.baselineDigest = evidence.baselineDigest;
|
|
343
|
+
if (evidence.expectedDigest !== undefined) payload.expectedDigest = evidence.expectedDigest;
|
|
344
|
+
if (evidence.writeLanded !== undefined) payload.writeLanded = evidence.writeLanded;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const baseDir = path.resolve(this.baseDir);
|
|
348
|
+
const temporaryPath = await resolveSafeStoragePath(
|
|
349
|
+
baseDir,
|
|
350
|
+
path.relative(baseDir, `${shardPath}.${process.pid}.${randomUUID()}.tmp`),
|
|
351
|
+
);
|
|
352
|
+
let handle: FileHandle | null = null;
|
|
353
|
+
try {
|
|
354
|
+
await mkdir(path.dirname(shardPath), { recursive: true });
|
|
355
|
+
handle = await open(temporaryPath, "wx", 0o600);
|
|
356
|
+
await handle.writeFile(`${JSON.stringify(payload)}\n`, "utf8");
|
|
357
|
+
await handle.sync();
|
|
358
|
+
await handle.close();
|
|
359
|
+
handle = null;
|
|
360
|
+
if (!(await lock.refresh())) {
|
|
361
|
+
throw new Error("CAS revision shard lock was lost.");
|
|
362
|
+
}
|
|
363
|
+
await rename(temporaryPath, shardPath);
|
|
364
|
+
} finally {
|
|
365
|
+
if (handle !== null) {
|
|
366
|
+
await handle.close().catch((error: unknown) => {
|
|
367
|
+
log.warn("failed to close CAS revision shard temporary file", error);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
await unlink(temporaryPath).catch((error: unknown) => {
|
|
371
|
+
if (!isErrnoCode(error, "ENOENT")) {
|
|
372
|
+
log.warn("failed to clean up CAS revision shard temporary file", error);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
private async resolveRelativePath(filePath: string): Promise<string> {
|
|
379
|
+
const baseDir = path.resolve(this.baseDir);
|
|
380
|
+
const target = await resolveSafeStoragePath(baseDir, path.relative(baseDir, path.resolve(baseDir, filePath)));
|
|
381
|
+
return path.relative(baseDir, target).split(path.sep).join("/");
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private async withShardLock<T>(
|
|
385
|
+
relativePath: string,
|
|
386
|
+
task: (lock: HeldFileLockController) => Promise<T>,
|
|
387
|
+
): Promise<T> {
|
|
388
|
+
const { lockPath } = await this.getSafeShardInfo(relativePath);
|
|
389
|
+
return await withHeldFileLock(
|
|
390
|
+
lockPath,
|
|
391
|
+
{ staleMs: CAS_REVISION_LOCK_STALE_MS, maxWaitMs: CAS_REVISION_LOCK_MAX_WAIT_MS },
|
|
392
|
+
async (acquired, lock) => {
|
|
393
|
+
if (!acquired) throw new Error("CAS revision lock is unavailable.");
|
|
394
|
+
return await task(lock);
|
|
395
|
+
},
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/** The target's standing revision token, or undefined when no receipt was
|
|
400
|
+
* ever minted for it. Fail-open on storage/read errors. */
|
|
401
|
+
async readRevision(filePath: string): Promise<string | undefined> {
|
|
402
|
+
try {
|
|
403
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
404
|
+
return await this.readStandingRevision(relativePath);
|
|
405
|
+
} catch (error) {
|
|
406
|
+
log.warn(`CasRevisionStore.readRevision failed for ${filePath}: ${error}`);
|
|
407
|
+
return undefined;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/** #2813 (P1 A): the truthful standing-receipt read. `absent` means no
|
|
412
|
+
* receipt was ever minted for the target — undefined semantics stay
|
|
413
|
+
* correct for those records. `unavailable` means the sidecar could not
|
|
414
|
+
* be read OR a reservation is pending finalization; callers that
|
|
415
|
+
* transact on receipt identity MUST refuse rather than treat the
|
|
416
|
+
* failure as absence. */
|
|
417
|
+
async readRevisionStatus(filePath: string): Promise<CasRevisionReadStatus> {
|
|
418
|
+
try {
|
|
419
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
420
|
+
const standing = await this.readStandingRevisionStrict(relativePath);
|
|
421
|
+
return standing === undefined
|
|
422
|
+
? { status: "absent" }
|
|
423
|
+
: {
|
|
424
|
+
status: "present",
|
|
425
|
+
revision: standing.revision,
|
|
426
|
+
...(standing.committedDigest !== undefined
|
|
427
|
+
? { committedDigest: standing.committedDigest }
|
|
428
|
+
: {}),
|
|
429
|
+
};
|
|
430
|
+
} catch (error) {
|
|
431
|
+
return { status: "unavailable", reason: error instanceof Error ? error.message : String(error) };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/** #2813 (P1 C): reserve the NEXT revision token as a durable PENDING
|
|
436
|
+
* marker under the target's shard lock — the write-ahead record of a
|
|
437
|
+
* receipt transaction. The token is strictly greater than the standing
|
|
438
|
+
* token (max(clock, prev + 1ms)), so two commits can never share a
|
|
439
|
+
* receipt — not within one millisecond, not across a backward clock
|
|
440
|
+
* step. Refuses while another reservation is pending (recovery needed)
|
|
441
|
+
* or the standing receipt cannot be determined. The caller MUST either
|
|
442
|
+
* `commit` after its durable write lands or `abort` when it fails.
|
|
443
|
+
* #2807: the marker records the reserve-time fingerprint (`baselineDigest`)
|
|
444
|
+
* and optional expected post-write fingerprint (`expectedDigest`) with
|
|
445
|
+
* `writeLanded: false`. {@link recoverPendingRevision} decides crashes
|
|
446
|
+
* before or after the memory write from that evidence. */
|
|
447
|
+
async beginRevisionTransaction(
|
|
448
|
+
filePath: string,
|
|
449
|
+
expectedContent?: string | Buffer | null,
|
|
450
|
+
): Promise<CasRevisionTransaction> {
|
|
451
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
452
|
+
return await this.withShardLock(relativePath, async (lock) => {
|
|
453
|
+
const standingInfo = await this.readStandingRevisionStrict(relativePath);
|
|
454
|
+
const standing = standingInfo?.revision;
|
|
455
|
+
const next = nextCasRevisionIso(standing);
|
|
456
|
+
const baselineDigest = await this.digestDurableFile(relativePath);
|
|
457
|
+
const expectedDigest =
|
|
458
|
+
expectedContent != null ? this.digestContent(expectedContent) : undefined;
|
|
459
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
460
|
+
await this.writeShard(shardPath, relativePath, next, lock, "pending", standing, {
|
|
461
|
+
baselineDigest,
|
|
462
|
+
...(expectedDigest !== undefined ? { expectedDigest } : {}),
|
|
463
|
+
writeLanded: false,
|
|
464
|
+
});
|
|
465
|
+
return {
|
|
466
|
+
pendingRevision: next,
|
|
467
|
+
writeLanded: () => this.recordPendingWriteLanded(relativePath, next),
|
|
468
|
+
commit: () => this.finalizeRevisionTransaction(relativePath, next, "commit"),
|
|
469
|
+
abort: () => this.finalizeRevisionTransaction(relativePath, next, "abort"),
|
|
470
|
+
};
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
public digestContent(content: string | Buffer): string {
|
|
475
|
+
const bytes = typeof content === "string" ? Buffer.from(content, "utf8") : content;
|
|
476
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
public async digestDurableFile(filePath: string): Promise<string | null> {
|
|
480
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
481
|
+
const baseDir = path.resolve(this.baseDir);
|
|
482
|
+
const target = await resolveSafeStoragePath(baseDir, relativePath);
|
|
483
|
+
let bytes: Buffer;
|
|
484
|
+
try {
|
|
485
|
+
bytes = await readFile(target);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
if (isErrnoCode(error, "ENOENT")) return null;
|
|
488
|
+
throw new Error(
|
|
489
|
+
`CAS revision evidence: durable memory file ${relativePath} is unreadable: ${error instanceof Error ? error.message : String(error)}`,
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/** #2807: mark the reserved write as landed. Verifies a pre-recorded
|
|
496
|
+
* expected digest against the durable file, or records the file digest
|
|
497
|
+
* when none was reserved. Sets `writeLanded: true`. Idempotent. */
|
|
498
|
+
private async recordPendingWriteLanded(relativePath: string, token: string): Promise<void> {
|
|
499
|
+
await this.withShardLock(relativePath, async (lock) => {
|
|
500
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
501
|
+
const view = await this.readShardView(shardPath, relativePath);
|
|
502
|
+
if (view.kind !== "pending" || view.foreign || view.revision !== token) {
|
|
503
|
+
throw new Error(
|
|
504
|
+
`CAS revision evidence recording refused for ${relativePath}: the pending marker does not match the reserved token.`,
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
if (pendingWriteHasLanded(view) && view.writeLanded !== false) return;
|
|
508
|
+
const currentDigest = await this.digestDurableFile(relativePath);
|
|
509
|
+
if (view.expectedDigest !== undefined && currentDigest !== view.expectedDigest) {
|
|
510
|
+
throw new Error(
|
|
511
|
+
`CAS revision evidence recording refused for ${relativePath}: the durable file does not match the reserved expected digest.`,
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
await this.writeShard(shardPath, relativePath, token, lock, "pending", view.previous, {
|
|
515
|
+
baselineDigest: view.baselineDigest === undefined ? null : view.baselineDigest,
|
|
516
|
+
expectedDigest: view.expectedDigest !== undefined ? view.expectedDigest : currentDigest,
|
|
517
|
+
writeLanded: true,
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
private async finalizeRevisionTransaction(
|
|
523
|
+
relativePath: string,
|
|
524
|
+
token: string,
|
|
525
|
+
outcome: "commit" | "abort",
|
|
526
|
+
): Promise<void> {
|
|
527
|
+
await this.withShardLock(relativePath, async (lock) => {
|
|
528
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
529
|
+
const view = await this.readShardView(shardPath, relativePath);
|
|
530
|
+
if (view.kind === "pending" && !view.foreign && view.revision === token) {
|
|
531
|
+
if (outcome === "commit") {
|
|
532
|
+
const committedDigest =
|
|
533
|
+
view.expectedDigest ?? (await this.digestDurableFile(relativePath));
|
|
534
|
+
await this.writeShard(shardPath, relativePath, token, lock, "committed", undefined, {
|
|
535
|
+
committedDigest,
|
|
536
|
+
});
|
|
537
|
+
} else if (view.previous !== undefined) {
|
|
538
|
+
await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
|
|
539
|
+
} else {
|
|
540
|
+
await unlink(shardPath);
|
|
541
|
+
}
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
if (outcome === "commit" && view.kind === "committed" && !view.foreign && view.revision === token) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
if (outcome === "abort" && view.kind === "missing") {
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
throw new Error(
|
|
551
|
+
`CAS revision transaction ${outcome} refused for ${relativePath}: the pending marker does not match the reserved token.`,
|
|
552
|
+
);
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/** #2813 (P1 C): recovery for a reservation left PENDING by a crash or a
|
|
557
|
+
* failed publication. The caller supplies the KNOWN outcome of the
|
|
558
|
+
* durable memory write: `fileWriteLanded` publishes the pending token as
|
|
559
|
+
* the COMMITTED receipt; otherwise the reservation is discarded and the
|
|
560
|
+
* previous standing token restored. Idempotent — an already-committed or
|
|
561
|
+
* absent shard is reported, not mutated. */
|
|
562
|
+
async reconcilePendingRevision(
|
|
563
|
+
filePath: string,
|
|
564
|
+
fileWriteLanded: boolean,
|
|
565
|
+
): Promise<"reconciled" | "committed" | "absent"> {
|
|
566
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
567
|
+
return await this.withShardLock(relativePath, async (lock) => {
|
|
568
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
569
|
+
const view = await this.readShardView(shardPath, relativePath);
|
|
570
|
+
if (view.kind === "committed") return "committed";
|
|
571
|
+
if (view.kind !== "pending") return "absent";
|
|
572
|
+
if (view.foreign) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`CAS revision pending marker for ${relativePath} names another target; manual recovery is required.`,
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
if (fileWriteLanded) {
|
|
578
|
+
const committedDigest =
|
|
579
|
+
view.expectedDigest ?? (await this.digestDurableFile(relativePath));
|
|
580
|
+
await this.writeShard(shardPath, relativePath, view.revision, lock, "committed", undefined, {
|
|
581
|
+
committedDigest,
|
|
582
|
+
});
|
|
583
|
+
} else if (view.previous !== undefined) {
|
|
584
|
+
await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
|
|
585
|
+
} else {
|
|
586
|
+
await unlink(shardPath);
|
|
587
|
+
}
|
|
588
|
+
return "reconciled";
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/** #2807 (P1): evidence-based recovery for a reservation left PENDING by
|
|
593
|
+
* a crash between reserve and finalize. Under the shard lock, the durable
|
|
594
|
+
* file's current fingerprint is compared against the marker:
|
|
595
|
+
* - matches `expectedDigest` → publish the pending token as COMMITTED;
|
|
596
|
+
* - matches `baselineDigest` (including both absent) → abort and restore;
|
|
597
|
+
* - anything else THROWS. Recovery never guesses.
|
|
598
|
+
*
|
|
599
|
+
* `onlyWithWriteEvidence` is the unlocked read path. A marker whose write
|
|
600
|
+
* has not landed (`writeLanded` false, or legacy with no expectedDigest)
|
|
601
|
+
* may belong to a live writer, so it returns `reserved`. A landed marker
|
|
602
|
+
* whose file no longer matches `expectedDigest` throws ambiguity. */
|
|
603
|
+
async recoverPendingRevision(
|
|
604
|
+
filePath: string,
|
|
605
|
+
options?: { onlyWithWriteEvidence?: boolean },
|
|
606
|
+
): Promise<"committed" | "aborted" | "absent" | "reserved"> {
|
|
607
|
+
const relativePath = await this.resolveRelativePath(filePath);
|
|
608
|
+
return await this.withShardLock(relativePath, async (lock) => {
|
|
609
|
+
const { shardPath } = await this.getSafeShardInfo(relativePath);
|
|
610
|
+
const view = await this.readShardView(shardPath, relativePath);
|
|
611
|
+
if (view.kind === "missing" || view.kind === "foreign") return "absent";
|
|
612
|
+
if (view.kind === "committed") return view.foreign ? "absent" : "committed";
|
|
613
|
+
if (view.foreign) {
|
|
614
|
+
throw new Error(
|
|
615
|
+
`CAS revision pending marker for ${relativePath} names another target; manual recovery is required.`,
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
const currentDigest = await this.digestDurableFile(relativePath);
|
|
619
|
+
const landed = pendingWriteHasLanded(view);
|
|
620
|
+
if (options?.onlyWithWriteEvidence && !landed) {
|
|
621
|
+
return "reserved";
|
|
622
|
+
}
|
|
623
|
+
if (view.expectedDigest !== undefined && currentDigest === view.expectedDigest) {
|
|
624
|
+
await this.writeShard(shardPath, relativePath, view.revision, lock, "committed", undefined, {
|
|
625
|
+
committedDigest: view.expectedDigest,
|
|
626
|
+
});
|
|
627
|
+
return "committed";
|
|
628
|
+
}
|
|
629
|
+
if (options?.onlyWithWriteEvidence) {
|
|
630
|
+
const evidence =
|
|
631
|
+
view.expectedDigest === undefined
|
|
632
|
+
? "the pending marker carries no crash evidence (written by an older version)"
|
|
633
|
+
: "the durable file matches neither the expected commit fingerprint nor the reserve-time baseline";
|
|
634
|
+
throw new Error(
|
|
635
|
+
`CAS revision recovery for ${relativePath} is ambiguous: ${evidence} (pending token ${view.revision}` +
|
|
636
|
+
`${view.previous !== undefined ? `, previous ${view.previous}` : ""}). ` +
|
|
637
|
+
`Inspect the durable file and the shard at ${shardPath}, then run ` +
|
|
638
|
+
`reconcilePendingRevision with the known write outcome. Refusing to guess.`,
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
if (view.baselineDigest !== undefined && currentDigest === view.baselineDigest) {
|
|
642
|
+
if (view.previous !== undefined) {
|
|
643
|
+
await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
|
|
644
|
+
} else {
|
|
645
|
+
await unlink(shardPath);
|
|
646
|
+
}
|
|
647
|
+
return "aborted";
|
|
648
|
+
}
|
|
649
|
+
const evidence =
|
|
650
|
+
view.baselineDigest === undefined && view.expectedDigest === undefined
|
|
651
|
+
? "the pending marker carries no crash evidence (written by an older version)"
|
|
652
|
+
: "the durable file matches neither the expected commit fingerprint nor the reserve-time baseline";
|
|
653
|
+
throw new Error(
|
|
654
|
+
`CAS revision recovery for ${relativePath} is ambiguous: ${evidence} (pending token ${view.revision}` +
|
|
655
|
+
`${view.previous !== undefined ? `, previous ${view.previous}` : ""}). ` +
|
|
656
|
+
`Inspect the durable file and the shard at ${shardPath}, then run ` +
|
|
657
|
+
`reconcilePendingRevision with the known write outcome. Refusing to guess.`,
|
|
658
|
+
);
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
}
|