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.
Files changed (206) hide show
  1. package/README.md +6 -4
  2. package/package.json +3 -2
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-DkrNbDzS.js → AIOps-sOceeExN.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-DJjFXDhv.js → ActionButton-BQs-vRUr.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DyUbagRn.js → Analytics-sfAHHMhA.js} +2 -2
  8. package/src/assets/web-panel/assets/{AppLayout-p7kJWSvn.js → AppLayout-0gAvE0c8.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-C3rVh4Ak.js → Artifacts-Dh9s2Qmd.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-Bch_L_YO.js → Audit-CITm26SU.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-BNHy8zP6.js → BackgroundAgents-BiMbBOh0.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-BUaye_Ys.js → Backup-CNpnhI3h.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-D49mzAVz.js → BaseInput-BI_lltkp.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-2MDzM_us.js → Chat-BgfB88xY.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-BDP3fGoz.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-5p1T_KEq.js → Checkbox-4xy9rS3j.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-TKtiLaoZ.js → Codegen-D93h9ihS.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-BVCMG9mS.js → Col-BRf3STY-.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-D09-QczH.js → Community-f187ziSL.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-QuRMCnj7.js → Compact-D4hXWuo1.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CN0PV7fk.js → Compliance-C6cYKI6H.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-5N2zhAty.js → Cowork-C1i1f8LD.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-BxT8UZ0S.js → Cron-BacCE4LA.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-Dp-noQl4.js → Crosschain-DXztxOoH.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-B7MZFkjG.js → DID-rpf4HN8x.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-DulJ3rKV.js → Dashboard-h4bgtH7L.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-DV4ov4zF.js → Dropdown-CyQnoHmu.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DB2-ooz6.js → EmailListRenderer-FCtp4AcB.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-B1Rb6p7q.js → EvolutionSettings-JbISHTWR.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-U8aHayx-.js → FamilyGuardDashboard-DCIQLyfK.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BkQULBHY.js → Federation-DDbFpwja.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-CtviG260.js → FormItemContext-CXF0jtXb.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DnPirB24.js → GenericCardRenderer-CUaNfAM0.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CK57Oro6.js → Git-Bhoz2gDf.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-DbI-LB8-.js → Governance-FiiXHe8e.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-sEG4T1Jg.js → Inference-brpTW2Q3.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-9SLJR3h9.js → KnowledgeGraph-BCWP-f6k.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BIZYcISQ.js → Logs-CxYcduoK.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-12vD1nC1.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CRmLLwAE.js → Marketplace-DANdmW7l.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-DkOFkSO1.js → McpTools-Bi_EKkb5.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-M29Kd9TU.js → Memory-DecoMbYw.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Tl6JvPw_.js → MobileBridge-DrOhFKp0.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-rRwP16dN.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-DkUjX1F5.js → Mtc-SLPII1iw.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-BCqr1I4q.js → MtcAudit-DWoVORYy.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-DmoqYGQ5.js → Multisig-Dxpnmq-m.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DNRQeRke.js → NLProgramming-kNTpNqCP.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-CQSBeiY6.js → Notes-D1uXCfVd.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-gNY9bbH6.js → NotificationSettings-D3Qt8Gkl.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-DW0CNjh8.js → OrderTableRenderer-qvaah2-m.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-CthnbKag.js → Organization-EhRl4JoJ.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-_GQ3sbXu.js → Overflow-BTt5C_5W.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-BTr7ea6W.js → P2P-CeR2jyb0.js} +2 -2
  55. package/src/assets/web-panel/assets/PdhVaultBrowser-BzD3OHWq.js +7 -0
  56. package/src/assets/web-panel/assets/{Permissions-DMny2Cjs.js → Permissions-BOPyeRlz.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-CyYlMSoI.js → PersonalDataHub-DcmNNsfO.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-FASu2Oc4.js → Pipeline-DuL3kwWC.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-9bC5FnsJ.js → Privacy-CkQRdlSU.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BOYZwB5G.js → ProjectInit-moE_vQ1P.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-45DViNG-.js → ProjectSettings-PnTWi4NQ.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-C2fZzMZc.js → Projects-DZvbT3D7.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BgjvZx9F.js → Providers-CkcrHYy9.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-Brw-3csB.js → QrScannerModal-nYNFGf_H.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-DWG-A5zB.js → QuickAsk-53WNo7xT.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DuQGxjIR.js → Recommend-CmYN_NaS.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-T1cdSSRL.js → RemoteSession-BuOdNEjA.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-9FT2dI4G.js → Reputation-BgkheZou.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-yNIbNftX.js → Row-DvA3klj1.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-BIchNoPd.js → RssFeed-CgkIL3PG.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-msDJ8UTZ.js → Search-Cv2twJdL.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-DE46oBYT.js → Security-XrD2UNU6.js} +2 -2
  73. package/src/assets/web-panel/assets/{Services-Dori7vc3.js → Services-LujCntCK.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-D3O3sUFz.js → Skeleton-ZZCOsxPX.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-BV0ct8SO.js → Skills-BEXGkOrU.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-DflIVOrh.js → Sla-CIqmCgdD.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Cpbv2Zz6.js → SpeechSettings-DkVbwJox.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-Dgg6-wbe.js → SyncSettings-BVGgUs0p.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-Cb6e4Klx.js → Tasks-C1lh68l5.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-GfdAATGz.js → Templates-BG4zNAFx.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-D0gecLXl.js → Tenant-t2o6i5fY.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BFRPJt-0.js → Terminal-CH8UDdVO.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BobtChxX.js → TimelineRenderer-B5sYY1IO.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-CifeZtHV.js → Tokens-D0y7QkG5.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-BHBvbBCf.js → Trigger-BA2nKko0.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-6lvqjKYp.js → Trust-CrFKCQIs.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CqzMc-G5.js → UkeySign-B3x_-Zun.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-OIiRG582.js → VideoEditing-TEwxbLH6.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-4MeKq0q_.js → Wallet-Larp5rrt.js} +2 -2
  90. package/src/assets/web-panel/assets/{WebAuthn-eHBRjGQG.js → WebAuthn-DfWbEIZe.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-DlzYdEqW.js → WorkflowEditor-8LKiKExY.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CBcjOzkX.js → chat-ByxYOvYW.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-zgwsYQSa.js → colors-Dh4yAClh.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Dcd9H5Bn.js → compact-item-f5n2j1WZ.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DR1tO-8r.js → createContext-DIprYuXL.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-DRIge35Z.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CtfbUH_p.js → hasIn-CvYeap2I.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-D1GxtY-h.js → index-3ROY-lYB.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CT7zIkqP.js → index-6VEWxOyC.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Cdhy5ckh.js → index-7eG1J-GT.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DvPOpvvH.js → index-B0AXUhiJ.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cur8LNNn.js → index-BS_dpgzu.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DWG98orp.js → index-BaXSBxy-.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C5XGvJb0.js → index-Bk8oWRk6.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DA2-Bhy8.js → index-BlImvgb7.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CwHgaYVH.js → index-BoayvJ48.js} +1 -1
  107. package/src/assets/web-panel/assets/index-Bq24rTYx.js +1 -0
  108. package/src/assets/web-panel/assets/{index-DHEiuvhA.js → index-BsU46c7D.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DSvcz0RO.js → index-BvyFQF8I.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-D7ZOiIKb.js → index-C2RGykST.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CmzQzTY5.js → index-C5aH2Pj2.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-oWOlF7CM.js → index-CD0s5ESV.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DVpp9YSQ.js → index-CIZQtz8G.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DWuCGhHa.js → index-CJjc8ObW.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-JSfldpw4.js → index-CTqJNul4.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-dvF6C39V.js → index-CcvA1nae.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CmVIM-m2.js → index-CpR0zD38.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CaGNqkY0.js → index-CzabQZ7I.js} +1 -1
  119. package/src/assets/web-panel/assets/index-D2f18WsK.js +1 -0
  120. package/src/assets/web-panel/assets/{index-BXfGHUz_.js → index-DGyTzElU.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-LN7Hkl1C.js → index-DI8jC7gQ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DfzOYmOj.js → index-DUj-sL9U.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BoxowMYS.js → index-DaZVtafQ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CSQCHpDo.js → index-DjvON8oh.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B3QUK1ks.js → index-DlJCDpeN.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-J-ORW1i6.js → index-DlTwZIeX.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-z8lrkcb-.js → index-DlULGx8u.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-hTcre7U9.js → index-DmcAL4hd.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DYPMJ5Mb.js → index-DshB3-Up.js} +3 -3
  130. package/src/assets/web-panel/assets/{index-5XaB_Tjg.js → index-Du435yzt.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C0kP88Pb.js → index-bt-0zMmH.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D8WPohye.js → index-c_CxUQl3.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DeAi4CNt.js → index-fpWv4u3Z.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BndPtS9D.js → index-hwbaD3Nk.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DTx4FyLU.js → index-uDiVjYrS.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CPLLgPxA.js → index-xU0eHLIH.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-CVMtDrWZ.js → initDefaultProps-DRuE92W6.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-Dye3IU8k.js → motion-6Sgma5Vd.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-C251Zo34.js → move-BbQsH8sb.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BDiOORoQ.js → mtc-parser-BdC4INal.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DTDA_RHv.js → omit-DeC5m_bi.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-CqEUTPcT.js → pickAttrs-DuehpBws.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BOB8QWH3.js → placementArrow-CJEhv2ij.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-CZDXP1d9.js → responsiveObserve-Dyw3lDGr.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-DPaRw3E9.js → slide-BMaLXTbS.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-Ba9d7XZ7.js → statusUtils-c1K_SdJH.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-mZKU3lvW.js → styleChecker-CefBry8k.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-VcauLq0M.js → useFlexGapSupport-Dj2IsZpo.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Cal9KRcx.js → useFs-RLfB3yqb.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-DISoRyQB.js → usePersonalDataHub-DbRVH_NA.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-B58C6w6B.js → vnode-DTn_QVJz.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-BPlBAMKB.js → zoom-DuFR0E7i.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/agent.js +12 -5
  156. package/src/commands/ask.js +96 -21
  157. package/src/commands/complete.js +14 -10
  158. package/src/commands/llm.js +23 -41
  159. package/src/commands/session.js +2 -2
  160. package/src/commands/stream.js +9 -5
  161. package/src/commands/ui.js +30 -2
  162. package/src/data/changelog.json +39 -0
  163. package/src/gateways/ws/llm-chat-protocol.js +18 -10
  164. package/src/gateways/ws/llm-creds.js +29 -79
  165. package/src/gateways/ws/ws-agent-handler.js +1 -1
  166. package/src/gateways/ws/ws-session-gateway.js +26 -12
  167. package/src/lib/__tests__/provider-stream.test.js +70 -4
  168. package/src/lib/chat-core.js +186 -24
  169. package/src/lib/cowork-adapter.js +29 -15
  170. package/src/lib/evolution/agent-evolution-runtime-composition.js +10 -7
  171. package/src/lib/evolution/evolution-deployment-config.js +27 -4
  172. package/src/lib/evolution/evolution-deployment-loader.js +58 -3
  173. package/src/lib/evolution/evolution-deployment-profile.js +2 -2
  174. package/src/lib/evolution/evolution-evidence-projector.js +18 -3
  175. package/src/lib/evolution/evolution-file-witness.js +10 -0
  176. package/src/lib/evolution/evolution-ledger.js +237 -28
  177. package/src/lib/evolution/evolution-windows-directory-durability.js +322 -0
  178. package/src/lib/evolution/governed-hub-llm.js +2 -1
  179. package/src/lib/evolution/governed-model-turn.js +4 -1
  180. package/src/lib/evolution/local-ui-evolution-deployment.js +682 -0
  181. package/src/lib/evolution/local-ui-evolution-host.mjs +26 -0
  182. package/src/lib/evolution/local-ui-evolution-runtime.js +601 -0
  183. package/src/lib/evolution/opaque-hex-id.js +28 -0
  184. package/src/lib/hub-llm-client.js +22 -14
  185. package/src/lib/image-input.js +19 -3
  186. package/src/lib/llm-config-defaults.js +19 -30
  187. package/src/lib/llm-connection-config.js +4 -0
  188. package/src/lib/llm-connection-probe.js +5 -1
  189. package/src/lib/llm-connection-resolution.js +94 -0
  190. package/src/lib/llm-providers.js +33 -11
  191. package/src/lib/ollama-base-url.js +14 -0
  192. package/src/lib/provider-protocol.js +104 -0
  193. package/src/lib/provider-stream.js +163 -4
  194. package/src/lib/runnable-provider.js +1 -0
  195. package/src/repl/chat-repl.js +58 -11
  196. package/src/runtime/agent-core.js +26 -43
  197. package/src/runtime/headless-runner.js +11 -4
  198. package/src/runtime/headless-stream.js +10 -4
  199. package/src/runtime/policies/agent-policy.js +17 -11
  200. package/src/assets/web-panel/assets/ChatBubbleRenderer-DOX3Y5EJ.js +0 -1
  201. package/src/assets/web-panel/assets/MarkdownRenderer-9nfWupWP.js +0 -1
  202. package/src/assets/web-panel/assets/MobileProjects-Bq-FPDzS.js +0 -1
  203. package/src/assets/web-panel/assets/PdhVaultBrowser-D9McHF9I.js +0 -7
  204. package/src/assets/web-panel/assets/devWarning-DYhpRtve.js +0 -1
  205. package/src/assets/web-panel/assets/index-DPJXFIY7.js +0 -1
  206. 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 { ensurePrivateDirectory, ensurePrivateFile } from "../secure-fs.js";
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
- for (const directory of [
2065
+ const directories = [
2026
2066
  requestedPaths.rootDir,
2027
2067
  requestedPaths.authorityRootDir,
2028
2068
  requestedPaths.segmentDir,
2029
2069
  requestedPaths.anchorDir,
2030
- ]) {
2031
- if (this.#secure) {
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
- } else {
2037
- this.#fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
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: true,
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 syncDirectory(this.#fs, directory);
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: true,
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 syncDirectory(this.#fs, this.#paths.authorityRootDir);
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
- for (const directory of directories) {
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 (mechanism !== "directory-fsync") {
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
- batch
4977
- ? "authenticated-witness-batch-cas"
4978
- : "authenticated-witness-cas",
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,