chainlesschain 0.166.91 → 0.166.92

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 (209) hide show
  1. package/README.md +17 -17
  2. package/package.json +3 -3
  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-DgV7xb8F.js → AIOps-C74YzqwJ.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CgANpkKu.js → ActionButton-TFef1hOE.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DnvpX7RB.js → Analytics-CYsWpkkU.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-C2bHccBM.js → AppLayout-CFf9kjwu.js} +3 -3
  9. package/src/assets/web-panel/assets/{Artifacts-BIhijC9g.js → Artifacts-TQqa94YO.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-CKRjWGdp.js → Audit-B79ayqfS.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CblYtgBE.js → BackgroundAgents-pjkHfLP9.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-Cq35b78a.js → Backup-CE6A-t_r.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-DcB7NoRz.js → BaseInput-CwcgWMBY.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-tc3b-s7i.js → Chat-BIkDNesY.js} +6 -6
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-DgaokYts.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BLD5bH5u.js → Checkbox-MbypIy5V.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BLOsoazN.js → Codegen-DiFHWDnt.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-Bdr7JwIx.js → Col-BNMlYMso.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-C84BsWE0.js → Community-B3HVyHOX.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-Dzdwd04z.js → Compact-C7hlAubb.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CCG-R0EV.js → Compliance-PaXZu6sE.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BYj72SK0.js → Cowork-BGiojbm-.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-B6iKAwOf.js → Cron-Bmr-1QAx.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BJ-oDC6u.js → Crosschain-BwUvWCVd.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-BnMckGLr.js → DID-k_4QZocW.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-Cyje-gCO.js → Dashboard-_ieRo2C5.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BpNlenjK.js → Dropdown-DYHh6T27.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BhonO7Nv.js → EmailListRenderer-BNlQcWQX.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DVoNU-Id.js → EvolutionSettings-DIkZ6U2D.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-tdn-KC67.js → FamilyGuardDashboard-Dq7qSr0P.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation--EEVrHhz.js → Federation-C64e3Cbx.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Cy8zr0-4.js → FormItemContext-D-GE2vUa.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-BuUhpgFi.js → GenericCardRenderer-DO3B2gis.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-Ctd3E5Pe.js → Git-0ETirIQH.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Ce7dV6aU.js → Governance-C9fnRygX.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CD1vExIH.js → Inference-CLJ9RTsK.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-Dn64OdQ7.js → KnowledgeGraph-D3C_GxrN.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-PmElVRrT.js → Logs-C5ctGbkN.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-Ce-eWK3j.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-OW4jTXwx.js → Marketplace-GF_t6hJ_.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BEq2Ib4x.js → McpTools-BGsGzgQs.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Can_P2oK.js → Memory-CcrY2A0j.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DJ8R-dn3.js → MobileBridge-Bi4T0RlS.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-B7kV9GOt.js → MobileProjects-DvjEGyvf.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-BfxamolS.js → Mtc-DL77Vf-k.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-DHtuv7av.js → MtcAudit-CDy_Uswb.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-DLkLpvxc.js → Multisig-DL0BAO_c.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-u4XtJTIt.js → NLProgramming-B-woh5IR.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BwuuPJLS.js → Notes-CEFVCxk7.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-HEeu-E9v.js → NotificationSettings-BqPPMuAP.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-BtvN-Qwh.js → OrderTableRenderer-GUKQ1xwp.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-Yh-czs3b.js → Organization-B1gX8jlr.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DmE8mYVM.js → Overflow-CeMxuUZy.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CWVck8WN.js → P2P-B5aIRWwJ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DgFqekod.js → PdhVaultBrowser-6rYgejd4.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-BtJBVOHV.js → Permissions-CqCp2SIl.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-6VBObXzd.js → PersonalDataHub-BsA7DJWW.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-D222FmqY.js → Pipeline-CiW6HeZh.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Bi9FMikp.js → Privacy-DckUOLYq.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-Bo52H47H.js → ProjectInit-CZppOOYR.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BPkesfOc.js → ProjectSettings-B9QPzhDU.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-GynohSFX.js → Projects-BErjjGha.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-DVdMg04n.js → Providers-DehU6Qiz.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-DqJCb595.js → QrScannerModal-E1SUvv1m.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-J7loQbXi.js → QuickAsk-COWFxyH3.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BI5aURVc.js → Recommend-D26pWKxX.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BN2sqGvz.js → RemoteSession-DCOIaId3.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BGOND-Fi.js → Reputation-DT_AHGAR.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-77dfwaUk.js → Row-B50S-1nl.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-FtBAxS3g.js → RssFeed-BaBnHg3Q.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BaYVLFb7.js → Search-BVdnLuuS.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-LE3Vv6ab.js → Security-BnacH74J.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-C5pP-Whz.js → Services-CxM08Zch.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CLqKUVsF.js → Skeleton-DE7CIc1N.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-BPjN0SX5.js → Skills-CGI0SJmf.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-14jD70kg.js → Sla-DpEzPcqc.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Dr9ij42W.js → SpeechSettings-CTmnmMHn.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BzLHP7B8.js → SyncSettings-Dxgrd9hd.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-YqV9b0rV.js → Tasks-CW4slS0A.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-CxxAE4PK.js → Templates-DxvGWDgB.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CRb3PcKJ.js → Tenant-_Q0o2tNK.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CTzPpBaP.js → Terminal-BTZn8pow.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DjFUj_hy.js → TimelineRenderer-CauL0KFe.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Bbb8tPvx.js → Tokens-CDoM2qeT.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CSeWGM0W.js → Trigger-B-QYGEU7.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-JgESMBo3.js → Trust-BD6XJHT-.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CiObLk0T.js → UkeySign-x4TFwCy0.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CFEZaQ2x.js → VideoEditing-t3imBK_0.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-DR8ZGDNn.js → Wallet-BCfkWwNC.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DxZukvu7.js → WebAuthn-WH314Mdm.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CKgSZQwn.js → WorkflowEditor-jUlcjrUg.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CTxEQE66.js → chat-Dg3VASTL.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CAjKMUu3.js → colors-BNvmBRKE.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-BXuz49at.js → compact-item-BGOfoqf4.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-CFN_Hwr9.js → createContext-BNQeqKAs.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-B7_ypN1G.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BwoSBSfP.js → hasIn-Bg3AjCrq.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-u9_DM3ZC.js → index--I3UF5t1.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-IahILygB.js → index-2D04Zltx.js} +3 -3
  100. package/src/assets/web-panel/assets/{index-Bqv_Cray.js → index-60AnjUTX.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CSmFby3Q.js → index-7QJUWemf.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DTX9CJPx.js → index-B--0QM0S.js} +1 -1
  103. package/src/assets/web-panel/assets/index-B-jSKJK6.js +1 -0
  104. package/src/assets/web-panel/assets/{index-C8er4W9u.js → index-B0mgngoB.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DViK2bkv.js → index-BBCMulQ-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DmkbAADP.js → index-BSNhW95G.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B2tEnBPx.js → index-B_JmInC0.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-_ZtCyUdz.js → index-BaPvEvB4.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CN53dE_u.js → index-Bkz1tgFR.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Bj4hIiLW.js → index-BmTacaQV.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Tz5dheZa.js → index-CCFZN66A.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Dv7V2kg6.js → index-COol3xfA.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bu2P6u8m.js → index-CY8cRKHR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bw9s2d3c.js → index-Cbp-wp-U.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-B9yR7zqr.js → index-Co_LnCWD.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BK4ftQ4d.js → index-Cx2EXRfr.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DxunxaTw.js → index-D-mSvCQK.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B7kp-zRE.js → index-D072oLjp.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CB3kVd9c.js → index-D6UqK83L.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CF9lWi1o.js → index-DF_FKSVH.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-IY9bd5az.js → index-DLwEXRrb.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-F2E5RCwz.js → index-DO0VlNtc.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-B2o_BBjg.js → index-DS04wRll.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DY-gBSm8.js → index-DYn5DnDk.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B0QbLlWn.js → index-D_O2ZjPk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DjF5BOZx.js → index-DcCnO0RU.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CehdwJ_Q.js → index-Dkp-okWa.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BmXpdcHI.js → index-OUFoxUgH.js} +1 -1
  129. package/src/assets/web-panel/assets/index-P4FXZJqI.js +1 -0
  130. package/src/assets/web-panel/assets/{index-t2Ch_JKn.js → index-Wo0f2iqb.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-T3MTE6jB.js → index-ZD5Kd8tx.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Cp5y7lX_.js → index-fOwii3LP.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Cgk0YEiq.js → index-hG7jXGEW.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-DpdDnZX_.js → index-pVdQieac.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-o9DpkZKf.js → index-uH2LnAs_.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-BmQITjMU.js → index-xzaUx19r.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-BoiGJDoO.js → initDefaultProps-B8PN9AxJ.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-5eL4E0pA.js → motion-BHivfw5Q.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-DjggDi_1.js → move-B0QU5nDd.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Ce8Vo2T3.js → mtc-parser-DRwRM3PE.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-D1yOBaO2.js → omit-SHt2rV2p.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-8NLceQe8.js → pickAttrs-CcmDlEb2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CsIdBRmQ.js → placementArrow-DYatmXDS.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-GM5NE8En.js → responsiveObserve-B7qrsXq5.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-44yj3u49.js → slide-BRGhlOWd.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-B8tqtWcX.js → statusUtils-CT-7NXsQ.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-NhDPBbyB.js → styleChecker-rZdw_Yyp.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-C8Qz1GtN.js → useFlexGapSupport-D8YNIP4P.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-ClUv4kih.js → useFs-B8pt0Gu-.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BwkOVEh6.js → usePersonalDataHub-VMmYM1tt.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode--gMF33R0.js → vnode-UNDuoPoq.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DXg3TqOP.js → zoom-dN-u667S.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +39 -0
  155. package/src/lib/evolution/evolution-artifact-ports.js +26 -0
  156. package/src/lib/evolution/evolution-eval-cohort-enrollment.js +713 -47
  157. package/src/lib/evolution/evolution-eval-gate.js +146 -0
  158. package/src/lib/evolution/evolution-eval-launch-admission.js +168 -90
  159. package/src/lib/evolution/evolution-eval-ledger-capture.js +50 -0
  160. package/src/lib/evolution/evolution-eval-readonly-audit.js +106 -0
  161. package/src/lib/evolution/evolution-ledger-file-backend.js +20 -0
  162. package/src/lib/evolution/evolution-ledger-ports.js +59 -27
  163. package/src/lib/evolution/evolution-ledger-v2-journal.js +55 -18
  164. package/src/lib/evolution/evolution-workbench-file-resources.js +19 -1
  165. package/src/lib/evolution/rrsi-cohort-registration.js +275 -0
  166. package/src/lib/evolution/rrsi-contracts.js +742 -0
  167. package/src/lib/evolution/rrsi-data.js +196 -0
  168. package/src/lib/evolution/rrsi-evaluation-adapter.js +275 -0
  169. package/src/lib/evolution/rrsi-evaluation-variants.js +267 -0
  170. package/src/lib/evolution/rrsi-group-statistics.js +553 -0
  171. package/src/lib/evolution/rrsi-history-ledger-adapter.js +3261 -0
  172. package/src/lib/evolution/rrsi-native-batch-evidence.js +520 -0
  173. package/src/lib/evolution/rrsi-native-eval-row-collector.js +538 -0
  174. package/src/lib/evolution/rrsi-native-evaluation-batch.js +547 -0
  175. package/src/lib/evolution/rrsi-native-evaluation-plan.js +431 -0
  176. package/src/lib/evolution/rrsi-native-group-statistics-plan.js +121 -0
  177. package/src/lib/evolution/rrsi-native-group-statistics.js +482 -0
  178. package/src/lib/evolution/rrsi-native-quality-receipt-contracts.js +321 -0
  179. package/src/lib/evolution/rrsi-native-quality-receipt.js +256 -0
  180. package/src/lib/evolution/rrsi-native-statistics-protocol.js +330 -0
  181. package/src/lib/evolution/rrsi-parent-binding.js +290 -0
  182. package/src/lib/evolution/rrsi-pm-execution-bridge.js +500 -0
  183. package/src/lib/evolution/rrsi-pm-training-mapping.js +134 -0
  184. package/src/lib/evolution/rrsi-preparation-contracts.js +213 -0
  185. package/src/lib/evolution/rrsi-registry-history-binding.js +193 -0
  186. package/src/lib/evolution/rrsi-registry-store-policy.js +1191 -0
  187. package/src/lib/evolution/rrsi-runtime-composition.js +79 -0
  188. package/src/lib/evolution/rrsi-selector.js +434 -0
  189. package/src/lib/evolution/rrsi-statistics-simulation.js +354 -0
  190. package/src/lib/evolution/skill-candidate-registry.js +216 -29
  191. package/src/lib/evolution/skill-registry-maintenance.js +80 -0
  192. package/src/lib/evolution/skill-registry-writer-control.js +138 -0
  193. package/src/lib/evolution/skill-release-registry.js +399 -169
  194. package/src/lib/formal-quality-eval-runtime.js +2 -14
  195. package/src/lib/goal-store.js +225 -16
  196. package/src/lib/record-replay/skill-recorder.js +38 -3
  197. package/src/lib/scheduler-kernel/authority-resolver.js +12 -163
  198. package/src/lib/scheduler-kernel/contract.js +27 -414
  199. package/src/lib/scheduler-kernel/runtime.js +21 -823
  200. package/src/lib/scheduler-kernel/service.js +11 -328
  201. package/src/lib/scheduler-kernel/source-locator-path.js +7 -142
  202. package/src/lib/scheduler-kernel/store.js +67 -5931
  203. package/src/lib/secure-fs.js +16 -1314
  204. package/src/lib/with-file-lock.js +122 -20
  205. package/src/assets/web-panel/assets/ChatBubbleRenderer-fcc_Tvqu.js +0 -1
  206. package/src/assets/web-panel/assets/MarkdownRenderer-BFiVKf5t.js +0 -1
  207. package/src/assets/web-panel/assets/devWarning-CfB8DxT2.js +0 -1
  208. package/src/assets/web-panel/assets/index-CCsRfd0k.js +0 -1
  209. package/src/assets/web-panel/assets/index-CsmiZIQ4.js +0 -1
@@ -0,0 +1,1191 @@
1
+ /** Authenticated fresh store provisioning, before any Registry is constructed.
2
+ * This installs a writer floor, not content-origin or business admission.
3
+ * Existing stores and ambiguous partial publication are never adopted.
4
+ */
5
+ import { randomUUID } from "node:crypto";
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { isProxy } from "node:util/types";
9
+ import {
10
+ repairPrivatePath,
11
+ ensurePrivateFile,
12
+ inspectPrivatePath,
13
+ } from "../secure-fs.js";
14
+ import { withFileLock } from "../with-file-lock.js";
15
+ import { withEvolutionFileIdentity } from "./evolution-file-identity.js";
16
+ import { readBoundedDescriptor } from "./bounded-descriptor-read.js";
17
+ import {
18
+ captureEvolutionLedgerFileBackend,
19
+ captureEvolutionLedgerFileBackendBinding,
20
+ } from "./evolution-ledger-file-backend.js";
21
+ import { isEvolutionLedgerV2Journal } from "./evolution-ledger-v2-journal.js";
22
+ import {
23
+ EVOLUTION_LEDGER_MAX_EVENTS,
24
+ EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
25
+ EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
26
+ EVOLUTION_ARTIFACT_REF_SCHEMA,
27
+ } from "./evolution-ledger.js";
28
+ import {
29
+ EvolutionArtifactPorts,
30
+ EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
31
+ captureEvolutionLedgerArtifactResolverBinding,
32
+ } from "./evolution-artifact-ports.js";
33
+ import { deriveSkillCandidateTenantKey } from "./skill-candidate-registry.js";
34
+ import { deriveSkillReleaseTenantKey } from "./skill-release-registry.js";
35
+ import { captureSkillReleaseOperationReader } from "./evolution-ledger-ports.js";
36
+ import {
37
+ snapshotRrsiData,
38
+ rrsiExact,
39
+ rrsiId,
40
+ rrsiHash,
41
+ rrsiCanonical,
42
+ rrsiEnvelope,
43
+ freezeRrsiData,
44
+ rrsiFail,
45
+ } from "./rrsi-data.js";
46
+
47
+ export const RRSI_REGISTRY_STORE_POLICY_SCHEMA =
48
+ "chainlesschain.rrsi-registry-store-policy/v1";
49
+ export const RRSI_REGISTRY_STORE_POLICY_EVENT_TYPE =
50
+ "rrsi.registry-store-policy.committed";
51
+ export const RRSI_REGISTRY_STORE_POLICY_ARTIFACT_TYPE =
52
+ "skill-registry-store-policy";
53
+ export const RRSI_REGISTRY_STORE_POLICY_HOLD_CODE =
54
+ "CC_RRSI_REGISTRY_STORE_POLICY_HOLD";
55
+ export const RRSI_REGISTRY_STORE_WRITER_FLOOR = 2;
56
+ const EVENT_SCHEMA = "chainlesschain.rrsi-registry-store-policy-event/v1";
57
+ const PREPARED_SCHEMA = "chainlesschain.rrsi-registry-store-prepared/v1";
58
+ const PHASES = ["prepared", "markers-installed", "committed"];
59
+ const POLICIES = new WeakMap();
60
+ const COMPONENT_BINDINGS = new WeakMap();
61
+ const ORIGIN_POLICY = freezeRrsiData({
62
+ schema: "chainlesschain.rrsi-registry-origin-policy/v1",
63
+ revision: 1,
64
+ writerFloor: RRSI_REGISTRY_STORE_WRITER_FLOOR,
65
+ unknownContent: "hold",
66
+ contentKey: "tenant-and-content-digest",
67
+ originAdmissionImplemented: false,
68
+ });
69
+ const ORIGIN_POLICY_DIGEST = rrsiHash(ORIGIN_POLICY.schema, ORIGIN_POLICY);
70
+ function hold(message, cause) {
71
+ try {
72
+ rrsiFail(message, RRSI_REGISTRY_STORE_POLICY_HOLD_CODE);
73
+ } catch (error) {
74
+ if (cause) error.cause = cause;
75
+ throw error;
76
+ }
77
+ }
78
+ const canonicalPath = (value) =>
79
+ process.platform === "win32" ? value.toLowerCase() : value;
80
+ const physicalIdentity = (stat) => `${String(stat.dev)}:${String(stat.ino)}`;
81
+ const headFields = [
82
+ "ledgerId",
83
+ "identityDigest",
84
+ "epoch",
85
+ "sequence",
86
+ "headDigest",
87
+ ];
88
+ const headData = (head) =>
89
+ Object.fromEntries(headFields.map((key) => [key, head[key]]));
90
+ const journalIdentity = (head) =>
91
+ Object.fromEntries(headFields.slice(0, 3).map((key) => [key, head[key]]));
92
+ const equal = (left, right) => rrsiCanonical(left) === rrsiCanonical(right);
93
+ const bytesFor = (value) => Buffer.from(`${rrsiCanonical(value)}\n`, "utf8");
94
+ function ownOptions(input, names) {
95
+ if (
96
+ !input ||
97
+ isProxy(input) ||
98
+ Object.getPrototypeOf(input) !== Object.prototype ||
99
+ Reflect.ownKeys(input).length !== names.length
100
+ )
101
+ rrsiFail("store policy requires plain own composition fields");
102
+ return Object.fromEntries(
103
+ names.map((name) => {
104
+ const field = Object.getOwnPropertyDescriptor(input, name);
105
+ if (!field?.enumerable || !("value" in field))
106
+ rrsiFail("store policy cannot use option accessors");
107
+ return [name, field.value];
108
+ }),
109
+ );
110
+ }
111
+ function directory(value) {
112
+ // NTFS file IDs can exceed Number's exact integer range. Preserve the full
113
+ // identity so distinct directories cannot collide after numeric rounding.
114
+ const stat = fs.lstatSync(value, { bigint: true });
115
+ if (
116
+ !stat.isDirectory() ||
117
+ stat.isSymbolicLink() ||
118
+ canonicalPath(path.resolve(fs.realpathSync.native(value))) !==
119
+ canonicalPath(value)
120
+ )
121
+ hold("store directory is not a canonical physical directory");
122
+ return { path: value, identity: physicalIdentity(stat) };
123
+ }
124
+ function assertDirectory(expected) {
125
+ if (!equal(directory(expected.path), expected))
126
+ hold("store directory identity changed");
127
+ }
128
+ function assertPrivateParent(expected) {
129
+ assertDirectory(expected);
130
+ const permission = inspectPrivatePath(expected.path);
131
+ if (permission?.ok !== true || permission.exists !== true)
132
+ hold("provisioning parent must have verified owner-only permissions");
133
+ assertDirectory(expected);
134
+ }
135
+ function syncDirectory(value) {
136
+ let fd;
137
+ try {
138
+ fd = fs.openSync(value, "r");
139
+ fs.fsyncSync(fd);
140
+ return true;
141
+ } catch (error) {
142
+ // Node cannot flush directory handles on these Windows filesystems. The
143
+ // authenticated journal and reopen checks do not imply power-loss proof.
144
+ if (
145
+ process.platform !== "win32" ||
146
+ !["EACCES", "EINVAL", "EISDIR", "EPERM"].includes(error?.code)
147
+ )
148
+ throw error;
149
+ return false;
150
+ } finally {
151
+ if (fd !== undefined) fs.closeSync(fd);
152
+ }
153
+ }
154
+ function readMarker(file, linkCount = 1) {
155
+ return withEvolutionFileIdentity(fs, file, (samePathHandle) => {
156
+ const before = fs.lstatSync(file, { bigint: true });
157
+ const safe = (stat) =>
158
+ stat.isFile() &&
159
+ !stat.isSymbolicLink() &&
160
+ Number(stat.nlink) === linkCount &&
161
+ stat.size > 0 &&
162
+ stat.size <= 4096;
163
+ if (
164
+ !safe(before) ||
165
+ canonicalPath(fs.realpathSync.native(file)) !== canonicalPath(file)
166
+ )
167
+ hold("store marker is not a bounded regular file");
168
+ const fd = fs.openSync(
169
+ file,
170
+ fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0),
171
+ );
172
+ try {
173
+ const opened = fs.fstatSync(fd, { bigint: true });
174
+ if (!safe(opened) || !samePathHandle(before, opened))
175
+ hold("store marker changed while opening");
176
+ const bytes = readBoundedDescriptor(fs, fd, Number(before.size), 4096);
177
+ const after = fs.lstatSync(file, { bigint: true });
178
+ if (
179
+ !samePathHandle(after, fs.fstatSync(fd, { bigint: true })) ||
180
+ !equal(
181
+ [
182
+ physicalIdentity(before),
183
+ String(before.size),
184
+ String(before.mtimeNs),
185
+ String(before.ctimeNs),
186
+ ],
187
+ [
188
+ physicalIdentity(after),
189
+ String(after.size),
190
+ String(after.mtimeNs),
191
+ String(after.ctimeNs),
192
+ ],
193
+ ) ||
194
+ !safe(after)
195
+ )
196
+ hold("store marker changed while reading");
197
+ return { bytes, identity: physicalIdentity(after) };
198
+ } finally {
199
+ fs.closeSync(fd);
200
+ }
201
+ });
202
+ }
203
+ function copyRef(value) {
204
+ const ref = Object.fromEntries(
205
+ ["schema", "ref", "digest"].map((key) => {
206
+ const field = Object.getOwnPropertyDescriptor(value, key);
207
+ if (!field?.enumerable || !("value" in field))
208
+ hold("policy artifact reference differs");
209
+ return [key, field.value];
210
+ }),
211
+ );
212
+ if (ref.schema !== EVOLUTION_ARTIFACT_REF_SCHEMA)
213
+ hold("policy artifact reference schema differs");
214
+ return ref;
215
+ }
216
+ function storePaths(parent, namespaceId, tenantId) {
217
+ const namespace = path.join(parent, namespaceId);
218
+ const stores = Object.fromEntries(
219
+ ["candidate", "release"].map((name) => {
220
+ const tenantKey =
221
+ name === "candidate"
222
+ ? deriveSkillCandidateTenantKey(tenantId)
223
+ : deriveSkillReleaseTenantKey(tenantId);
224
+ const baseDir = path.join(namespace, name);
225
+ return [
226
+ name,
227
+ {
228
+ baseDir,
229
+ tenantKey,
230
+ rootDir: path.join(baseDir, "tenants", tenantKey),
231
+ },
232
+ ];
233
+ }),
234
+ );
235
+ const paths = [namespace];
236
+ for (const name of ["candidate", "release"])
237
+ paths.push(
238
+ stores[name].baseDir,
239
+ path.dirname(stores[name].rootDir),
240
+ stores[name].rootDir,
241
+ );
242
+ return { namespace, stores, paths };
243
+ }
244
+ function markerFor(prepared, component) {
245
+ const store = prepared[component],
246
+ peer = prepared[component === "candidate" ? "release" : "candidate"];
247
+ const core = {
248
+ schema: `chainlesschain.skill-${component}-tenant-marker/v2`,
249
+ component: `skill-${component}-registry`,
250
+ tenantId: prepared.tenantId,
251
+ tenantKey: store.tenantKey,
252
+ storeId: store.storeId,
253
+ peerStoreId: peer.storeId,
254
+ namespaceId: prepared.namespaceId,
255
+ operationId: prepared.operationId,
256
+ journalIdentity: prepared.journalIdentity,
257
+ storeEpoch: 1,
258
+ writerFloor: RRSI_REGISTRY_STORE_WRITER_FLOOR,
259
+ originPolicyDigest: ORIGIN_POLICY_DIGEST,
260
+ provisionDigest: rrsiHash(PREPARED_SCHEMA, prepared),
261
+ };
262
+ return { ...core, markerDigest: rrsiHash(core.schema, core) };
263
+ }
264
+ function normalizePrepared(value, descriptor, identity) {
265
+ rrsiExact(
266
+ value,
267
+ [
268
+ "operationId",
269
+ "tenantId",
270
+ "namespaceId",
271
+ "parent",
272
+ "directories",
273
+ "candidate",
274
+ "release",
275
+ "journalIdentity",
276
+ "originPolicy",
277
+ "bootstrapDirectoryFsyncVerified",
278
+ ],
279
+ "prepared store",
280
+ );
281
+ rrsiId(value.operationId, "provision operation ID");
282
+ if (
283
+ value.tenantId !== descriptor.tenantId ||
284
+ !equal(value.journalIdentity, identity) ||
285
+ !equal(value.originPolicy, ORIGIN_POLICY) ||
286
+ typeof value.bootstrapDirectoryFsyncVerified !== "boolean" ||
287
+ !/^pair\.[a-f0-9-]{36}$/u.test(value.namespaceId)
288
+ )
289
+ hold("prepared store identity or policy differs");
290
+ const uuid =
291
+ /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u;
292
+ if (!uuid.test(value.namespaceId.slice(5)))
293
+ hold("prepared namespace ID is invalid");
294
+ const validateDirectory = (entry) => {
295
+ rrsiExact(entry, ["path", "identity"], "prepared directory");
296
+ if (
297
+ typeof entry.path !== "string" ||
298
+ path.resolve(entry.path) !== entry.path ||
299
+ !/^[0-9]+:[0-9]+$/u.test(entry.identity)
300
+ )
301
+ hold("prepared directory identity is invalid");
302
+ };
303
+ validateDirectory(value.parent);
304
+ const expected = storePaths(
305
+ value.parent.path,
306
+ value.namespaceId,
307
+ value.tenantId,
308
+ );
309
+ if (
310
+ !Array.isArray(value.directories) ||
311
+ value.directories.length !== expected.paths.length
312
+ )
313
+ hold("prepared directory inventory differs");
314
+ value.directories.forEach((entry, index) => {
315
+ validateDirectory(entry);
316
+ if (entry.path !== expected.paths[index])
317
+ hold("prepared directory path differs");
318
+ });
319
+ if (
320
+ new Set([
321
+ value.parent.identity,
322
+ ...value.directories.map((entry) => entry.identity),
323
+ ]).size !== 8
324
+ )
325
+ hold("prepared directories are not independent");
326
+ for (const name of ["candidate", "release"]) {
327
+ rrsiExact(
328
+ value[name],
329
+ ["baseDir", "rootDir", "tenantKey", "storeId"],
330
+ "prepared store component",
331
+ );
332
+ if (
333
+ !equal(value[name], {
334
+ ...expected.stores[name],
335
+ storeId: value[name].storeId,
336
+ }) ||
337
+ typeof value[name].storeId !== "string" ||
338
+ !value[name].storeId.startsWith("store.") ||
339
+ !uuid.test(value[name].storeId.slice(6))
340
+ )
341
+ hold("prepared component binding differs");
342
+ }
343
+ if (value.candidate.storeId === value.release.storeId)
344
+ hold("store identities must be independent");
345
+ for (const name of ["candidate", "release"])
346
+ if (bytesFor(markerFor(value, name)).length > 4096)
347
+ hold("store marker exceeds byte limit");
348
+ return value;
349
+ }
350
+ function assertLayout(prepared, markerPresence, ownTemporary = null) {
351
+ assertDirectory(prepared.parent);
352
+ prepared.directories.forEach(assertDirectory);
353
+ const roots = [prepared.candidate.rootDir, prepared.release.rootDir];
354
+ for (const entry of prepared.directories) {
355
+ const children = prepared.directories
356
+ .filter((other) => path.dirname(other.path) === entry.path)
357
+ .map((other) => path.basename(other.path));
358
+ const rootIndex = roots.indexOf(entry.path);
359
+ if (rootIndex !== -1 && markerPresence[rootIndex])
360
+ children.push("_tenant.json");
361
+ if (ownTemporary && path.dirname(ownTemporary) === entry.path)
362
+ children.push(path.basename(ownTemporary));
363
+ const actual = fs.readdirSync(entry.path);
364
+ if (actual.length > 8 || !equal(actual.sort(), children.sort()))
365
+ hold(
366
+ "fresh store bootstrap inventory changed or contains publication debris",
367
+ );
368
+ }
369
+ prepared.directories.forEach(assertDirectory);
370
+ }
371
+ function assertImmutableBoundary(prepared) {
372
+ assertDirectory(prepared.parent);
373
+ prepared.directories.forEach(assertDirectory);
374
+ }
375
+ function markerProof(prepared, boundaryOnly = false) {
376
+ const check = () =>
377
+ boundaryOnly
378
+ ? assertImmutableBoundary(prepared)
379
+ : assertLayout(prepared, [true, true]);
380
+ check();
381
+ const markers = Object.fromEntries(
382
+ ["candidate", "release"].map((name) => {
383
+ const expected = markerFor(prepared, name);
384
+ const stored = readMarker(
385
+ path.join(prepared[name].rootDir, "_tenant.json"),
386
+ );
387
+ if (!stored.bytes.equals(bytesFor(expected)))
388
+ hold("store marker bytes or writer floor differ");
389
+ return [
390
+ name,
391
+ { markerDigest: expected.markerDigest, identity: stored.identity },
392
+ ];
393
+ }),
394
+ );
395
+ check();
396
+ return markers;
397
+ }
398
+
399
+ export function createRrsiRegistryStorePolicy(input) {
400
+ const options = ownOptions(input, [
401
+ "backend",
402
+ "artifactPorts",
403
+ "ledgerArtifactResolver",
404
+ "descriptor",
405
+ ]);
406
+ const backend = captureEvolutionLedgerFileBackend(options.backend);
407
+ const binding = captureEvolutionLedgerFileBackendBinding(backend);
408
+ const ledger = backend.ledger;
409
+ if (!isEvolutionLedgerV2Journal(ledger) || !binding.matchesLedger(ledger))
410
+ rrsiFail("store policy requires the genuine original retained v2 journal");
411
+ const resolver = options.ledgerArtifactResolver;
412
+ const resolverBinding =
413
+ captureEvolutionLedgerArtifactResolverBinding(resolver);
414
+ if (
415
+ !binding.matchesArtifactResolver(resolver) ||
416
+ !resolverBinding.matchesArtifactPorts(options.artifactPorts) ||
417
+ isProxy(options.artifactPorts) ||
418
+ Object.getPrototypeOf(options.artifactPorts) !==
419
+ EvolutionArtifactPorts.prototype
420
+ )
421
+ rrsiFail("store policy requires the original artifact ports and resolver");
422
+ const configured = snapshotRrsiData(options.descriptor);
423
+ rrsiExact(
424
+ configured,
425
+ ["tenantId", "artifactTenantId", "audience", "purpose"],
426
+ "store policy descriptor",
427
+ );
428
+ Object.entries(configured).forEach(([key, value]) => rrsiId(value, key));
429
+ if (
430
+ configured.purpose !== "evolution-ledger" ||
431
+ configured.tenantId !== ledger.descriptor.tenantId ||
432
+ configured.artifactTenantId !== ledger.descriptor.artifactTenantId ||
433
+ configured.audience !== ledger.descriptor.audience ||
434
+ configured.artifactTenantId !== resolverBinding.tenantId ||
435
+ configured.audience !== resolverBinding.audience ||
436
+ configured.purpose !== resolverBinding.purpose
437
+ )
438
+ rrsiFail("store policy journal and artifact scope differ");
439
+ const descriptor = freezeRrsiData({
440
+ ...configured,
441
+ schema: RRSI_REGISTRY_STORE_POLICY_SCHEMA,
442
+ scopeId: `registry-policy.${rrsiHash(RRSI_REGISTRY_STORE_POLICY_SCHEMA, configured).slice(7)}`,
443
+ writerFloor: RRSI_REGISTRY_STORE_WRITER_FLOOR,
444
+ originPolicyDigest: ORIGIN_POLICY_DIGEST,
445
+ existingStoreUpgradeImplemented: false,
446
+ originAdmissionImplemented: false,
447
+ grantsMutationOrPromotionAuthority: false,
448
+ });
449
+ const methods = Object.fromEntries(
450
+ ["read", "verify", "appendDomainEvent"].map((name) => {
451
+ const method = Object.getOwnPropertyDescriptor(ledger, name)?.value;
452
+ if (typeof method !== "function" || !Object.isFrozen(ledger))
453
+ rrsiFail("store policy journal method is missing or mutable");
454
+ return [name, (...args) => Reflect.apply(method, ledger, args)];
455
+ }),
456
+ );
457
+ const lockTarget = path.join(
458
+ backend.descriptor.authorityRootDir,
459
+ "rrsi-registry-store-policy-operations",
460
+ );
461
+ let active = false;
462
+ const locked = (operation) => {
463
+ if (active) hold("store policy operation is already active");
464
+ active = true;
465
+ try {
466
+ return withFileLock(
467
+ lockTarget,
468
+ (context) => {
469
+ if (context.locked !== true)
470
+ hold("store policy lock was not acquired");
471
+ context.assertOwnership();
472
+ const result = operation(context.assertOwnership);
473
+ context.assertOwnership();
474
+ return result;
475
+ },
476
+ { failIfUnavailable: true, timeoutMs: 0 },
477
+ );
478
+ } finally {
479
+ active = false;
480
+ }
481
+ };
482
+ const eventId = (operationId, phase) =>
483
+ `registry-policy.${rrsiHash(EVENT_SCHEMA, { operationId, phase }).slice(7)}`;
484
+ function resolveRecord(ref, identity) {
485
+ const resolution = Reflect.apply(resolver, undefined, [
486
+ {
487
+ ledgerId: identity.ledgerId,
488
+ epoch: identity.epoch,
489
+ ref: copyRef(ref),
490
+ tenantId: descriptor.artifactTenantId,
491
+ },
492
+ ]);
493
+ if (
494
+ resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
495
+ resolution.authenticated !== true ||
496
+ resolution.found !== true ||
497
+ resolution.ref !== ref.ref ||
498
+ resolution.digest !== ref.digest ||
499
+ !Buffer.isBuffer(resolution.bytes) ||
500
+ resolution.bytes.length > 1024 * 1024
501
+ )
502
+ hold("store policy artifact cannot be authenticated");
503
+ const stored = snapshotRrsiData(
504
+ JSON.parse(
505
+ new TextDecoder("utf-8", { fatal: true }).decode(resolution.bytes),
506
+ ),
507
+ );
508
+ if (
509
+ stored.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
510
+ stored.tenantId !== descriptor.artifactTenantId ||
511
+ stored.audience !== descriptor.audience ||
512
+ stored.purpose !== descriptor.purpose ||
513
+ stored.type !== RRSI_REGISTRY_STORE_POLICY_ARTIFACT_TYPE ||
514
+ stored.retention !== "ledger"
515
+ )
516
+ hold("store policy artifact retention scope differs");
517
+ if (!Buffer.from(rrsiCanonical(stored), "utf8").equals(resolution.bytes))
518
+ hold("store policy artifact bytes are not canonical");
519
+ return stored.value;
520
+ }
521
+ function load() {
522
+ for (let attempt = 0; attempt < 3; attempt++) {
523
+ const before = methods.verify();
524
+ if (
525
+ before.authenticated !== true ||
526
+ before.durable !== true ||
527
+ before.status !== "verified"
528
+ )
529
+ hold("store policy journal head is unauthenticated");
530
+ const events = methods.read({
531
+ afterSequence: 0,
532
+ limit: EVOLUTION_LEDGER_MAX_EVENTS,
533
+ });
534
+ if (events.length !== before.sequence) {
535
+ if (!equal(headData(before), headData(methods.verify()))) continue;
536
+ hold("store policy requires complete contiguous journal coverage");
537
+ }
538
+ if (events.some((event, index) => event.sequence !== index + 1))
539
+ hold("store policy requires complete contiguous journal coverage");
540
+ const identity = journalIdentity(before),
541
+ records = [];
542
+ let prepared = null,
543
+ proof = null;
544
+ for (const event of events) {
545
+ if (event.type !== RRSI_REGISTRY_STORE_POLICY_EVENT_TYPE) continue;
546
+ if (
547
+ records.length >= 3 ||
548
+ event.schema !== EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA ||
549
+ event.tenantId !== descriptor.tenantId ||
550
+ event.artifactTenantId !== descriptor.artifactTenantId ||
551
+ event.correlationId !== descriptor.scopeId ||
552
+ event.skillName !== null ||
553
+ event.decision !== "committed"
554
+ )
555
+ hold("store policy event scope or phase count differs");
556
+ const record = resolveRecord(event.subjectRef, identity);
557
+ const coreNames = [
558
+ "descriptor",
559
+ "journalIdentity",
560
+ "operationId",
561
+ "phase",
562
+ "preparedDigest",
563
+ "previousRecordDigest",
564
+ "observedHead",
565
+ "payload",
566
+ ];
567
+ rrsiExact(
568
+ record,
569
+ [
570
+ "schema",
571
+ ...coreNames,
572
+ "recordDigest",
573
+ "structuralOnly",
574
+ "authenticated",
575
+ "readyForExecution",
576
+ "qualifiesForPromotion",
577
+ ],
578
+ "store policy event record",
579
+ );
580
+ const rebuilt = rrsiEnvelope(
581
+ EVENT_SCHEMA,
582
+ "recordDigest",
583
+ Object.fromEntries(coreNames.map((name) => [name, record[name]])),
584
+ );
585
+ const previous = records.at(-1);
586
+ if (
587
+ !equal(record, rebuilt) ||
588
+ !equal(record.descriptor, descriptor) ||
589
+ !equal(record.journalIdentity, identity) ||
590
+ record.phase !== PHASES[records.length] ||
591
+ record.previousRecordDigest !==
592
+ (previous?.record.recordDigest ?? null) ||
593
+ !equal(record.observedHead, {
594
+ ...identity,
595
+ sequence: event.sequence - 1,
596
+ headDigest: event.prevDigest,
597
+ }) ||
598
+ event.eventId !== eventId(record.operationId, record.phase) ||
599
+ !equal(event.sourceRefs.map(copyRef), previous ? [previous.ref] : [])
600
+ )
601
+ hold("store policy record identity, order or predecessor differs");
602
+ if (!prepared)
603
+ prepared = normalizePrepared(record.payload, descriptor, identity);
604
+ if (
605
+ record.operationId !== prepared.operationId ||
606
+ record.preparedDigest !== rrsiHash(PREPARED_SCHEMA, prepared)
607
+ )
608
+ hold("store policy operation or prepared bytes differ");
609
+ if (record.phase === "markers-installed") {
610
+ proof = record.payload;
611
+ rrsiExact(proof, ["candidate", "release"], "installed markers");
612
+ for (const name of ["candidate", "release"]) {
613
+ rrsiExact(
614
+ proof[name],
615
+ ["markerDigest", "identity"],
616
+ "installed marker",
617
+ );
618
+ if (
619
+ proof[name].markerDigest !==
620
+ markerFor(prepared, name).markerDigest ||
621
+ !/^[0-9]+:[0-9]+$/u.test(proof[name].identity)
622
+ )
623
+ hold("installed marker identity differs");
624
+ }
625
+ if (proof.candidate.identity === proof.release.identity)
626
+ hold("marker files must be independent");
627
+ }
628
+ if (
629
+ record.phase === "committed" &&
630
+ !equal(record.payload, {
631
+ installedRecordDigest: previous.record.recordDigest,
632
+ markers: proof,
633
+ })
634
+ )
635
+ hold("committed provisioning differs from installed proof");
636
+ records.push({
637
+ record,
638
+ ref: copyRef(event.subjectRef),
639
+ sequence: event.sequence,
640
+ });
641
+ }
642
+ const after = methods.verify();
643
+ if (!equal(headData(before), headData(after))) continue;
644
+ return { head: headData(after), identity, records, prepared, proof };
645
+ }
646
+ hold("store policy journal changed repeatedly while reading");
647
+ }
648
+ function append(state, phase, payload, assertOwnership) {
649
+ assertOwnership();
650
+ const prepared = phase === "prepared" ? payload : state.prepared;
651
+ const previous = state.records.at(-1);
652
+ const record = rrsiEnvelope(EVENT_SCHEMA, "recordDigest", {
653
+ descriptor,
654
+ journalIdentity: state.identity,
655
+ operationId: prepared.operationId,
656
+ phase,
657
+ preparedDigest: rrsiHash(PREPARED_SCHEMA, prepared),
658
+ previousRecordDigest: previous?.record.recordDigest ?? null,
659
+ observedHead: state.head,
660
+ payload,
661
+ });
662
+ const published = Reflect.apply(
663
+ EvolutionArtifactPorts.prototype.putCanonical,
664
+ options.artifactPorts,
665
+ [
666
+ RRSI_REGISTRY_STORE_POLICY_ARTIFACT_TYPE,
667
+ record,
668
+ {
669
+ audience: descriptor.audience,
670
+ purpose: descriptor.purpose,
671
+ retention: "ledger",
672
+ },
673
+ ],
674
+ );
675
+ if (
676
+ published?.receipt?.persisted !== true ||
677
+ published.receipt.readbackVerified !== true ||
678
+ published.receipt.integrityVerified !== true ||
679
+ published.receipt.retention !== "ledger" ||
680
+ !equal(resolveRecord(published.ref, state.identity), record)
681
+ )
682
+ hold("store policy artifact retention failed");
683
+ assertOwnership();
684
+ if (phase !== "prepared") {
685
+ const actual = markerProof(prepared);
686
+ if (!equal(actual, phase === "markers-installed" ? payload : state.proof))
687
+ hold("store marker identities changed before policy append");
688
+ } else assertLayout(prepared, [false, false]);
689
+ assertOwnership();
690
+ try {
691
+ const receipt = methods.appendDomainEvent(
692
+ {
693
+ type: RRSI_REGISTRY_STORE_POLICY_EVENT_TYPE,
694
+ eventId: eventId(prepared.operationId, phase),
695
+ tenantId: descriptor.tenantId,
696
+ artifactTenantId: descriptor.artifactTenantId,
697
+ correlationId: descriptor.scopeId,
698
+ skillName: null,
699
+ decision: "committed",
700
+ reason:
701
+ "Authenticated fresh Registry provisioning; independent business admission remains required",
702
+ sourceRefs: previous ? [previous.ref] : [],
703
+ subjectRef: copyRef(published.ref),
704
+ },
705
+ {
706
+ expectedHeadDigest: state.head.headDigest,
707
+ expectedSequence: state.head.sequence,
708
+ },
709
+ );
710
+ if (receipt?.authenticated !== true || receipt.durable !== true)
711
+ hold("store policy append is uncertain");
712
+ } catch (cause) {
713
+ throw Object.assign(
714
+ new Error(
715
+ "store policy commit is uncertain; recover the original operation",
716
+ { cause },
717
+ ),
718
+ {
719
+ code: "CC_RRSI_REGISTRY_STORE_POLICY_COMMIT_UNKNOWN",
720
+ operationId: prepared.operationId,
721
+ },
722
+ );
723
+ }
724
+ assertOwnership();
725
+ const readback = load();
726
+ if (readback.records.at(-1)?.record.recordDigest !== record.recordDigest)
727
+ hold("store policy committed record cannot be read back");
728
+ return readback;
729
+ }
730
+ function allocate(request, state, assertOwnership) {
731
+ const parent = directory(request.parentDir);
732
+ for (const protectedRoot of [
733
+ backend.descriptor.rootDir,
734
+ backend.descriptor.authorityRootDir,
735
+ path.dirname(backend.descriptor.witnessFilePath),
736
+ ]) {
737
+ const relation = path.relative(protectedRoot, parent.path);
738
+ if (
739
+ relation === "" ||
740
+ (!relation.startsWith(`..${path.sep}`) &&
741
+ relation !== ".." &&
742
+ !path.isAbsolute(relation))
743
+ )
744
+ hold("fresh stores cannot be provisioned inside journal storage");
745
+ }
746
+ const present = (target) => {
747
+ try {
748
+ fs.lstatSync(target);
749
+ return true;
750
+ } catch (error) {
751
+ if (error.code === "ENOENT") return false;
752
+ throw error;
753
+ }
754
+ };
755
+ const assertOutsideRegistry = () => {
756
+ for (let ancestor = parent.path; ; ancestor = path.dirname(ancestor)) {
757
+ if (
758
+ present(path.join(ancestor, "_tenant.json")) ||
759
+ present(path.join(ancestor, "tenants")) ||
760
+ (present(path.join(ancestor, "candidate")) &&
761
+ present(path.join(ancestor, "release")))
762
+ )
763
+ hold("fresh stores cannot be nested inside a Registry tenant root");
764
+ if (ancestor === path.dirname(ancestor)) break;
765
+ }
766
+ };
767
+ // Invalid existing layouts need no permission helper. A valid allocation
768
+ // still verifies its original parent and repeats the ancestor check after
769
+ // that potentially slow read, before it creates any namespace.
770
+ assertOutsideRegistry();
771
+ assertPrivateParent(parent);
772
+ assertOutsideRegistry();
773
+ const namespaceId = `pair.${randomUUID()}`;
774
+ const layout = storePaths(parent.path, namespaceId, descriptor.tenantId);
775
+ let bootstrapDirectoryFsyncVerified = true;
776
+ const captured = [];
777
+ // No recursive creation, existence fallback, caller RNG or orphan adoption.
778
+ for (const target of layout.paths) {
779
+ assertOwnership();
780
+ assertDirectory(parent);
781
+ captured.forEach(assertDirectory);
782
+ assertOwnership();
783
+ fs.mkdirSync(target, { mode: 0o700 });
784
+ const original = directory(target);
785
+ assertOwnership();
786
+ assertDirectory(parent);
787
+ captured.forEach(assertDirectory);
788
+ assertDirectory(original);
789
+ assertOwnership();
790
+ repairPrivatePath(target, {
791
+ failIfUnavailable: true,
792
+ applyWindowsAcl: true,
793
+ });
794
+ assertDirectory(original);
795
+ captured.push(original);
796
+ bootstrapDirectoryFsyncVerified =
797
+ syncDirectory(path.dirname(target)) && bootstrapDirectoryFsyncVerified;
798
+ }
799
+ const prepared = {
800
+ operationId: request.operationId,
801
+ tenantId: descriptor.tenantId,
802
+ namespaceId,
803
+ parent,
804
+ directories: captured,
805
+ candidate: {
806
+ ...layout.stores.candidate,
807
+ storeId: `store.${randomUUID()}`,
808
+ },
809
+ release: { ...layout.stores.release, storeId: `store.${randomUUID()}` },
810
+ journalIdentity: state.identity,
811
+ originPolicy: ORIGIN_POLICY,
812
+ bootstrapDirectoryFsyncVerified,
813
+ };
814
+ normalizePrepared(prepared, descriptor, state.identity);
815
+ assertLayout(prepared, [false, false]);
816
+ return prepared;
817
+ }
818
+ function install(prepared, name, presence, assertOwnership) {
819
+ assertOwnership();
820
+ assertLayout(prepared, presence);
821
+ assertOwnership();
822
+ const root = prepared[name].rootDir;
823
+ const target = path.join(root, "_tenant.json");
824
+ const temporary = path.join(root, `.rrsi-marker-${randomUUID()}.tmp`);
825
+ const bytes = bytesFor(markerFor(prepared, name));
826
+ const fd = fs.openSync(temporary, "wx", 0o600);
827
+ let written;
828
+ try {
829
+ assertOwnership();
830
+ assertLayout(prepared, presence, temporary);
831
+ assertOwnership();
832
+ fs.writeFileSync(fd, bytes);
833
+ fs.fsyncSync(fd);
834
+ written = fs.fstatSync(fd, { bigint: true });
835
+ } finally {
836
+ fs.closeSync(fd);
837
+ }
838
+ // Failures deliberately retain private debris. Never delete or overwrite a
839
+ // canonical marker or clean a path after ownership/identity has changed.
840
+ const staged = readMarker(temporary);
841
+ if (
842
+ !staged.bytes.equals(bytes) ||
843
+ String(written.ino) !== staged.identity.split(":")[1]
844
+ )
845
+ hold("store marker temporary identity differs");
846
+ assertOwnership();
847
+ assertLayout(prepared, presence, temporary);
848
+ assertOwnership();
849
+ ensurePrivateFile(temporary, {
850
+ failIfUnavailable: true,
851
+ applyWindowsAcl: true,
852
+ });
853
+ if (!equal(readMarker(temporary), staged))
854
+ hold("store marker changed during permission hardening");
855
+ assertOwnership();
856
+ assertLayout(prepared, presence, temporary);
857
+ assertOwnership();
858
+ fs.linkSync(temporary, target); // A v1 winner is never replaced.
859
+ const linked = readMarker(target, 2),
860
+ source = readMarker(temporary, 2);
861
+ if (
862
+ linked.identity !== staged.identity ||
863
+ source.identity !== staged.identity ||
864
+ !linked.bytes.equals(bytes) ||
865
+ !source.bytes.equals(bytes)
866
+ )
867
+ hold("store marker publication identity differs");
868
+ presence[name === "candidate" ? 0 : 1] = true;
869
+ assertOwnership();
870
+ assertLayout(prepared, presence, temporary);
871
+ if (readMarker(temporary, 2).identity !== staged.identity)
872
+ hold("store marker temporary was replaced");
873
+ assertOwnership();
874
+ fs.unlinkSync(temporary);
875
+ syncDirectory(root);
876
+ assertLayout(prepared, presence);
877
+ const final = readMarker(target);
878
+ if (final.identity !== staged.identity || !final.bytes.equals(bytes))
879
+ hold("store marker final readback differs");
880
+ }
881
+ function status(
882
+ state,
883
+ operationId,
884
+ { boundaryOnly = false, verifyPermissions = true } = {},
885
+ ) {
886
+ if (!state.prepared || state.prepared.operationId !== operationId)
887
+ hold("store provisioning operation is unregistered");
888
+ if (verifyPermissions) assertPrivateParent(state.prepared.parent);
889
+ else assertDirectory(state.prepared.parent);
890
+ const actual = markerProof(state.prepared, boundaryOnly);
891
+ if (state.proof && !equal(actual, state.proof))
892
+ hold("installed marker physical identity changed");
893
+ if (!equal(state.head, headData(methods.verify())))
894
+ hold("store policy journal changed during physical readback");
895
+ return freezeRrsiData({
896
+ schema: "chainlesschain.rrsi-registry-store-policy-readback/v1",
897
+ phase: state.records.at(-1).record.phase,
898
+ operationId,
899
+ prepared: state.prepared,
900
+ markers: actual,
901
+ records: state.records.map(({ record, ref, sequence }) => ({
902
+ phase: record.phase,
903
+ recordDigest: record.recordDigest,
904
+ ref,
905
+ sequence,
906
+ })),
907
+ currentHead: state.head,
908
+ historyAuthenticated: true,
909
+ freshPhysicalPairProvisioningCommitted: state.records.length === 3,
910
+ writerFloorInstalled: true,
911
+ bootstrapDirectoryFsyncVerified:
912
+ state.prepared.bootstrapDirectoryFsyncVerified,
913
+ markerDirectoryFsyncAttested: false,
914
+ originCutoverAuthenticated: false,
915
+ originClassificationAvailable: false,
916
+ legacyWriterDrainVerified: false,
917
+ productionAuthorityVerified: false,
918
+ grantsMutationOrPromotionAuthority: false,
919
+ readyForExecution: false,
920
+ qualifiesForPromotion: false,
921
+ });
922
+ }
923
+ function finish(state, operationId, assertOwnership) {
924
+ const verified = status(state, operationId); // Missing marker or debris never triggers repair.
925
+ // A committed operation performs no mutation. Its complete bookended
926
+ // readback already has the same checks as read(), with the outer ownership
927
+ // check still required before returning from the operation lock.
928
+ if (state.records.length === 3) return verified;
929
+ if (state.records.length === 1)
930
+ state = append(
931
+ state,
932
+ "markers-installed",
933
+ markerProof(state.prepared),
934
+ assertOwnership,
935
+ );
936
+ if (state.records.length === 2)
937
+ state = append(
938
+ state,
939
+ "committed",
940
+ {
941
+ installedRecordDigest: state.records[1].record.recordDigest,
942
+ markers: state.proof,
943
+ },
944
+ assertOwnership,
945
+ );
946
+ return status(state, operationId);
947
+ }
948
+ // Constructor verifies retained history but never installs missing markers.
949
+ load();
950
+ const policy = Object.freeze({
951
+ descriptor,
952
+ bindComponent(input) {
953
+ const request = snapshotRrsiData(input);
954
+ rrsiExact(
955
+ request,
956
+ ["operationId", "component"],
957
+ "Registry component binding",
958
+ );
959
+ rrsiId(request.operationId, "provision operation ID");
960
+ if (!["candidate", "release"].includes(request.component))
961
+ rrsiFail("Registry binding component is invalid");
962
+ // Do not take a policy operation lock or repair any Registry path. The
963
+ // retained head and both physical markers bookend this read-only open.
964
+ let original;
965
+ try {
966
+ original = status(load(), request.operationId);
967
+ } catch (cause) {
968
+ if (["ENOENT", "ENOTDIR"].includes(cause?.code))
969
+ hold("an authenticated Registry binding boundary is missing", cause);
970
+ throw cause;
971
+ }
972
+ if (!original.freshPhysicalPairProvisioningCommitted)
973
+ hold("Registry requires committed fresh store provisioning");
974
+ const prepared = original.prepared;
975
+ const component = request.component;
976
+ const store = prepared[component];
977
+ const peer =
978
+ prepared[component === "candidate" ? "release" : "candidate"];
979
+ const componentDescriptor = freezeRrsiData({
980
+ schema: "chainlesschain.rrsi-registry-component-binding/v1",
981
+ operationId: request.operationId,
982
+ component: `skill-${component}-registry`,
983
+ tenantId: prepared.tenantId,
984
+ ...store,
985
+ peerStoreId: peer.storeId,
986
+ journalIdentity: prepared.journalIdentity,
987
+ committedRecordDigest: original.records.at(-1).recordDigest,
988
+ writerFloor: RRSI_REGISTRY_STORE_WRITER_FLOOR,
989
+ registryRuntimeMode: "uninitialized-read-only",
990
+ persistentStoreIdentityAuthenticated: true,
991
+ originCutoverAuthenticated: false,
992
+ originClassificationAvailable: false,
993
+ grantsMutationOrPromotionAuthority: false,
994
+ });
995
+ function recheckUnchecked() {
996
+ // Invalid existing physical state needs no journal recovery or locks.
997
+ assertLayout(prepared, [true, true]);
998
+ if (!equal(markerProof(prepared, true), original.markers))
999
+ hold("Registry marker identity changed after capture");
1000
+ const result = status(load(), request.operationId, {
1001
+ boundaryOnly: true,
1002
+ verifyPermissions: false,
1003
+ });
1004
+ if (
1005
+ !equal(result.prepared, prepared) ||
1006
+ !equal(result.markers, original.markers) ||
1007
+ !equal(result.records, original.records)
1008
+ )
1009
+ hold("Registry component binding changed after capture");
1010
+ // No origin or runtime attachment exists yet. Unknown content and
1011
+ // even empty runtime containers remain HOLD, with no adoption/cleanup.
1012
+ assertLayout(prepared, [true, true]);
1013
+ if (!equal(markerProof(prepared, true), original.markers))
1014
+ hold("Registry markers changed during uninitialized inventory read");
1015
+ if (!equal(result.currentHead, headData(methods.verify())))
1016
+ hold("Registry journal changed during uninitialized inventory read");
1017
+ return result;
1018
+ }
1019
+ function recheck() {
1020
+ try {
1021
+ return recheckUnchecked();
1022
+ } catch (cause) {
1023
+ if (["ENOENT", "ENOTDIR"].includes(cause?.code))
1024
+ hold("an authenticated Registry boundary is missing", cause);
1025
+ throw cause;
1026
+ }
1027
+ }
1028
+ const componentBinding = Object.freeze({
1029
+ descriptor: componentDescriptor,
1030
+ });
1031
+ COMPONENT_BINDINGS.set(
1032
+ componentBinding,
1033
+ Object.freeze({
1034
+ descriptor: componentDescriptor,
1035
+ boundaries: freezeRrsiData({
1036
+ base: prepared.directories.find(
1037
+ (entry) => entry.path === store.baseDir,
1038
+ ),
1039
+ tenants: prepared.directories.find(
1040
+ (entry) => entry.path === path.dirname(store.rootDir),
1041
+ ),
1042
+ tenantRoot: prepared.directories.find(
1043
+ (entry) => entry.path === store.rootDir,
1044
+ ),
1045
+ }),
1046
+ marker: freezeRrsiData({
1047
+ identity: original.markers[component].identity,
1048
+ marker: markerFor(prepared, component),
1049
+ }),
1050
+ recheck,
1051
+ recheckForOpen() {
1052
+ try {
1053
+ assertPrivateParent(prepared.parent);
1054
+ return recheck();
1055
+ } catch (cause) {
1056
+ if (["ENOENT", "ENOTDIR"].includes(cause?.code))
1057
+ hold(
1058
+ "an authenticated Registry open boundary is missing",
1059
+ cause,
1060
+ );
1061
+ throw cause;
1062
+ }
1063
+ },
1064
+ matchesPolicy: (value) => value === policy,
1065
+ assertTransactionLedger(value) {
1066
+ let reader;
1067
+ try {
1068
+ reader = captureSkillReleaseOperationReader(value);
1069
+ } catch (cause) {
1070
+ hold("a genuine Registry transaction port is required", cause);
1071
+ }
1072
+ if (
1073
+ !reader.matchesLedger(ledger) ||
1074
+ !reader.matchesArtifactPorts(options.artifactPorts) ||
1075
+ !equal(reader.scope, {
1076
+ artifactTenantId: descriptor.artifactTenantId,
1077
+ audience: descriptor.audience,
1078
+ purpose: descriptor.purpose,
1079
+ })
1080
+ )
1081
+ hold(
1082
+ "Registry transaction ports require the original journal, artifact ports and exact scope",
1083
+ );
1084
+ },
1085
+ assertMutationAllowed() {
1086
+ hold(
1087
+ "Registry origin admission and runtime initialization are not implemented",
1088
+ );
1089
+ },
1090
+ }),
1091
+ );
1092
+ return componentBinding;
1093
+ },
1094
+ provisionFresh(input) {
1095
+ const request = snapshotRrsiData(input);
1096
+ rrsiExact(
1097
+ request,
1098
+ ["parentDir", "operationId"],
1099
+ "fresh provisioning request",
1100
+ );
1101
+ rrsiId(request.operationId, "provision operation ID");
1102
+ if (
1103
+ typeof request.parentDir !== "string" ||
1104
+ path.resolve(request.parentDir) !== request.parentDir
1105
+ )
1106
+ rrsiFail(
1107
+ "provision parent must be an existing absolute canonical directory",
1108
+ );
1109
+ return locked((assertOwnership) => {
1110
+ let state = load();
1111
+ if (state.prepared) {
1112
+ if (
1113
+ state.prepared.operationId !== request.operationId ||
1114
+ state.prepared.parent.path !== request.parentDir
1115
+ )
1116
+ hold(
1117
+ "this tenant already has a bound store provisioning operation",
1118
+ );
1119
+ return finish(state, request.operationId, assertOwnership);
1120
+ }
1121
+ const prepared = allocate(request, state, assertOwnership);
1122
+ state = append(state, "prepared", prepared, assertOwnership);
1123
+ const presence = [false, false];
1124
+ install(prepared, "candidate", presence, assertOwnership);
1125
+ install(prepared, "release", presence, assertOwnership);
1126
+ return finish(state, request.operationId, assertOwnership);
1127
+ });
1128
+ },
1129
+ recover(operationId) {
1130
+ rrsiId(operationId, "provision operation ID");
1131
+ return locked((assertOwnership) =>
1132
+ finish(load(), operationId, assertOwnership),
1133
+ );
1134
+ },
1135
+ read(operationId) {
1136
+ rrsiId(operationId, "provision operation ID");
1137
+ return locked(() => status(load(), operationId));
1138
+ },
1139
+ });
1140
+ POLICIES.set(
1141
+ policy,
1142
+ Object.freeze({
1143
+ descriptor,
1144
+ matchesBackend: (value) => value === backend,
1145
+ matchesArtifactPorts: (value) => value === options.artifactPorts,
1146
+ matchesArtifactResolver: (value) => value === resolver,
1147
+ read: policy.read,
1148
+ }),
1149
+ );
1150
+ return policy;
1151
+ }
1152
+
1153
+ export function captureRrsiRegistryStorePolicy(value) {
1154
+ const captured = POLICIES.get(value);
1155
+ if (!captured) rrsiFail("a genuine Registry store policy is required");
1156
+ return captured;
1157
+ }
1158
+
1159
+ export function captureRrsiRegistryComponentBinding(value) {
1160
+ const captured = COMPONENT_BINDINGS.get(value);
1161
+ if (!captured) hold("a genuine Registry component binding is required");
1162
+ return captured;
1163
+ }
1164
+
1165
+ /** Current v1 constructors must never bootstrap in the reserved fresh namespace,
1166
+ * including after marker loss and through a canonical filesystem alias. */
1167
+ export function assertOutsideRrsiRegistryNamespace(baseDir) {
1168
+ const reserved = (value) =>
1169
+ value.split(/[\\/]/u).some((part) => /^pair\.[a-f0-9-]{36}$/iu.test(part));
1170
+ const requested = path.resolve(baseDir);
1171
+ if (reserved(requested))
1172
+ hold(
1173
+ "reserved v2 Registry namespace requires its genuine component binding",
1174
+ );
1175
+ for (let current = requested; ; current = path.dirname(current)) {
1176
+ try {
1177
+ const target = path.resolve(
1178
+ fs.realpathSync.native(current),
1179
+ path.relative(current, requested),
1180
+ );
1181
+ if (reserved(target))
1182
+ hold(
1183
+ "reserved v2 Registry namespace cannot be opened through an unbound alias",
1184
+ );
1185
+ return target;
1186
+ } catch (error) {
1187
+ if (error.code !== "ENOENT") throw error;
1188
+ if (current === path.dirname(current)) throw error;
1189
+ }
1190
+ }
1191
+ }