chainlesschain 0.166.109 → 0.166.112
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 +6 -4
- package/package.json +3 -2
- 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/assets/{AIOps-DkrNbDzS.js → AIOps-sOceeExN.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DJjFXDhv.js → ActionButton-BQs-vRUr.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DyUbagRn.js → Analytics-sfAHHMhA.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-p7kJWSvn.js → AppLayout-0gAvE0c8.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-C3rVh4Ak.js → Artifacts-Dh9s2Qmd.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bch_L_YO.js → Audit-CITm26SU.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BNHy8zP6.js → BackgroundAgents-BiMbBOh0.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BUaye_Ys.js → Backup-CNpnhI3h.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D49mzAVz.js → BaseInput-BI_lltkp.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-2MDzM_us.js → Chat-BgfB88xY.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BDP3fGoz.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-5p1T_KEq.js → Checkbox-4xy9rS3j.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-TKtiLaoZ.js → Codegen-D93h9ihS.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BVCMG9mS.js → Col-BRf3STY-.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D09-QczH.js → Community-f187ziSL.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-QuRMCnj7.js → Compact-D4hXWuo1.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CN0PV7fk.js → Compliance-C6cYKI6H.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-5N2zhAty.js → Cowork-C1i1f8LD.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BxT8UZ0S.js → Cron-BacCE4LA.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Dp-noQl4.js → Crosschain-DXztxOoH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B7MZFkjG.js → DID-rpf4HN8x.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DulJ3rKV.js → Dashboard-h4bgtH7L.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DV4ov4zF.js → Dropdown-CyQnoHmu.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DB2-ooz6.js → EmailListRenderer-FCtp4AcB.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-B1Rb6p7q.js → EvolutionSettings-JbISHTWR.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-U8aHayx-.js → FamilyGuardDashboard-DCIQLyfK.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BkQULBHY.js → Federation-DDbFpwja.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CtviG260.js → FormItemContext-CXF0jtXb.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DnPirB24.js → GenericCardRenderer-CUaNfAM0.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CK57Oro6.js → Git-Bhoz2gDf.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DbI-LB8-.js → Governance-FiiXHe8e.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-sEG4T1Jg.js → Inference-brpTW2Q3.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-9SLJR3h9.js → KnowledgeGraph-BCWP-f6k.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BIZYcISQ.js → Logs-CxYcduoK.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-12vD1nC1.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CRmLLwAE.js → Marketplace-DANdmW7l.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DkOFkSO1.js → McpTools-Bi_EKkb5.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-M29Kd9TU.js → Memory-DecoMbYw.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Tl6JvPw_.js → MobileBridge-DrOhFKp0.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-rRwP16dN.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-DkUjX1F5.js → Mtc-SLPII1iw.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BCqr1I4q.js → MtcAudit-DWoVORYy.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DmoqYGQ5.js → Multisig-Dxpnmq-m.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DNRQeRke.js → NLProgramming-kNTpNqCP.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CQSBeiY6.js → Notes-D1uXCfVd.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-gNY9bbH6.js → NotificationSettings-D3Qt8Gkl.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DW0CNjh8.js → OrderTableRenderer-qvaah2-m.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CthnbKag.js → Organization-EhRl4JoJ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-_GQ3sbXu.js → Overflow-BTt5C_5W.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BTr7ea6W.js → P2P-CeR2jyb0.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-BzD3OHWq.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DMny2Cjs.js → Permissions-BOPyeRlz.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CyYlMSoI.js → PersonalDataHub-DcmNNsfO.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-FASu2Oc4.js → Pipeline-DuL3kwWC.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-9bC5FnsJ.js → Privacy-CkQRdlSU.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BOYZwB5G.js → ProjectInit-moE_vQ1P.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-45DViNG-.js → ProjectSettings-PnTWi4NQ.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-C2fZzMZc.js → Projects-DZvbT3D7.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BgjvZx9F.js → Providers-CkcrHYy9.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Brw-3csB.js → QrScannerModal-nYNFGf_H.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DWG-A5zB.js → QuickAsk-53WNo7xT.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DuQGxjIR.js → Recommend-CmYN_NaS.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-T1cdSSRL.js → RemoteSession-BuOdNEjA.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-9FT2dI4G.js → Reputation-BgkheZou.js} +1 -1
- package/src/assets/web-panel/assets/{Row-yNIbNftX.js → Row-DvA3klj1.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BIchNoPd.js → RssFeed-CgkIL3PG.js} +3 -3
- package/src/assets/web-panel/assets/{Search-msDJ8UTZ.js → Search-Cv2twJdL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DE46oBYT.js → Security-XrD2UNU6.js} +2 -2
- package/src/assets/web-panel/assets/{Services-Dori7vc3.js → Services-LujCntCK.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D3O3sUFz.js → Skeleton-ZZCOsxPX.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BV0ct8SO.js → Skills-BEXGkOrU.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DflIVOrh.js → Sla-CIqmCgdD.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cpbv2Zz6.js → SpeechSettings-DkVbwJox.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dgg6-wbe.js → SyncSettings-BVGgUs0p.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Cb6e4Klx.js → Tasks-C1lh68l5.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-GfdAATGz.js → Templates-BG4zNAFx.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-D0gecLXl.js → Tenant-t2o6i5fY.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BFRPJt-0.js → Terminal-CH8UDdVO.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BobtChxX.js → TimelineRenderer-B5sYY1IO.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CifeZtHV.js → Tokens-D0y7QkG5.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BHBvbBCf.js → Trigger-BA2nKko0.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-6lvqjKYp.js → Trust-CrFKCQIs.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CqzMc-G5.js → UkeySign-B3x_-Zun.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-OIiRG582.js → VideoEditing-TEwxbLH6.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-4MeKq0q_.js → Wallet-Larp5rrt.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-eHBRjGQG.js → WebAuthn-DfWbEIZe.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DlzYdEqW.js → WorkflowEditor-8LKiKExY.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CBcjOzkX.js → chat-ByxYOvYW.js} +1 -1
- package/src/assets/web-panel/assets/{colors-zgwsYQSa.js → colors-Dh4yAClh.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Dcd9H5Bn.js → compact-item-f5n2j1WZ.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DR1tO-8r.js → createContext-DIprYuXL.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DRIge35Z.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CtfbUH_p.js → hasIn-CvYeap2I.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1GxtY-h.js → index-3ROY-lYB.js} +1 -1
- package/src/assets/web-panel/assets/{index-CT7zIkqP.js → index-6VEWxOyC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cdhy5ckh.js → index-7eG1J-GT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvPOpvvH.js → index-B0AXUhiJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cur8LNNn.js → index-BS_dpgzu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWG98orp.js → index-BaXSBxy-.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5XGvJb0.js → index-Bk8oWRk6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA2-Bhy8.js → index-BlImvgb7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwHgaYVH.js → index-BoayvJ48.js} +1 -1
- package/src/assets/web-panel/assets/index-Bq24rTYx.js +1 -0
- package/src/assets/web-panel/assets/{index-DHEiuvhA.js → index-BsU46c7D.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSvcz0RO.js → index-BvyFQF8I.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7ZOiIKb.js → index-C2RGykST.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmzQzTY5.js → index-C5aH2Pj2.js} +1 -1
- package/src/assets/web-panel/assets/{index-oWOlF7CM.js → index-CD0s5ESV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVpp9YSQ.js → index-CIZQtz8G.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWuCGhHa.js → index-CJjc8ObW.js} +1 -1
- package/src/assets/web-panel/assets/{index-JSfldpw4.js → index-CTqJNul4.js} +1 -1
- package/src/assets/web-panel/assets/{index-dvF6C39V.js → index-CcvA1nae.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmVIM-m2.js → index-CpR0zD38.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaGNqkY0.js → index-CzabQZ7I.js} +1 -1
- package/src/assets/web-panel/assets/index-D2f18WsK.js +1 -0
- package/src/assets/web-panel/assets/{index-BXfGHUz_.js → index-DGyTzElU.js} +1 -1
- package/src/assets/web-panel/assets/{index-LN7Hkl1C.js → index-DI8jC7gQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfzOYmOj.js → index-DUj-sL9U.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoxowMYS.js → index-DaZVtafQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSQCHpDo.js → index-DjvON8oh.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3QUK1ks.js → index-DlJCDpeN.js} +1 -1
- package/src/assets/web-panel/assets/{index-J-ORW1i6.js → index-DlTwZIeX.js} +1 -1
- package/src/assets/web-panel/assets/{index-z8lrkcb-.js → index-DlULGx8u.js} +1 -1
- package/src/assets/web-panel/assets/{index-hTcre7U9.js → index-DmcAL4hd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYPMJ5Mb.js → index-DshB3-Up.js} +3 -3
- package/src/assets/web-panel/assets/{index-5XaB_Tjg.js → index-Du435yzt.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0kP88Pb.js → index-bt-0zMmH.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8WPohye.js → index-c_CxUQl3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeAi4CNt.js → index-fpWv4u3Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-BndPtS9D.js → index-hwbaD3Nk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTx4FyLU.js → index-uDiVjYrS.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPLLgPxA.js → index-xU0eHLIH.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CVMtDrWZ.js → initDefaultProps-DRuE92W6.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Dye3IU8k.js → motion-6Sgma5Vd.js} +1 -1
- package/src/assets/web-panel/assets/{move-C251Zo34.js → move-BbQsH8sb.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BDiOORoQ.js → mtc-parser-BdC4INal.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DTDA_RHv.js → omit-DeC5m_bi.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CqEUTPcT.js → pickAttrs-DuehpBws.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BOB8QWH3.js → placementArrow-CJEhv2ij.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CZDXP1d9.js → responsiveObserve-Dyw3lDGr.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DPaRw3E9.js → slide-BMaLXTbS.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ba9d7XZ7.js → statusUtils-c1K_SdJH.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-mZKU3lvW.js → styleChecker-CefBry8k.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-VcauLq0M.js → useFlexGapSupport-Dj2IsZpo.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Cal9KRcx.js → useFs-RLfB3yqb.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DISoRyQB.js → usePersonalDataHub-DbRVH_NA.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-B58C6w6B.js → vnode-DTn_QVJz.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BPlBAMKB.js → zoom-DuFR0E7i.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent.js +12 -5
- package/src/commands/ask.js +96 -21
- package/src/commands/complete.js +14 -10
- package/src/commands/llm.js +23 -41
- package/src/commands/session.js +2 -2
- package/src/commands/stream.js +9 -5
- package/src/commands/ui.js +30 -2
- package/src/data/changelog.json +39 -0
- package/src/gateways/ws/llm-chat-protocol.js +18 -10
- package/src/gateways/ws/llm-creds.js +29 -79
- package/src/gateways/ws/ws-agent-handler.js +1 -1
- package/src/gateways/ws/ws-session-gateway.js +26 -12
- package/src/lib/__tests__/provider-stream.test.js +70 -4
- package/src/lib/chat-core.js +186 -24
- package/src/lib/cowork-adapter.js +29 -15
- package/src/lib/evolution/agent-evolution-runtime-composition.js +10 -7
- package/src/lib/evolution/evolution-deployment-config.js +27 -4
- package/src/lib/evolution/evolution-deployment-loader.js +58 -3
- package/src/lib/evolution/evolution-deployment-profile.js +2 -2
- package/src/lib/evolution/evolution-evidence-projector.js +18 -3
- package/src/lib/evolution/evolution-file-witness.js +10 -0
- package/src/lib/evolution/evolution-ledger.js +237 -28
- package/src/lib/evolution/evolution-windows-directory-durability.js +322 -0
- package/src/lib/evolution/governed-hub-llm.js +2 -1
- package/src/lib/evolution/governed-model-turn.js +4 -1
- package/src/lib/evolution/local-ui-evolution-deployment.js +682 -0
- package/src/lib/evolution/local-ui-evolution-host.mjs +26 -0
- package/src/lib/evolution/local-ui-evolution-runtime.js +601 -0
- package/src/lib/evolution/opaque-hex-id.js +28 -0
- package/src/lib/hub-llm-client.js +22 -14
- package/src/lib/image-input.js +19 -3
- package/src/lib/llm-config-defaults.js +19 -30
- package/src/lib/llm-connection-config.js +4 -0
- package/src/lib/llm-connection-probe.js +5 -1
- package/src/lib/llm-connection-resolution.js +94 -0
- package/src/lib/llm-providers.js +33 -11
- package/src/lib/ollama-base-url.js +14 -0
- package/src/lib/provider-protocol.js +104 -0
- package/src/lib/provider-stream.js +163 -4
- package/src/lib/runnable-provider.js +1 -0
- package/src/repl/chat-repl.js +58 -11
- package/src/runtime/agent-core.js +26 -43
- package/src/runtime/headless-runner.js +11 -4
- package/src/runtime/headless-stream.js +10 -4
- package/src/runtime/policies/agent-policy.js +17 -11
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DOX3Y5EJ.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-9nfWupWP.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-Bq-FPDzS.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-D9McHF9I.js +0 -7
- package/src/assets/web-panel/assets/devWarning-DYhpRtve.js +0 -1
- package/src/assets/web-panel/assets/index-DPJXFIY7.js +0 -1
- package/src/assets/web-panel/assets/index-DjBhR5M_.js +0 -1
|
@@ -9,8 +9,13 @@ import {
|
|
|
9
9
|
} from "./evolution-file-identity.js";
|
|
10
10
|
import { artifactPhysicalIdentity } from "./evolution-artifact-identity.js";
|
|
11
11
|
import { getHomeDir } from "../paths.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ensurePrivateDirectory,
|
|
14
|
+
ensurePrivateFile,
|
|
15
|
+
repairPrivatePaths,
|
|
16
|
+
} from "../secure-fs.js";
|
|
13
17
|
import { withFileLock } from "../with-file-lock.js";
|
|
18
|
+
import { isLocalUiEvolutionFileSystem } from "./evolution-windows-directory-durability.js";
|
|
14
19
|
import {
|
|
15
20
|
assertKnowledgeWikiSourceAdmission,
|
|
16
21
|
WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
@@ -148,9 +153,12 @@ const DECISIONS = new Set([
|
|
|
148
153
|
const REVOCATION_STATES = new Set(["not-revoked", "revoked", "tombstoned"]);
|
|
149
154
|
const DURABILITY_MECHANISMS = new Set([
|
|
150
155
|
"authenticated-witness-cas",
|
|
156
|
+
"authenticated-witness-cas-windows-directory-flush",
|
|
151
157
|
"authenticated-witness-batch-cas",
|
|
158
|
+
"authenticated-witness-batch-cas-windows-directory-flush",
|
|
152
159
|
"directory-fsync",
|
|
153
160
|
"verified-existing",
|
|
161
|
+
"windows-directory-flush",
|
|
154
162
|
]);
|
|
155
163
|
const EMPTY_DISCARD_ACCUMULATOR_DIGEST = domainDigest(
|
|
156
164
|
DISCARD_ACCUMULATOR_DOMAIN,
|
|
@@ -1809,6 +1817,21 @@ function captureFs(fsImpl) {
|
|
|
1809
1817
|
Reflect.apply(implementation, undefined, args),
|
|
1810
1818
|
);
|
|
1811
1819
|
}
|
|
1820
|
+
const directorySync = Object.getOwnPropertyDescriptor(
|
|
1821
|
+
fsImpl,
|
|
1822
|
+
"syncDirectorySync",
|
|
1823
|
+
);
|
|
1824
|
+
if (directorySync) {
|
|
1825
|
+
if (typeof directorySync.value !== "function") {
|
|
1826
|
+
throw ledgerError(
|
|
1827
|
+
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
1828
|
+
"syncDirectorySync must be a data function",
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1831
|
+
captured.syncDirectorySync = Object.freeze((...args) =>
|
|
1832
|
+
Reflect.apply(directorySync.value, fsImpl, args),
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1812
1835
|
if (!fsImpl.constants || typeof fsImpl.constants !== "object") {
|
|
1813
1836
|
throw ledgerError(
|
|
1814
1837
|
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
@@ -1832,6 +1855,9 @@ function realpath(fsPort, value) {
|
|
|
1832
1855
|
}
|
|
1833
1856
|
|
|
1834
1857
|
function syncDirectory(fsPort, directory) {
|
|
1858
|
+
if (typeof fsPort.syncDirectorySync === "function") {
|
|
1859
|
+
return fsPort.syncDirectorySync(directory);
|
|
1860
|
+
}
|
|
1835
1861
|
let descriptor = null;
|
|
1836
1862
|
try {
|
|
1837
1863
|
descriptor = fsPort.openSync(directory, "r");
|
|
@@ -1898,6 +1924,15 @@ function defaultAuthorityRoot(rootDir) {
|
|
|
1898
1924
|
);
|
|
1899
1925
|
}
|
|
1900
1926
|
|
|
1927
|
+
function sameArtifactIdentity(stat, expected) {
|
|
1928
|
+
const identity = artifactPhysicalIdentity(stat);
|
|
1929
|
+
return (
|
|
1930
|
+
identity.dev === expected.dev &&
|
|
1931
|
+
identity.ino === expected.ino &&
|
|
1932
|
+
identity.birthtimeMs === expected.birthtimeMs
|
|
1933
|
+
);
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1901
1936
|
export class EvolutionLedger {
|
|
1902
1937
|
#artifactResolver;
|
|
1903
1938
|
#boundaries;
|
|
@@ -1909,6 +1944,8 @@ export class EvolutionLedger {
|
|
|
1909
1944
|
#lock;
|
|
1910
1945
|
#lockClock;
|
|
1911
1946
|
#lockTimeoutMs;
|
|
1947
|
+
#localUiWindowsDurability;
|
|
1948
|
+
#pendingWindowsAclFiles;
|
|
1912
1949
|
#paths;
|
|
1913
1950
|
#random;
|
|
1914
1951
|
#secure;
|
|
@@ -1971,6 +2008,9 @@ export class EvolutionLedger {
|
|
|
1971
2008
|
);
|
|
1972
2009
|
}
|
|
1973
2010
|
|
|
2011
|
+
this.#localUiWindowsDurability =
|
|
2012
|
+
process.platform === "win32" && isLocalUiEvolutionFileSystem(fsImpl);
|
|
2013
|
+
this.#pendingWindowsAclFiles = new Map();
|
|
1974
2014
|
this.#fs = captureFs(fsImpl);
|
|
1975
2015
|
// Identity helpers only open parent/volume directories through this port.
|
|
1976
2016
|
this.#identityFs = Object.freeze({
|
|
@@ -2022,19 +2062,68 @@ export class EvolutionLedger {
|
|
|
2022
2062
|
};
|
|
2023
2063
|
|
|
2024
2064
|
try {
|
|
2025
|
-
|
|
2065
|
+
const directories = [
|
|
2026
2066
|
requestedPaths.rootDir,
|
|
2027
2067
|
requestedPaths.authorityRootDir,
|
|
2028
2068
|
requestedPaths.segmentDir,
|
|
2029
2069
|
requestedPaths.anchorDir,
|
|
2030
|
-
]
|
|
2031
|
-
|
|
2070
|
+
];
|
|
2071
|
+
if (this.#secure && this.#localUiWindowsDurability) {
|
|
2072
|
+
const roots = [
|
|
2073
|
+
requestedPaths.rootDir,
|
|
2074
|
+
requestedPaths.authorityRootDir,
|
|
2075
|
+
];
|
|
2076
|
+
const children = [
|
|
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.
|
|
2082
|
+
for (const directory of roots) {
|
|
2032
2083
|
ensurePrivateDirectory(directory, {
|
|
2033
2084
|
applyWindowsAcl: true,
|
|
2034
2085
|
failIfUnavailable: true,
|
|
2035
2086
|
});
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2087
|
+
}
|
|
2088
|
+
for (const directory of children) {
|
|
2089
|
+
ensurePrivateDirectory(directory, {
|
|
2090
|
+
applyWindowsAcl: false,
|
|
2091
|
+
failIfUnavailable: true,
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
const repaired = repairPrivatePaths(children);
|
|
2095
|
+
if (
|
|
2096
|
+
repaired.length !== children.length ||
|
|
2097
|
+
repaired.some((entry) => entry.ok !== true || entry.exists === false)
|
|
2098
|
+
) {
|
|
2099
|
+
throw new Error("Could not verify private ledger directories");
|
|
2100
|
+
}
|
|
2101
|
+
for (const directory of children) {
|
|
2102
|
+
const stat = this.#fs.lstatSync(directory);
|
|
2103
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
2104
|
+
throw new Error("Private ledger directory changed during setup");
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
} else {
|
|
2108
|
+
for (const directory of directories) {
|
|
2109
|
+
if (this.#secure) {
|
|
2110
|
+
ensurePrivateDirectory(directory, {
|
|
2111
|
+
applyWindowsAcl: true,
|
|
2112
|
+
failIfUnavailable: true,
|
|
2113
|
+
});
|
|
2114
|
+
} else {
|
|
2115
|
+
this.#fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
if (typeof this.#fs.syncDirectorySync === "function") {
|
|
2120
|
+
for (const directory of new Set([
|
|
2121
|
+
path.dirname(requestedPaths.rootDir),
|
|
2122
|
+
requestedPaths.rootDir,
|
|
2123
|
+
path.dirname(requestedPaths.authorityRootDir),
|
|
2124
|
+
requestedPaths.authorityRootDir,
|
|
2125
|
+
])) {
|
|
2126
|
+
this.#fs.syncDirectorySync(directory);
|
|
2038
2127
|
}
|
|
2039
2128
|
}
|
|
2040
2129
|
|
|
@@ -3185,7 +3274,7 @@ export class EvolutionLedger {
|
|
|
3185
3274
|
descriptor = null;
|
|
3186
3275
|
if (this.#secure) {
|
|
3187
3276
|
ensurePrivateFile(temporaryPath, {
|
|
3188
|
-
applyWindowsAcl:
|
|
3277
|
+
applyWindowsAcl: !this.#localUiWindowsDurability,
|
|
3189
3278
|
failIfUnavailable: true,
|
|
3190
3279
|
});
|
|
3191
3280
|
}
|
|
@@ -3194,12 +3283,6 @@ export class EvolutionLedger {
|
|
|
3194
3283
|
if (onPublished) onPublished(temporaryPath);
|
|
3195
3284
|
this.#fs.unlinkSync(temporaryPath);
|
|
3196
3285
|
temporaryExists = false;
|
|
3197
|
-
if (this.#secure) {
|
|
3198
|
-
ensurePrivateFile(filePath, {
|
|
3199
|
-
applyWindowsAcl: true,
|
|
3200
|
-
failIfUnavailable: true,
|
|
3201
|
-
});
|
|
3202
|
-
}
|
|
3203
3286
|
const finalStat = this.#fs.lstatSync(filePath);
|
|
3204
3287
|
if (
|
|
3205
3288
|
!finalStat.isFile() ||
|
|
@@ -3212,6 +3295,7 @@ export class EvolutionLedger {
|
|
|
3212
3295
|
`${label} publication did not produce a single-link artifact`,
|
|
3213
3296
|
);
|
|
3214
3297
|
}
|
|
3298
|
+
this.#securePublishedFile(filePath, finalStat);
|
|
3215
3299
|
descriptor = this.#fs.openSync(
|
|
3216
3300
|
filePath,
|
|
3217
3301
|
this.#fs.constants.O_RDWR | (this.#fs.constants.O_NOFOLLOW || 0),
|
|
@@ -3219,7 +3303,9 @@ export class EvolutionLedger {
|
|
|
3219
3303
|
this.#fs.fsyncSync(descriptor);
|
|
3220
3304
|
this.#fs.closeSync(descriptor);
|
|
3221
3305
|
descriptor = null;
|
|
3222
|
-
return
|
|
3306
|
+
return this.#localUiWindowsDurability
|
|
3307
|
+
? "windows-directory-flush-deferred"
|
|
3308
|
+
: syncDirectory(this.#fs, directory);
|
|
3223
3309
|
} catch (cause) {
|
|
3224
3310
|
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
3225
3311
|
throw ledgerError(
|
|
@@ -3271,18 +3357,12 @@ export class EvolutionLedger {
|
|
|
3271
3357
|
descriptor = null;
|
|
3272
3358
|
if (this.#secure) {
|
|
3273
3359
|
ensurePrivateFile(temporaryPath, {
|
|
3274
|
-
applyWindowsAcl:
|
|
3360
|
+
applyWindowsAcl: !this.#localUiWindowsDurability,
|
|
3275
3361
|
failIfUnavailable: true,
|
|
3276
3362
|
});
|
|
3277
3363
|
}
|
|
3278
3364
|
this.#fs.renameSync(temporaryPath, this.#paths.headPath);
|
|
3279
3365
|
renamed = true;
|
|
3280
|
-
if (this.#secure) {
|
|
3281
|
-
ensurePrivateFile(this.#paths.headPath, {
|
|
3282
|
-
applyWindowsAcl: true,
|
|
3283
|
-
failIfUnavailable: true,
|
|
3284
|
-
});
|
|
3285
|
-
}
|
|
3286
3366
|
const headStat = this.#fs.lstatSync(this.#paths.headPath);
|
|
3287
3367
|
if (
|
|
3288
3368
|
!headStat.isFile() ||
|
|
@@ -3295,6 +3375,7 @@ export class EvolutionLedger {
|
|
|
3295
3375
|
"HEAD replacement did not produce a single-link artifact",
|
|
3296
3376
|
);
|
|
3297
3377
|
}
|
|
3378
|
+
this.#securePublishedFile(this.#paths.headPath, headStat);
|
|
3298
3379
|
descriptor = this.#fs.openSync(
|
|
3299
3380
|
this.#paths.headPath,
|
|
3300
3381
|
this.#fs.constants.O_RDWR | (this.#fs.constants.O_NOFOLLOW || 0),
|
|
@@ -3302,7 +3383,9 @@ export class EvolutionLedger {
|
|
|
3302
3383
|
this.#fs.fsyncSync(descriptor);
|
|
3303
3384
|
this.#fs.closeSync(descriptor);
|
|
3304
3385
|
descriptor = null;
|
|
3305
|
-
return
|
|
3386
|
+
return this.#localUiWindowsDurability
|
|
3387
|
+
? "windows-directory-flush-deferred"
|
|
3388
|
+
: syncDirectory(this.#fs, this.#paths.authorityRootDir);
|
|
3306
3389
|
} catch (cause) {
|
|
3307
3390
|
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
3308
3391
|
throw ledgerError(
|
|
@@ -3332,8 +3415,108 @@ export class EvolutionLedger {
|
|
|
3332
3415
|
}
|
|
3333
3416
|
}
|
|
3334
3417
|
|
|
3418
|
+
#securePublishedFile(filePath, stat) {
|
|
3419
|
+
if (!this.#secure) return;
|
|
3420
|
+
if (this.#localUiWindowsDurability) {
|
|
3421
|
+
this.#pendingWindowsAclFiles.set(path.resolve(filePath), {
|
|
3422
|
+
identity: artifactPhysicalIdentity(stat),
|
|
3423
|
+
size: stat.size,
|
|
3424
|
+
});
|
|
3425
|
+
return;
|
|
3426
|
+
}
|
|
3427
|
+
ensurePrivateFile(filePath, {
|
|
3428
|
+
applyWindowsAcl: true,
|
|
3429
|
+
failIfUnavailable: true,
|
|
3430
|
+
});
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3433
|
+
#assertPendingWindowsAclFile(filePath, expected) {
|
|
3434
|
+
const stat = this.#fs.lstatSync(filePath);
|
|
3435
|
+
if (
|
|
3436
|
+
!stat.isFile() ||
|
|
3437
|
+
stat.isSymbolicLink() ||
|
|
3438
|
+
stat.nlink !== 1 ||
|
|
3439
|
+
stat.size !== expected.size ||
|
|
3440
|
+
!sameArtifactIdentity(stat, expected.identity)
|
|
3441
|
+
) {
|
|
3442
|
+
throw ledgerError(
|
|
3443
|
+
"CC_EVOLUTION_LEDGER_STORE_UNSAFE",
|
|
3444
|
+
"published ledger file changed before Windows ACL verification",
|
|
3445
|
+
);
|
|
3446
|
+
}
|
|
3447
|
+
return stat;
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
#flushPendingWindowsAclFiles() {
|
|
3451
|
+
if (
|
|
3452
|
+
!this.#localUiWindowsDurability ||
|
|
3453
|
+
this.#pendingWindowsAclFiles.size === 0
|
|
3454
|
+
) {
|
|
3455
|
+
return [];
|
|
3456
|
+
}
|
|
3457
|
+
const entries = [...this.#pendingWindowsAclFiles.entries()];
|
|
3458
|
+
const files = entries.map(([filePath]) => filePath);
|
|
3459
|
+
const directories = [...new Set(files.map((filePath) => path.dirname(filePath)))];
|
|
3460
|
+
try {
|
|
3461
|
+
this.#assertBoundaries();
|
|
3462
|
+
for (const [filePath, expected] of entries) {
|
|
3463
|
+
this.#assertPendingWindowsAclFile(filePath, expected);
|
|
3464
|
+
}
|
|
3465
|
+
const repaired = repairPrivatePaths(files);
|
|
3466
|
+
if (
|
|
3467
|
+
repaired.length !== files.length ||
|
|
3468
|
+
repaired.some(
|
|
3469
|
+
(entry, index) =>
|
|
3470
|
+
entry.target !== files[index] ||
|
|
3471
|
+
entry.ok !== true ||
|
|
3472
|
+
entry.exists === false,
|
|
3473
|
+
)
|
|
3474
|
+
) {
|
|
3475
|
+
throw new Error("Windows ACL batch did not verify every ledger file");
|
|
3476
|
+
}
|
|
3477
|
+
for (const [filePath, expected] of entries) {
|
|
3478
|
+
this.#assertPendingWindowsAclFile(filePath, expected);
|
|
3479
|
+
const descriptor = this.#fs.openSync(
|
|
3480
|
+
filePath,
|
|
3481
|
+
this.#fs.constants.O_RDWR | (this.#fs.constants.O_NOFOLLOW || 0),
|
|
3482
|
+
);
|
|
3483
|
+
try {
|
|
3484
|
+
const opened = this.#fs.fstatSync(descriptor);
|
|
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",
|
|
3494
|
+
);
|
|
3495
|
+
}
|
|
3496
|
+
this.#fs.fsyncSync(descriptor);
|
|
3497
|
+
} finally {
|
|
3498
|
+
this.#fs.closeSync(descriptor);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
this.#assertBoundaries();
|
|
3502
|
+
for (const filePath of files) this.#pendingWindowsAclFiles.delete(filePath);
|
|
3503
|
+
return directories;
|
|
3504
|
+
} catch (cause) {
|
|
3505
|
+
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
3506
|
+
throw ledgerError(
|
|
3507
|
+
"CC_EVOLUTION_LEDGER_WRITE_FAILED",
|
|
3508
|
+
"published ledger files could not be secured before witness commit",
|
|
3509
|
+
{ cause, commitState: "not-committed", published: true },
|
|
3510
|
+
);
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3335
3514
|
#requireDirectoryDurability(directories) {
|
|
3336
|
-
|
|
3515
|
+
const mechanisms = new Set();
|
|
3516
|
+
const durableDirectories = [
|
|
3517
|
+
...new Set([...directories, ...this.#flushPendingWindowsAclFiles()]),
|
|
3518
|
+
];
|
|
3519
|
+
for (const directory of durableDirectories) {
|
|
3337
3520
|
let mechanism;
|
|
3338
3521
|
try {
|
|
3339
3522
|
mechanism = syncDirectory(this.#fs, directory);
|
|
@@ -3344,14 +3527,21 @@ export class EvolutionLedger {
|
|
|
3344
3527
|
{ cause, commitState: "not-committed" },
|
|
3345
3528
|
);
|
|
3346
3529
|
}
|
|
3347
|
-
if (
|
|
3530
|
+
if (
|
|
3531
|
+
mechanism !== "directory-fsync" &&
|
|
3532
|
+
mechanism !== "windows-directory-flush"
|
|
3533
|
+
) {
|
|
3348
3534
|
throw ledgerError(
|
|
3349
3535
|
"CC_EVOLUTION_LEDGER_DURABILITY_UNAVAILABLE",
|
|
3350
3536
|
"the platform cannot durably publish ledger objects before witness CAS",
|
|
3351
3537
|
{ commitState: "not-committed", mechanism },
|
|
3352
3538
|
);
|
|
3353
3539
|
}
|
|
3540
|
+
mechanisms.add(mechanism);
|
|
3354
3541
|
}
|
|
3542
|
+
return mechanisms.has("windows-directory-flush")
|
|
3543
|
+
? "windows-directory-flush"
|
|
3544
|
+
: "directory-fsync";
|
|
3355
3545
|
}
|
|
3356
3546
|
|
|
3357
3547
|
#cleanupDirectoryDebris(directory, targetPattern) {
|
|
@@ -3566,6 +3756,11 @@ export class EvolutionLedger {
|
|
|
3566
3756
|
serializeRecord(storeMarker, 64 * 1024, "store marker"),
|
|
3567
3757
|
"store incarnation marker",
|
|
3568
3758
|
);
|
|
3759
|
+
if (this.#localUiWindowsDurability) {
|
|
3760
|
+
this.#requireDirectoryDurability([
|
|
3761
|
+
path.dirname(this.#paths.storeMarkerPath),
|
|
3762
|
+
]);
|
|
3763
|
+
}
|
|
3569
3764
|
const storeMarkerFile = this.#readCanonicalFile(
|
|
3570
3765
|
this.#paths.storeMarkerPath,
|
|
3571
3766
|
64 * 1024,
|
|
@@ -4881,6 +5076,7 @@ export class EvolutionLedger {
|
|
|
4881
5076
|
state.event = state.events.at(-1);
|
|
4882
5077
|
const witnessedStates = [];
|
|
4883
5078
|
let currentWitness = current.witness;
|
|
5079
|
+
let platformDurabilityMechanism = "directory-fsync";
|
|
4884
5080
|
for (const entry of planned) {
|
|
4885
5081
|
const { anchor, anchorBytes, event, eventBytes, segmentDigest } =
|
|
4886
5082
|
entry;
|
|
@@ -4922,7 +5118,7 @@ export class EvolutionLedger {
|
|
|
4922
5118
|
anchorDigest: anchor.anchorDigest,
|
|
4923
5119
|
eventDigest: event.eventDigest,
|
|
4924
5120
|
});
|
|
4925
|
-
this.#requireDirectoryDurability([
|
|
5121
|
+
platformDurabilityMechanism = this.#requireDirectoryDurability([
|
|
4926
5122
|
this.#paths.segmentDir,
|
|
4927
5123
|
this.#paths.anchorDir,
|
|
4928
5124
|
]);
|
|
@@ -4948,6 +5144,12 @@ export class EvolutionLedger {
|
|
|
4948
5144
|
});
|
|
4949
5145
|
}
|
|
4950
5146
|
|
|
5147
|
+
if (this.#localUiWindowsDurability) {
|
|
5148
|
+
platformDurabilityMechanism = this.#requireDirectoryDurability([
|
|
5149
|
+
this.#paths.authorityRootDir,
|
|
5150
|
+
]);
|
|
5151
|
+
}
|
|
5152
|
+
|
|
4951
5153
|
const persisted = this.#loadState({
|
|
4952
5154
|
allowInitialize: false,
|
|
4953
5155
|
incremental: true,
|
|
@@ -4973,9 +5175,13 @@ export class EvolutionLedger {
|
|
|
4973
5175
|
{ ...persisted, witness: witnessedStates[index] },
|
|
4974
5176
|
event,
|
|
4975
5177
|
planned[index].anchor,
|
|
4976
|
-
|
|
4977
|
-
?
|
|
4978
|
-
|
|
5178
|
+
platformDurabilityMechanism === "windows-directory-flush"
|
|
5179
|
+
? batch
|
|
5180
|
+
? "authenticated-witness-batch-cas-windows-directory-flush"
|
|
5181
|
+
: "authenticated-witness-cas-windows-directory-flush"
|
|
5182
|
+
: batch
|
|
5183
|
+
? "authenticated-witness-batch-cas"
|
|
5184
|
+
: "authenticated-witness-cas",
|
|
4979
5185
|
),
|
|
4980
5186
|
);
|
|
4981
5187
|
state.receipt = state.receipts.at(-1);
|
|
@@ -5152,6 +5358,9 @@ export class EvolutionLedger {
|
|
|
5152
5358
|
"state snapshot",
|
|
5153
5359
|
);
|
|
5154
5360
|
this.#writeImmutable(snapshotPath, bytes, "state snapshot");
|
|
5361
|
+
if (this.#localUiWindowsDurability) {
|
|
5362
|
+
this.#requireDirectoryDurability([path.dirname(snapshotPath)]);
|
|
5363
|
+
}
|
|
5155
5364
|
const persisted = this.#readCanonicalFile(
|
|
5156
5365
|
snapshotPath,
|
|
5157
5366
|
MAX_STATE_SNAPSHOT_BYTES,
|