chainlesschain 0.166.115 → 0.166.118
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/README.md +43 -5
- package/package.json +4 -4
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BsoSoDNb.js → AIOps-BGySwMIP.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Dcx7Gm5t.js → ActionButton-Chn7fBLr.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-S1hsBIz3.js → Analytics-ORH7UkGa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-B2j067qM.js → AppLayout-8xV4jWjP.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D5iGV9ic.js → Artifacts-26SBK-x-.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-C8ChVvXu.js → Audit-CtXpqbXg.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Cg97AAJS.js → BackgroundAgents-C5zLvQis.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CyxU9IUg.js → Backup-C93xY4vO.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CKlWjA8I.js → BaseInput-DpVCHfAn.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C-EqZza6.js → Chat-DM0LblR2.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BRFiXKPX.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-kkI13tSJ.js → Checkbox-BsAt3cKR.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-NlqEDwHK.js → Codegen-E_kp4KFd.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CfepEu79.js → Col-6msR3T6I.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BRo0qLXM.js → Community-PyX9c5D-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BMu8TP0E.js → Compact-7G1bVDSH.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-B7Q3Moef.js → Compliance-DcHN7GlD.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BVwt7Xmc.js → Cowork-WUIHJYDx.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CgBv20Qy.js → Cron-CWgCbptg.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CwcSBJk2.js → Crosschain-BzKZ6roD.js} +1 -1
- package/src/assets/web-panel/assets/{DID-d20rCiIm.js → DID-r7zxeItn.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-PpZaUYpS.js → Dashboard-D3pBiN2H.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DjsLdX_Z.js → Dropdown-C4otRJlZ.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CaPkrtxn.js → EmailListRenderer-CzDTC8lm.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-DDY8cQnE.js → EvolutionSettings-DGkXiIs-.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-VQavMjyj.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D0GvKQgI.js → Federation-dsI-xcpf.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Dl_TWHmb.js → FormItemContext-CEEb1fMR.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Bny2uagG.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B01KXq47.js → Git-CBwr2ZI3.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-F4c4Vwo1.js → Governance-D-Wy2Jjr.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-_025Q-8K.js → Inference-B4Yk_IRx.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DwbTmQb1.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CnNo0hCm.js → Logs-Ce1IiKAj.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-GND_8y0V.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Dkz5bv7F.js → Marketplace-CsIEByzK.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CBtRwDW_.js → McpTools-_DRzjcIn.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Y9jnyTb7.js → Memory-zvLpyi__.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Br1urkOz.js → MobileBridge-DXd1ik2Z.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DnsyuerX.js → MobileProjects-DKh2q-Y9.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-he3ZzieF.js → Mtc-Ct-fhtIx.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BadphAuN.js → MtcAudit-J4zY3Oqk.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-3_pVLymK.js → Multisig-B2HJMCKe.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DmtmHfsI.js → NLProgramming-CwcSmU4q.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CE4L2O55.js → Notes-Da53L6wb.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-B7QmfJn9.js → NotificationSettings-BxhufdrA.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-O0wRSyJ0.js → OrderTableRenderer-BoFwohAi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BrlMSsyT.js → Organization-MIsMrUes.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CY4ULPrZ.js → Overflow-Dy2P4v3q.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-kIANZYKd.js → P2P-CD9Sxn2y.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DEgB4rvF.js → PdhVaultBrowser-BvBWgfG0.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-CWxywRp5.js → Permissions-CwOlDRis.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DAg7iCbr.js → PersonalDataHub-CZYaxEpv.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-Brc6ONnR.js → Pipeline-kLU7PUbB.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CcinYTL8.js → Privacy-BVRycSiI.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bz8XEsom.js → ProjectInit-DP3pr7uJ.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CsOMlSTZ.js → ProjectSettings-CACaDYjs.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CB1k4zTC.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CeunOQiH.js → Providers-D7Y9WHRE.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CN2a2_Fb.js → QrScannerModal-CeP8xzs1.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CVeLif3e.js → QuickAsk-iJVFrhZ2.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-1k9WOEGM.js → Recommend-DmTpnagw.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Q8UCqIMw.js → RemoteSession-C6ek8Uni.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CkrCgXKM.js → Reputation-CPfwc9de.js} +1 -1
- package/src/assets/web-panel/assets/{Row-JFdvuTzi.js → Row-C1wwtSMJ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C74JHCmk.js → RssFeed-BiDJsqaH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DrJiVO1T.js → Search-BF6Aon95.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BJzNlSJq.js → Security-Bps0XnV4.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D4TLMnJm.js → Services-uf92smGR.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-cswTDqhh.js → Skeleton-DQd4eVWW.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Bv0rM1BS.js → Skills-DgamiYa5.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-D9rE7hNh.js → Sla-CF1IVIrm.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-Bzxmjbpc.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-BwnMG8kq.js → SyncSettings-B8zKauiq.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-wJvU24cB.js → Tasks-DPKV_xSt.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CZbRU3tN.js → Templates-BikeSZIF.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-_jbpFJPZ.js → Tenant-CEaUaDkJ.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BzNm5WKZ.js → Terminal-ZPgOSQ_q.js} +3 -3
- package/src/assets/web-panel/assets/{TimelineRenderer-bmybWjuS.js → TimelineRenderer-DmyB4Udk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-o1WDcqVQ.js → Tokens-g85Pm5TO.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BB1D6sIB.js → Trigger-D202hx9a.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CLxdCfy2.js → Trust-DzvQYVFy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B9LS6vS0.js → UkeySign-KRzwddVg.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bg0-wxjz.js → VideoEditing-IRBXLO2z.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Bw0G2F6P.js → Wallet-DSf5KPgQ.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-irEiNY9b.js → WebAuthn-DNPxLTCc.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-Bh08FbJs.js → WorkflowEditor-C3wAtVcK.js} +1 -1
- package/src/assets/web-panel/assets/{addon-fit-CK6X9sAG.js → addon-fit-CbkjSUJl.js} +1 -1
- package/src/assets/web-panel/assets/{chat-De-FPjVT.js → chat-q3XXUtv2.js} +1 -1
- package/src/assets/web-panel/assets/{colors-ygdyvinU.js → colors-CF54SNei.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BQ9jH9KV.js → compact-item-BaRkvZuT.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BFuVSyox.js → createContext-CDR9hsfs.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-1LO-NplX.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-i19GtR1P.js → hasIn-DlC--S8R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DS1IwwGL.js → index-B0Ptc7yu.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1IsP_JO.js → index-B0V9rgdu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWfgeaG4.js → index-BEiUlFKb.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTY20pWu.js → index-BJO0n1LQ.js} +1 -1
- package/src/assets/web-panel/assets/index-BLaJsev4.js +1 -0
- package/src/assets/web-panel/assets/index-BLmviChG.js +1 -0
- package/src/assets/web-panel/assets/{index-IXkif6J_.js → index-BU5DJqk7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVhtukYX.js → index-BY-Tf3OM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKlU5VZy.js → index-BZrE0Go8.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bw5pTpnI.js → index-BizdX2X5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGMxK155.js → index-C87Yr3h1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVnFgasM.js → index-C9Wypz9e.js} +1 -1
- package/src/assets/web-panel/assets/{index-C61w3omz.js → index-CAoG_E-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-l5-J0jHx.js → index-CAxSyMrF.js} +1 -1
- package/src/assets/web-panel/assets/{index-28DjsABm.js → index-CC5HjNM6.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPUCvc8i.js → index-CNZQEZ9g.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpdXhhMY.js → index-CPvIhha6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAboGZTw.js → index-CR_wqMGy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DL7ewjD2.js → index-CSClXoB3.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bhf-MuUh.js → index-CZ8azVgB.js} +3 -3
- package/src/assets/web-panel/assets/{index-BaaydJcC.js → index-Ccc5z8eJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2LieObB.js → index-CeiKbM3a.js} +1 -1
- package/src/assets/web-panel/assets/{index-We2nK3ju.js → index-Cl6av3X7.js} +1 -1
- package/src/assets/web-panel/assets/{index-m8waSAyv.js → index-CtGfeD7E.js} +1 -1
- package/src/assets/web-panel/assets/{index-cDJsyAkI.js → index-Ctid12Gq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlwxUZQL.js → index-D0H-N0uG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBYiCI1d.js → index-D0vIgprF.js} +1 -1
- package/src/assets/web-panel/assets/{index-_9tUBcLm.js → index-D4wUDFRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-4HoFz1MA.js → index-DJFipyK7.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cq9k4-Ws.js → index-DX2REKNp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuuOX5u3.js → index-Dc3gD0cw.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgjLaB7k.js → index-DiQzer2R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMNjaSir.js → index-DntKLOs9.js} +1 -1
- package/src/assets/web-panel/assets/{index-vXtH3o6O.js → index-Dplhl6gh.js} +1 -1
- package/src/assets/web-panel/assets/{index-BLMtCKAY.js → index-Dq8q_PWB.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXrk8OYO.js → index-IVQdOBNN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBVcGaxk.js → index-Kerduyao.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKblSCL9.js → index-W6cLGjpW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgoSgmjK.js → index-qZDNFll9.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B_EZHeqN.js → initDefaultProps-Ccz7v71u.js} +1 -1
- package/src/assets/web-panel/assets/{markdown-Yo_c6Krv.js → markdown-Bq2x0XsR.js} +1 -1
- package/src/assets/web-panel/assets/markdown-DUKxbhE4.js +51 -0
- package/src/assets/web-panel/assets/{motion-BrVb_Gy1.js → motion-BlCLpVDp.js} +1 -1
- package/src/assets/web-panel/assets/{move-CKxVRL_J.js → move-B80G7fLU.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C80rvQ1J.js → mtc-parser-Djw08NJh.js} +1 -1
- package/src/assets/web-panel/assets/{omit-De5vD7BR.js → omit-Bg_G1eUr.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BTyEDjth.js → pickAttrs-Df9zYUg2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BWR94AjR.js → placementArrow-DjCDLhJ4.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-1g-Vnibk.js → responsiveObserve--Naz7NgY.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Dmg6dYuF.js → slide-CHn3ald-.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ddj6rSab.js → statusUtils-BiGwoIK_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DyP1mPDf.js → styleChecker-Zf2dQx1j.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D3d_0YuY.js → useFlexGapSupport-sLES8nyD.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-M3vq-gE2.js → useFs-DV1Hl4qu.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-GtP2TgtK.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BurE2ATQ.js → vnode-e8Eo3Oyl.js} +1 -1
- package/src/assets/web-panel/assets/{xterm-BZcWGsqw.js → xterm-zbskxxGA.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Ch-ViiDe.js → zoom-B8A6xKMF.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/compact.js +7 -2
- package/src/data/changelog.json +27 -1
- package/src/harness/jsonl-session-store.js +80 -74
- package/src/harness/prompt-compressor.js +57 -3
- package/src/lib/artifact-store.js +129 -20
- package/src/lib/bounded-artifact-file-read.js +128 -46
- package/src/lib/context-memory-kernel/context-image-transport.js +248 -0
- package/src/lib/context-memory-kernel/jsonl-session-context-port.js +4 -1
- package/src/lib/context-memory-kernel/live-compaction.js +40 -10
- package/src/lib/context-memory-kernel/message-adapter.js +80 -10
- package/src/lib/context-memory-kernel/message-bundle-store.js +1140 -0
- package/src/lib/context-memory-kernel/provider-context.js +23 -8
- package/src/lib/evolution/agent-evolution-ingress.js +103 -19
- package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
- package/src/lib/evolution/agent-model-projection.js +90 -18
- package/src/lib/evolution/evidence-json-text.js +341 -42
- package/src/lib/evolution/evolution-artifact-ports.js +1005 -83
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +59 -15
- package/src/lib/evolution/evolution-evidence-projector.js +153 -16
- package/src/lib/evolution/evolution-evidence-storage-layout.js +115 -0
- package/src/lib/evolution/evolution-file-witness.js +7 -3
- package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +6 -2
- package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +6 -2
- package/src/lib/evolution/evolution-ledger.js +226 -55
- package/src/lib/evolution/evolution-private-storage.js +20 -0
- package/src/lib/evolution/evolution-run-ledger-adapter.js +298 -11
- package/src/lib/evolution/evolution-windows-directory-durability.js +215 -32
- package/src/lib/evolution/local-ui-evolution-runtime.js +3 -38
- package/src/lib/evolution/local-ui-signing-authority.js +69 -0
- package/src/lib/image-token-estimate.js +59 -0
- package/src/lib/ollama-provider-fetch.js +33 -0
- package/src/lib/provider-stream.js +14 -13
- package/src/lib/read-file-loop-guard.js +7 -4
- package/src/lib/session-history-origins.js +94 -35
- package/src/lib/session-message-provenance.js +26 -2
- package/src/lib/session-runtime-retention.js +10 -1
- package/src/lib/session-transcript-history.js +5 -1
- package/src/lib/session-transcript-migration.js +67 -12
- package/src/lib/storage-failure-cause-codes.js +449 -0
- package/src/lib/tool-result-preview.js +276 -0
- package/src/runtime/agent-core.js +111 -92
- package/src/runtime/headless-stream.js +121 -27
- package/src/assets/web-panel/assets/MarkdownRenderer-D8_iZief.js +0 -1
- package/src/assets/web-panel/assets/Projects-BeSOM6wi.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-Bfhvin8B.js +0 -1
- package/src/assets/web-panel/assets/devWarning-c2I2Rn4_.js +0 -1
- package/src/assets/web-panel/assets/index-CTs4dYcV.js +0 -1
- package/src/assets/web-panel/assets/index-DeuvaW15.js +0 -1
- package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../secure-fs.js";
|
|
17
17
|
import { withFileLock } from "../with-file-lock.js";
|
|
18
18
|
import { isLocalUiEvolutionFileSystem } from "./evolution-windows-directory-durability.js";
|
|
19
|
+
import { isProductionEvolutionFileSystem } from "./evolution-private-storage.js";
|
|
19
20
|
import {
|
|
20
21
|
assertKnowledgeWikiSourceAdmission,
|
|
21
22
|
WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
@@ -65,6 +66,8 @@ export const EVOLUTION_LEDGER_V2_CUTOVER_COMPLETED =
|
|
|
65
66
|
"evolution.ledger-v2.cutover-completed";
|
|
66
67
|
const MIGRATION_SOURCES = new WeakMap();
|
|
67
68
|
const DIRECTORY_BOUNDARIES = new WeakMap();
|
|
69
|
+
const VERIFIED_HISTORY_READERS = new WeakMap();
|
|
70
|
+
const DEFAULT_APPEND_PORTS = new WeakSet();
|
|
68
71
|
|
|
69
72
|
const IDENTITY_DOMAIN = "chainlesschain.evolution-ledger-identity/v1\0";
|
|
70
73
|
const EVENT_DOMAIN = "chainlesschain.evolution-event/v2\0";
|
|
@@ -1684,6 +1687,11 @@ const PHYSICAL_DIRECTORY_FIELDS = Object.freeze([
|
|
|
1684
1687
|
"gid",
|
|
1685
1688
|
]);
|
|
1686
1689
|
const physicalBirthtime = (stat) => artifactPhysicalIdentity(stat).birthtimeMs;
|
|
1690
|
+
const physicalFileFingerprint = (stat) =>
|
|
1691
|
+
[
|
|
1692
|
+
...PHYSICAL_FILE_FIELDS.map((field) => String(stat[field])),
|
|
1693
|
+
String(stat.birthtimeNs ?? physicalBirthtime(stat)),
|
|
1694
|
+
].join(":");
|
|
1687
1695
|
const samePhysicalFile = (left, right) =>
|
|
1688
1696
|
PHYSICAL_FILE_FIELDS.every((field) => left[field] === right[field]) &&
|
|
1689
1697
|
physicalBirthtime(left) === physicalBirthtime(right);
|
|
@@ -1713,6 +1721,16 @@ function assertPhysicalFile(stat, maximum, label) {
|
|
|
1713
1721
|
}
|
|
1714
1722
|
}
|
|
1715
1723
|
|
|
1724
|
+
function assertWindowsAclPhysicalFile(stat, label) {
|
|
1725
|
+
assertPhysicalFile(stat, Number.MAX_SAFE_INTEGER, label);
|
|
1726
|
+
if (typeof stat.birthtimeNs !== "bigint") {
|
|
1727
|
+
throw ledgerError(
|
|
1728
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
1729
|
+
`${label} requires full-precision creation time`,
|
|
1730
|
+
);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1716
1734
|
function physicalDirectoryIdentity(stat) {
|
|
1717
1735
|
if (
|
|
1718
1736
|
PHYSICAL_DIRECTORY_FIELDS.some(
|
|
@@ -1946,6 +1964,7 @@ export class EvolutionLedger {
|
|
|
1946
1964
|
#lockTimeoutMs;
|
|
1947
1965
|
#localUiWindowsDurability;
|
|
1948
1966
|
#pendingWindowsAclFiles;
|
|
1967
|
+
#productionFs;
|
|
1949
1968
|
#paths;
|
|
1950
1969
|
#random;
|
|
1951
1970
|
#secure;
|
|
@@ -2011,6 +2030,7 @@ export class EvolutionLedger {
|
|
|
2011
2030
|
this.#localUiWindowsDurability =
|
|
2012
2031
|
process.platform === "win32" && isLocalUiEvolutionFileSystem(fsImpl);
|
|
2013
2032
|
this.#pendingWindowsAclFiles = new Map();
|
|
2033
|
+
this.#productionFs = isProductionEvolutionFileSystem(fsImpl);
|
|
2014
2034
|
this.#fs = captureFs(fsImpl);
|
|
2015
2035
|
// Identity helpers only open parent/volume directories through this port.
|
|
2016
2036
|
this.#identityFs = Object.freeze({
|
|
@@ -2069,22 +2089,51 @@ export class EvolutionLedger {
|
|
|
2069
2089
|
requestedPaths.anchorDir,
|
|
2070
2090
|
];
|
|
2071
2091
|
if (this.#secure && this.#localUiWindowsDurability) {
|
|
2072
|
-
const roots = [
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
requestedPaths.segmentDir,
|
|
2078
|
-
requestedPaths.anchorDir,
|
|
2079
|
-
];
|
|
2080
|
-
// Secure each parent before creating children so inherited Windows
|
|
2081
|
-
// ACLs are private throughout setup. Batch only the child repair.
|
|
2092
|
+
const roots = [requestedPaths.rootDir, requestedPaths.authorityRootDir];
|
|
2093
|
+
const children = [requestedPaths.segmentDir, requestedPaths.anchorDir];
|
|
2094
|
+
// Prepare the independent roots without creating descendants or ledger
|
|
2095
|
+
// objects. Secure both roots in one native ACL operation before any
|
|
2096
|
+
// children can inherit their permissions.
|
|
2082
2097
|
for (const directory of roots) {
|
|
2083
2098
|
ensurePrivateDirectory(directory, {
|
|
2084
|
-
applyWindowsAcl:
|
|
2099
|
+
applyWindowsAcl: false,
|
|
2085
2100
|
failIfUnavailable: true,
|
|
2086
2101
|
});
|
|
2087
2102
|
}
|
|
2103
|
+
const rootIdentities = roots.map((directory) => {
|
|
2104
|
+
const stat = this.#fs.lstatSync(directory, { bigint: true });
|
|
2105
|
+
const identity = physicalDirectoryIdentity(stat);
|
|
2106
|
+
if (typeof stat.birthtimeNs !== "bigint") {
|
|
2107
|
+
throw new Error(
|
|
2108
|
+
"Private ledger root requires full-precision creation time",
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
return { identity, birthtimeNs: stat.birthtimeNs };
|
|
2112
|
+
});
|
|
2113
|
+
const repairedRoots = repairPrivatePaths(roots);
|
|
2114
|
+
if (
|
|
2115
|
+
repairedRoots.length !== roots.length ||
|
|
2116
|
+
repairedRoots.some(
|
|
2117
|
+
(entry, index) =>
|
|
2118
|
+
entry.target !== roots[index] ||
|
|
2119
|
+
entry.ok !== true ||
|
|
2120
|
+
entry.exists === false,
|
|
2121
|
+
)
|
|
2122
|
+
) {
|
|
2123
|
+
throw new Error("Could not verify private ledger roots");
|
|
2124
|
+
}
|
|
2125
|
+
for (const [index, directory] of roots.entries()) {
|
|
2126
|
+
const stat = this.#fs.lstatSync(directory, { bigint: true });
|
|
2127
|
+
const identity = physicalDirectoryIdentity(stat);
|
|
2128
|
+
const expected = rootIdentities[index];
|
|
2129
|
+
if (
|
|
2130
|
+
identity.dev !== expected.identity.dev ||
|
|
2131
|
+
identity.ino !== expected.identity.ino ||
|
|
2132
|
+
stat.birthtimeNs !== expected.birthtimeNs
|
|
2133
|
+
) {
|
|
2134
|
+
throw new Error("Private ledger root changed during ACL setup");
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2088
2137
|
for (const directory of children) {
|
|
2089
2138
|
ensurePrivateDirectory(directory, {
|
|
2090
2139
|
applyWindowsAcl: false,
|
|
@@ -2275,6 +2324,34 @@ export class EvolutionLedger {
|
|
|
2275
2324
|
recheck: Object.freeze(recheck),
|
|
2276
2325
|
}),
|
|
2277
2326
|
);
|
|
2327
|
+
if (new.target === EvolutionLedger)
|
|
2328
|
+
VERIFIED_HISTORY_READERS.set(
|
|
2329
|
+
this,
|
|
2330
|
+
Object.freeze((...args) => {
|
|
2331
|
+
if (args.length)
|
|
2332
|
+
throw new TypeError(
|
|
2333
|
+
"verified history takes no replacement context",
|
|
2334
|
+
);
|
|
2335
|
+
return this.#withLock(() => {
|
|
2336
|
+
const state = this.#loadState({
|
|
2337
|
+
allowInitialize: false,
|
|
2338
|
+
incremental: true,
|
|
2339
|
+
});
|
|
2340
|
+
return deepFreeze({
|
|
2341
|
+
authority: this.#authorityProjection(state),
|
|
2342
|
+
events: state.events.slice(0, 10_000),
|
|
2343
|
+
});
|
|
2344
|
+
});
|
|
2345
|
+
}),
|
|
2346
|
+
);
|
|
2347
|
+
if (
|
|
2348
|
+
new.target === EvolutionLedger &&
|
|
2349
|
+
this.#productionFs &&
|
|
2350
|
+
lock === withFileLock &&
|
|
2351
|
+
crashHook == null
|
|
2352
|
+
) {
|
|
2353
|
+
DEFAULT_APPEND_PORTS.add(this);
|
|
2354
|
+
}
|
|
2278
2355
|
Object.freeze(this);
|
|
2279
2356
|
}
|
|
2280
2357
|
|
|
@@ -3063,7 +3140,7 @@ export class EvolutionLedger {
|
|
|
3063
3140
|
label,
|
|
3064
3141
|
allowMissing,
|
|
3065
3142
|
samePathHandle,
|
|
3066
|
-
{ trustedParentPath = null } = {},
|
|
3143
|
+
{ trustedParentPath = null, legacyFingerprint = true } = {},
|
|
3067
3144
|
) {
|
|
3068
3145
|
const heldParent =
|
|
3069
3146
|
trustedParentPath !== null &&
|
|
@@ -3091,19 +3168,24 @@ export class EvolutionLedger {
|
|
|
3091
3168
|
// Preserve the exact legacy Number fingerprint already signed into the
|
|
3092
3169
|
// store marker binding. It is sampled inside a separate BigInt window and
|
|
3093
3170
|
// is never used as the authority for a physical file/handle comparison.
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
(!
|
|
3100
|
-
|
|
3171
|
+
let fingerprint = null;
|
|
3172
|
+
if (legacyFingerprint) {
|
|
3173
|
+
const legacyBefore = this.#fs.lstatSync(filePath);
|
|
3174
|
+
const sampled = this.#fs.lstatSync(filePath, { bigint: true });
|
|
3175
|
+
assertPhysicalFile(sampled, maximum, label);
|
|
3176
|
+
if (!samePhysicalFile(before, sampled)) {
|
|
3177
|
+
throw ledgerError(
|
|
3178
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3179
|
+
`${label} changed while its fingerprint was sampled`,
|
|
3180
|
+
);
|
|
3181
|
+
}
|
|
3182
|
+
fingerprint = fileFingerprint(legacyBefore);
|
|
3183
|
+
}
|
|
3184
|
+
if (!heldParent && !samePath(realpath(this.#fs, filePath), filePath))
|
|
3101
3185
|
throw ledgerError(
|
|
3102
3186
|
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3103
3187
|
`${label} changed while its fingerprint was sampled`,
|
|
3104
3188
|
);
|
|
3105
|
-
}
|
|
3106
|
-
const fingerprint = fileFingerprint(legacyBefore);
|
|
3107
3189
|
descriptor = this.#fs.openSync(
|
|
3108
3190
|
filePath,
|
|
3109
3191
|
this.#fs.constants.O_RDONLY |
|
|
@@ -3137,7 +3219,9 @@ export class EvolutionLedger {
|
|
|
3137
3219
|
);
|
|
3138
3220
|
}
|
|
3139
3221
|
const after = this.#fs.fstatSync(descriptor, { bigint: true });
|
|
3140
|
-
const legacyAfter =
|
|
3222
|
+
const legacyAfter = legacyFingerprint
|
|
3223
|
+
? this.#fs.lstatSync(filePath)
|
|
3224
|
+
: null;
|
|
3141
3225
|
const afterPath = this.#fs.lstatSync(filePath, { bigint: true });
|
|
3142
3226
|
assertPhysicalFile(after, maximum, label);
|
|
3143
3227
|
assertPhysicalFile(afterPath, maximum, label);
|
|
@@ -3154,7 +3238,7 @@ export class EvolutionLedger {
|
|
|
3154
3238
|
!samePhysicalFile(before, afterPath) ||
|
|
3155
3239
|
!samePathHandle(afterPath, after) ||
|
|
3156
3240
|
!samePhysicalOwner(afterPath, after) ||
|
|
3157
|
-
fileFingerprint(legacyAfter) !== fingerprint ||
|
|
3241
|
+
(legacyFingerprint && fileFingerprint(legacyAfter) !== fingerprint) ||
|
|
3158
3242
|
(!heldParent && !samePath(realpath(this.#fs, filePath), filePath))
|
|
3159
3243
|
) {
|
|
3160
3244
|
throw ledgerError(
|
|
@@ -3162,7 +3246,13 @@ export class EvolutionLedger {
|
|
|
3162
3246
|
`${label} pathname changed during bounded read`,
|
|
3163
3247
|
);
|
|
3164
3248
|
}
|
|
3165
|
-
return {
|
|
3249
|
+
return {
|
|
3250
|
+
bytes,
|
|
3251
|
+
fingerprint,
|
|
3252
|
+
physicalFingerprint: this.#productionFs
|
|
3253
|
+
? physicalFileFingerprint(before)
|
|
3254
|
+
: null,
|
|
3255
|
+
};
|
|
3166
3256
|
} catch (cause) {
|
|
3167
3257
|
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
3168
3258
|
throw ledgerError(
|
|
@@ -3193,7 +3283,7 @@ export class EvolutionLedger {
|
|
|
3193
3283
|
{ trustedParentPath },
|
|
3194
3284
|
);
|
|
3195
3285
|
if (file === null) return null;
|
|
3196
|
-
const { bytes
|
|
3286
|
+
const { bytes } = file;
|
|
3197
3287
|
if (expectedBytes !== null) {
|
|
3198
3288
|
if (!Buffer.isBuffer(expectedBytes) || !bytes.equals(expectedBytes)) {
|
|
3199
3289
|
throw ledgerError(
|
|
@@ -3201,7 +3291,7 @@ export class EvolutionLedger {
|
|
|
3201
3291
|
`${label} differs from its signed snapshot bytes`,
|
|
3202
3292
|
);
|
|
3203
3293
|
}
|
|
3204
|
-
return {
|
|
3294
|
+
return { ...file, contentDigest: sha256(bytes), record: null };
|
|
3205
3295
|
}
|
|
3206
3296
|
let text;
|
|
3207
3297
|
try {
|
|
@@ -3235,7 +3325,7 @@ export class EvolutionLedger {
|
|
|
3235
3325
|
`${label} bytes are not canonical`,
|
|
3236
3326
|
);
|
|
3237
3327
|
}
|
|
3238
|
-
return {
|
|
3328
|
+
return { ...file, contentDigest: sha256(bytes), record };
|
|
3239
3329
|
}
|
|
3240
3330
|
|
|
3241
3331
|
#writeImmutable(filePath, bytes, label, onPublished = null) {
|
|
@@ -3418,9 +3508,27 @@ export class EvolutionLedger {
|
|
|
3418
3508
|
#securePublishedFile(filePath, stat) {
|
|
3419
3509
|
if (!this.#secure) return;
|
|
3420
3510
|
if (this.#localUiWindowsDurability) {
|
|
3511
|
+
const physical = this.#fs.lstatSync(filePath, { bigint: true });
|
|
3512
|
+
assertWindowsAclPhysicalFile(physical, "published ledger file");
|
|
3513
|
+
// Keep the publication sample consistent, then retain the full-precision
|
|
3514
|
+
// path identity for all ACL checks (the signed legacy binding is unchanged).
|
|
3515
|
+
if (
|
|
3516
|
+
["dev", "ino", "mode", "size"].some(
|
|
3517
|
+
(field) => Number(physical[field]) !== stat[field],
|
|
3518
|
+
) ||
|
|
3519
|
+
Number(physical.birthtimeNs / 1_000_000_000n) * 1000 +
|
|
3520
|
+
Number(physical.birthtimeNs % 1_000_000_000n) / 1_000_000 !==
|
|
3521
|
+
stat.birthtimeMs
|
|
3522
|
+
) {
|
|
3523
|
+
throw ledgerError(
|
|
3524
|
+
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
3525
|
+
"published ledger file changed before Windows ACL verification",
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3421
3528
|
this.#pendingWindowsAclFiles.set(path.resolve(filePath), {
|
|
3422
|
-
identity: artifactPhysicalIdentity(
|
|
3423
|
-
|
|
3529
|
+
identity: artifactPhysicalIdentity(physical),
|
|
3530
|
+
birthtimeNs: physical.birthtimeNs,
|
|
3531
|
+
size: physical.size,
|
|
3424
3532
|
});
|
|
3425
3533
|
return;
|
|
3426
3534
|
}
|
|
@@ -3431,12 +3539,13 @@ export class EvolutionLedger {
|
|
|
3431
3539
|
}
|
|
3432
3540
|
|
|
3433
3541
|
#assertPendingWindowsAclFile(filePath, expected) {
|
|
3434
|
-
const stat = this.#fs.lstatSync(filePath);
|
|
3542
|
+
const stat = this.#fs.lstatSync(filePath, { bigint: true });
|
|
3435
3543
|
if (
|
|
3436
3544
|
!stat.isFile() ||
|
|
3437
3545
|
stat.isSymbolicLink() ||
|
|
3438
|
-
stat.nlink !==
|
|
3546
|
+
stat.nlink !== 1n ||
|
|
3439
3547
|
stat.size !== expected.size ||
|
|
3548
|
+
stat.birthtimeNs !== expected.birthtimeNs ||
|
|
3440
3549
|
!sameArtifactIdentity(stat, expected.identity)
|
|
3441
3550
|
) {
|
|
3442
3551
|
throw ledgerError(
|
|
@@ -3456,7 +3565,9 @@ export class EvolutionLedger {
|
|
|
3456
3565
|
}
|
|
3457
3566
|
const entries = [...this.#pendingWindowsAclFiles.entries()];
|
|
3458
3567
|
const files = entries.map(([filePath]) => filePath);
|
|
3459
|
-
const directories = [
|
|
3568
|
+
const directories = [
|
|
3569
|
+
...new Set(files.map((filePath) => path.dirname(filePath))),
|
|
3570
|
+
];
|
|
3460
3571
|
try {
|
|
3461
3572
|
this.#assertBoundaries();
|
|
3462
3573
|
for (const [filePath, expected] of entries) {
|
|
@@ -3475,31 +3586,73 @@ export class EvolutionLedger {
|
|
|
3475
3586
|
throw new Error("Windows ACL batch did not verify every ledger file");
|
|
3476
3587
|
}
|
|
3477
3588
|
for (const [filePath, expected] of entries) {
|
|
3478
|
-
|
|
3479
|
-
|
|
3589
|
+
// Affected libuv path stats project dev differently from fstat. Bind
|
|
3590
|
+
// the handle to a separately held parent volume without relaxing the
|
|
3591
|
+
// inode, owner, creation time, or mutation metadata checks.
|
|
3592
|
+
withEvolutionFileIdentity(
|
|
3593
|
+
this.#identityFs,
|
|
3480
3594
|
filePath,
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
if (
|
|
3486
|
-
!opened.isFile() ||
|
|
3487
|
-
opened.nlink !== 1 ||
|
|
3488
|
-
opened.size !== expected.size ||
|
|
3489
|
-
!sameArtifactIdentity(opened, expected.identity)
|
|
3490
|
-
) {
|
|
3491
|
-
throw ledgerError(
|
|
3492
|
-
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
3493
|
-
"ledger file identity changed during Windows ACL verification",
|
|
3595
|
+
(samePathHandle) => {
|
|
3596
|
+
const before = this.#assertPendingWindowsAclFile(
|
|
3597
|
+
filePath,
|
|
3598
|
+
expected,
|
|
3494
3599
|
);
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3600
|
+
assertWindowsAclPhysicalFile(before, "published ledger file");
|
|
3601
|
+
const descriptor = this.#fs.openSync(
|
|
3602
|
+
filePath,
|
|
3603
|
+
this.#fs.constants.O_RDWR | (this.#fs.constants.O_NOFOLLOW || 0),
|
|
3604
|
+
);
|
|
3605
|
+
try {
|
|
3606
|
+
const opened = this.#fs.fstatSync(descriptor, { bigint: true });
|
|
3607
|
+
assertWindowsAclPhysicalFile(
|
|
3608
|
+
opened,
|
|
3609
|
+
"published ledger descriptor",
|
|
3610
|
+
);
|
|
3611
|
+
if (
|
|
3612
|
+
!opened.isFile() ||
|
|
3613
|
+
opened.nlink !== 1n ||
|
|
3614
|
+
opened.size !== expected.size ||
|
|
3615
|
+
opened.birthtimeNs !== before.birthtimeNs ||
|
|
3616
|
+
!samePathHandle(before, opened) ||
|
|
3617
|
+
!samePhysicalOwner(before, opened)
|
|
3618
|
+
) {
|
|
3619
|
+
throw ledgerError(
|
|
3620
|
+
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
3621
|
+
"ledger file identity changed during Windows ACL verification",
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
this.#fs.fsyncSync(descriptor);
|
|
3625
|
+
const after = this.#fs.fstatSync(descriptor, { bigint: true });
|
|
3626
|
+
assertWindowsAclPhysicalFile(
|
|
3627
|
+
after,
|
|
3628
|
+
"published ledger descriptor",
|
|
3629
|
+
);
|
|
3630
|
+
const afterPath = this.#assertPendingWindowsAclFile(
|
|
3631
|
+
filePath,
|
|
3632
|
+
expected,
|
|
3633
|
+
);
|
|
3634
|
+
if (
|
|
3635
|
+
!samePhysicalFile(opened, after) ||
|
|
3636
|
+
opened.birthtimeNs !== after.birthtimeNs ||
|
|
3637
|
+
!samePhysicalFile(before, afterPath) ||
|
|
3638
|
+
afterPath.birthtimeNs !== after.birthtimeNs ||
|
|
3639
|
+
!samePathHandle(afterPath, after) ||
|
|
3640
|
+
!samePhysicalOwner(afterPath, after)
|
|
3641
|
+
) {
|
|
3642
|
+
throw ledgerError(
|
|
3643
|
+
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
3644
|
+
"ledger file identity changed during Windows ACL verification",
|
|
3645
|
+
);
|
|
3646
|
+
}
|
|
3647
|
+
} finally {
|
|
3648
|
+
this.#fs.closeSync(descriptor);
|
|
3649
|
+
}
|
|
3650
|
+
},
|
|
3651
|
+
);
|
|
3500
3652
|
}
|
|
3501
3653
|
this.#assertBoundaries();
|
|
3502
|
-
for (const filePath of files)
|
|
3654
|
+
for (const filePath of files)
|
|
3655
|
+
this.#pendingWindowsAclFiles.delete(filePath);
|
|
3503
3656
|
return directories;
|
|
3504
3657
|
} catch (cause) {
|
|
3505
3658
|
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
@@ -3832,10 +3985,12 @@ export class EvolutionLedger {
|
|
|
3832
3985
|
"cached ledger file",
|
|
3833
3986
|
false,
|
|
3834
3987
|
samePathHandle,
|
|
3835
|
-
{ trustedParentPath },
|
|
3988
|
+
{ trustedParentPath, legacyFingerprint: !this.#productionFs },
|
|
3836
3989
|
);
|
|
3837
3990
|
return (
|
|
3838
|
-
|
|
3991
|
+
(this.#productionFs
|
|
3992
|
+
? file.physicalFingerprint === expected.physicalFingerprint
|
|
3993
|
+
: file.fingerprint === expected.fingerprint) &&
|
|
3839
3994
|
sha256(file.bytes) === expected.contentDigest
|
|
3840
3995
|
);
|
|
3841
3996
|
}
|
|
@@ -4055,6 +4210,7 @@ export class EvolutionLedger {
|
|
|
4055
4210
|
anchorFingerprints[entry.name] = Object.freeze({
|
|
4056
4211
|
contentDigest: file.contentDigest,
|
|
4057
4212
|
fingerprint: file.fingerprint,
|
|
4213
|
+
physicalFingerprint: file.physicalFingerprint,
|
|
4058
4214
|
});
|
|
4059
4215
|
}
|
|
4060
4216
|
},
|
|
@@ -4093,6 +4249,7 @@ export class EvolutionLedger {
|
|
|
4093
4249
|
segmentFingerprints[entry.name] = Object.freeze({
|
|
4094
4250
|
contentDigest: file.contentDigest,
|
|
4095
4251
|
fingerprint: file.fingerprint,
|
|
4252
|
+
physicalFingerprint: file.physicalFingerprint,
|
|
4096
4253
|
});
|
|
4097
4254
|
}
|
|
4098
4255
|
},
|
|
@@ -4453,6 +4610,7 @@ export class EvolutionLedger {
|
|
|
4453
4610
|
anchorFingerprints[name] = Object.freeze({
|
|
4454
4611
|
contentDigest: anchorFile.contentDigest,
|
|
4455
4612
|
fingerprint: anchorFile.fingerprint,
|
|
4613
|
+
physicalFingerprint: anchorFile.physicalFingerprint,
|
|
4456
4614
|
});
|
|
4457
4615
|
anchors.push(anchor);
|
|
4458
4616
|
if (index === 0) continue;
|
|
@@ -4485,6 +4643,7 @@ export class EvolutionLedger {
|
|
|
4485
4643
|
segmentFingerprints[segmentName] = Object.freeze({
|
|
4486
4644
|
contentDigest: segmentFile.contentDigest,
|
|
4487
4645
|
fingerprint: segmentFile.fingerprint,
|
|
4646
|
+
physicalFingerprint: segmentFile.physicalFingerprint,
|
|
4488
4647
|
});
|
|
4489
4648
|
eventIds.add(event.eventId);
|
|
4490
4649
|
events.push(event);
|
|
@@ -5642,6 +5801,18 @@ export class EvolutionLedger {
|
|
|
5642
5801
|
}
|
|
5643
5802
|
}
|
|
5644
5803
|
|
|
5804
|
+
/** One authenticated state supplies both history and its exact frontier. */
|
|
5805
|
+
export function getEvolutionLedgerVerifiedHistoryReader(ledger) {
|
|
5806
|
+
if (arguments.length !== 1)
|
|
5807
|
+
throw new TypeError("verified history capture takes one original ledger");
|
|
5808
|
+
return VERIFIED_HISTORY_READERS.get(ledger) ?? null;
|
|
5809
|
+
}
|
|
5810
|
+
|
|
5811
|
+
/** Construction identity only: custom filesystem/lock/crash ports keep phases. */
|
|
5812
|
+
export function hasEvolutionLedgerDefaultAppendPorts(ledger) {
|
|
5813
|
+
return DEFAULT_APPEND_PORTS.has(ledger);
|
|
5814
|
+
}
|
|
5815
|
+
|
|
5645
5816
|
// Trusted composition port; consumers receive the journal wrapper, never this
|
|
5646
5817
|
// capability. WeakMap identity excludes structural or prototype impersonation.
|
|
5647
5818
|
export function captureEvolutionLedgerMigrationSource(ledger) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { isUnmodifiedLocalUiEvolutionFileSystem } from "./evolution-windows-directory-durability.js";
|
|
3
|
+
|
|
4
|
+
export function isProductionEvolutionFileSystem(fsImpl) {
|
|
5
|
+
return fsImpl === fs || isUnmodifiedLocalUiEvolutionFileSystem(fsImpl);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function evolutionPrivateStorageOptions(fsImpl, { file = false } = {}) {
|
|
9
|
+
// The production adapter only adds directory flushing; ACL operations still
|
|
10
|
+
// use Node's original fs. Preserve explicit dependencies for custom ports.
|
|
11
|
+
const production = isProductionEvolutionFileSystem(fsImpl);
|
|
12
|
+
return {
|
|
13
|
+
...(production ? {} : { deps: { fs: fsImpl } }),
|
|
14
|
+
// An elevated Windows token can give a new file its administrator-group
|
|
15
|
+
// owner even when its DACL inherits only the user's private directory rule.
|
|
16
|
+
// Explicit repair binds both the file owner and ACL to the current user.
|
|
17
|
+
...(file ? { applyWindowsAcl: true } : {}),
|
|
18
|
+
failIfUnavailable: true,
|
|
19
|
+
};
|
|
20
|
+
}
|