chainlesschain 0.166.91 → 0.166.93

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 (221) 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-oo9rE0gh.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CgANpkKu.js → ActionButton-CVJVVv4i.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DnvpX7RB.js → Analytics-CUXuwmia.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-C2bHccBM.js → AppLayout-iM4PvCuY.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-BIhijC9g.js → Artifacts-DKUIJbf9.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-CKRjWGdp.js → Audit-C4_SzFN2.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CblYtgBE.js → BackgroundAgents-C3427uy-.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-Cq35b78a.js → Backup-BpEQQiog.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-DcB7NoRz.js → BaseInput-C_exQomZ.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-tc3b-s7i.js → Chat-DzpkLtWa.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-DX4XmTWm.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BLD5bH5u.js → Checkbox-CxAC1CU8.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BLOsoazN.js → Codegen-wDFAGCLp.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-Bdr7JwIx.js → Col-BvwirhMf.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-C84BsWE0.js → Community-BJuA7paY.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-Dzdwd04z.js → Compact-DzV35_u2.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CCG-R0EV.js → Compliance-CIDPPvr9.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BYj72SK0.js → Cowork-DyTMxP3N.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-B6iKAwOf.js → Cron-PcNLjMFx.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BJ-oDC6u.js → Crosschain-B_O7ck6Z.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-BnMckGLr.js → DID-CII35Me1.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-Cyje-gCO.js → Dashboard-DU56fkNz.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BpNlenjK.js → Dropdown-DHC8HVeJ.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BhonO7Nv.js → EmailListRenderer-oUOHFNsD.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DVoNU-Id.js → EvolutionSettings-D7RCAWNl.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-tdn-KC67.js → FamilyGuardDashboard-CGONPZxC.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation--EEVrHhz.js → Federation-BbDlPWcl.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Cy8zr0-4.js → FormItemContext-BBJbFQQT.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-BuUhpgFi.js → GenericCardRenderer-iuxAero4.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-Ctd3E5Pe.js → Git-Dw0prdY5.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Ce7dV6aU.js → Governance-DOGqi_uV.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CD1vExIH.js → Inference-BY5oUGGj.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-Dn64OdQ7.js → KnowledgeGraph-CcE2EVYX.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-PmElVRrT.js → Logs-DyfN4R5w.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-BFiVKf5t.js → MarkdownRenderer-Bj62Aq0M.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-OW4jTXwx.js → Marketplace-CuuuAXUh.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BEq2Ib4x.js → McpTools-948Fithv.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Can_P2oK.js → Memory-D4PINvyy.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DJ8R-dn3.js → MobileBridge-ECKMaLzX.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-B7kV9GOt.js → MobileProjects-CB5MAcvD.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-BfxamolS.js → Mtc-BRzIM3HJ.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-DHtuv7av.js → MtcAudit-CGeAXJGn.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-DLkLpvxc.js → Multisig-C_qJ-8K-.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-u4XtJTIt.js → NLProgramming-DAEyCn7T.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BwuuPJLS.js → Notes-DmD3MEec.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-HEeu-E9v.js → NotificationSettings-Cv4Q3VC9.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-BNlpaFjH.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-Yh-czs3b.js → Organization-DqAFdz6p.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DmE8mYVM.js → Overflow-8Ye9cIcE.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CWVck8WN.js → P2P-755SfHoJ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DgFqekod.js → PdhVaultBrowser-CgZLiucX.js} +4 -4
  56. package/src/assets/web-panel/assets/{Permissions-BtJBVOHV.js → Permissions-C-vFF_rL.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-6VBObXzd.js → PersonalDataHub-Diz1oXM3.js} +5 -5
  58. package/src/assets/web-panel/assets/{Pipeline-D222FmqY.js → Pipeline-D4kIzsZG.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Bi9FMikp.js → Privacy-QKLkSAUH.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-Bo52H47H.js → ProjectInit-I0S9o_RT.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BPkesfOc.js → ProjectSettings-DdgV3-Ho.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-GynohSFX.js → Projects-BJHHegtj.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-DVdMg04n.js → Providers-uVa1zfbS.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-DqJCb595.js → QrScannerModal-YLVpOChR.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-J7loQbXi.js → QuickAsk-535AYH61.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BI5aURVc.js → Recommend-C_P6eNSw.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BN2sqGvz.js → RemoteSession-EXH1SbNj.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BGOND-Fi.js → Reputation-Cxc7d3eU.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-77dfwaUk.js → Row-EDqJy-wS.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-FtBAxS3g.js → RssFeed-C03Xeg9_.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BaYVLFb7.js → Search-DsIga9DK.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-LE3Vv6ab.js → Security-DgArMFc-.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-C5pP-Whz.js → Services-MooDpHBP.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CLqKUVsF.js → Skeleton-B10P1Dr6.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-BPjN0SX5.js → Skills-DHLHEkLl.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-14jD70kg.js → Sla-D4RT7d4g.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Dr9ij42W.js → SpeechSettings-D8u6F-LV.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BzLHP7B8.js → SyncSettings-4nvNzRq8.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-YqV9b0rV.js → Tasks-CmCb8zNO.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-CxxAE4PK.js → Templates-CzESIa21.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CRb3PcKJ.js → Tenant-Ch_N3p4d.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CTzPpBaP.js → Terminal-BZccUf_X.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DjFUj_hy.js → TimelineRenderer-FrKcNy_3.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Bbb8tPvx.js → Tokens-4xvLpXfD.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CSeWGM0W.js → Trigger-84UjyxXd.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-JgESMBo3.js → Trust-M6UtHnji.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CiObLk0T.js → UkeySign-L_xEgtCg.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CFEZaQ2x.js → VideoEditing-BLJCX9ru.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-DR8ZGDNn.js → Wallet-DwL6uJCj.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DxZukvu7.js → WebAuthn-Bmn9pdzz.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CKgSZQwn.js → WorkflowEditor-DSsZ5xG1.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CTxEQE66.js → chat--FGNUaa8.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CAjKMUu3.js → colors-DeuwNdqX.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-BXuz49at.js → compact-item-I4XKxRFU.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-CFN_Hwr9.js → createContext-RoD2p5Ba.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-ctnml4IW.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BwoSBSfP.js → hasIn-BsvyddUM.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CB3kVd9c.js → index-0tRU1Sv-.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-o9DpkZKf.js → index-4xHc2WjT.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BmQITjMU.js → index-B8-eGLN9.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DY-gBSm8.js → index-BS_uqSTa.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-F2E5RCwz.js → index-BYEVBlCl.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CF9lWi1o.js → index-BcBM065G.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bu2P6u8m.js → index-BnrL4s-3.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Dv7V2kg6.js → index-BrZPb0On.js} +1 -1
  106. package/src/assets/web-panel/assets/index-C7PN8mh1.js +1 -0
  107. package/src/assets/web-panel/assets/{index-DViK2bkv.js → index-CBazK4-7.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BmXpdcHI.js → index-CPS3zv1c.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bqv_Cray.js → index-CSrZiiAs.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B7kp-zRE.js → index-CVwZMt9Z.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B0QbLlWn.js → index-CdgKZYgm.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DjF5BOZx.js → index-CesTu01s.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CSmFby3Q.js → index-CiHlSuMl.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-B2o_BBjg.js → index-CsLVac9n.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CehdwJ_Q.js → index-D1ONyBTW.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Bj4hIiLW.js → index-D4IZsKbF.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-_ZtCyUdz.js → index-D4P4vpmv.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B9yR7zqr.js → index-D6J8dz7X.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-u9_DM3ZC.js → index-DChy2sHE.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C8er4W9u.js → index-DKUCl_Lk.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BK4ftQ4d.js → index-DRluW3_r.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B2tEnBPx.js → index-DWUmhNO-.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-IY9bd5az.js → index-DXnpVGG3.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Cp5y7lX_.js → index-DYOpAS6-.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-T3MTE6jB.js → index-DiH-3cR2.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DxunxaTw.js → index-DlEfwgzr.js} +1 -1
  127. package/src/assets/web-panel/assets/index-KnbBJAO-.js +1 -0
  128. package/src/assets/web-panel/assets/{index-DTX9CJPx.js → index-R4St_zjR.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Tz5dheZa.js → index-ScgoDU9V.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DmkbAADP.js → index-UWdT_lty.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Bw9s2d3c.js → index-VAlor744.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CN53dE_u.js → index-Wco_uvRo.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DpdDnZX_.js → index-ZgFED_Zd.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-IahILygB.js → index-jaHeti4i.js} +3 -3
  135. package/src/assets/web-panel/assets/{index-Cgk0YEiq.js → index-rJDabtw4.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-t2Ch_JKn.js → index-vRiGKIP0.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-BoiGJDoO.js → initDefaultProps-BHT0PacY.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-5eL4E0pA.js → motion-CBYsMtsC.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-DjggDi_1.js → move-DnHfFV4K.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Ce8Vo2T3.js → mtc-parser-DfGkRYrx.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-D1yOBaO2.js → omit-SjLcPQA9.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-8NLceQe8.js → pickAttrs-CCZHF4ep.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CsIdBRmQ.js → placementArrow-DjCGn2sJ.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-GM5NE8En.js → responsiveObserve-BCFCl2on.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-44yj3u49.js → slide-DsfmuIZu.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-B8tqtWcX.js → statusUtils-hPKuJUia.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-NhDPBbyB.js → styleChecker-DOXKH7Kf.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-C8Qz1GtN.js → useFlexGapSupport-B_G7yqio.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-ClUv4kih.js → useFs-BXOTOm2l.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BwkOVEh6.js → usePersonalDataHub-CRvie3g7.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode--gMF33R0.js → vnode-D9_zMmww.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DXg3TqOP.js → zoom-C4tW03qI.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +52 -0
  155. package/src/lib/artifact-store.js +51 -3
  156. package/src/lib/bounded-artifact-file-read.js +131 -0
  157. package/src/lib/evolution/evolution-artifact-ports.js +235 -129
  158. package/src/lib/evolution/evolution-eval-cohort-enrollment.js +713 -47
  159. package/src/lib/evolution/evolution-eval-gate.js +146 -0
  160. package/src/lib/evolution/evolution-eval-launch-admission.js +168 -90
  161. package/src/lib/evolution/evolution-eval-ledger-capture.js +50 -0
  162. package/src/lib/evolution/evolution-eval-readonly-audit.js +106 -0
  163. package/src/lib/evolution/evolution-ledger-file-backend.js +20 -0
  164. package/src/lib/evolution/evolution-ledger-ports.js +59 -27
  165. package/src/lib/evolution/evolution-ledger-v2-journal.js +55 -18
  166. package/src/lib/evolution/evolution-workbench-file-resources.js +19 -1
  167. package/src/lib/evolution/rrsi-cohort-registration.js +275 -0
  168. package/src/lib/evolution/rrsi-contracts.js +742 -0
  169. package/src/lib/evolution/rrsi-data.js +196 -0
  170. package/src/lib/evolution/rrsi-evaluation-adapter.js +275 -0
  171. package/src/lib/evolution/rrsi-evaluation-variants.js +267 -0
  172. package/src/lib/evolution/rrsi-group-statistics.js +553 -0
  173. package/src/lib/evolution/rrsi-history-ledger-adapter.js +3286 -0
  174. package/src/lib/evolution/rrsi-installation-route-contracts.js +275 -0
  175. package/src/lib/evolution/rrsi-installation-route-reader.js +282 -0
  176. package/src/lib/evolution/rrsi-native-batch-evidence.js +520 -0
  177. package/src/lib/evolution/rrsi-native-eval-row-collector.js +538 -0
  178. package/src/lib/evolution/rrsi-native-evaluation-batch.js +547 -0
  179. package/src/lib/evolution/rrsi-native-evaluation-plan.js +431 -0
  180. package/src/lib/evolution/rrsi-native-group-statistics-plan.js +121 -0
  181. package/src/lib/evolution/rrsi-native-group-statistics.js +482 -0
  182. package/src/lib/evolution/rrsi-native-quality-receipt-contracts.js +321 -0
  183. package/src/lib/evolution/rrsi-native-quality-receipt.js +256 -0
  184. package/src/lib/evolution/rrsi-native-statistics-protocol.js +330 -0
  185. package/src/lib/evolution/rrsi-observed-text-index.js +978 -0
  186. package/src/lib/evolution/rrsi-parent-binding.js +290 -0
  187. package/src/lib/evolution/rrsi-pm-execution-bridge.js +500 -0
  188. package/src/lib/evolution/rrsi-pm-training-mapping.js +134 -0
  189. package/src/lib/evolution/rrsi-preparation-contracts.js +213 -0
  190. package/src/lib/evolution/rrsi-registry-history-binding.js +193 -0
  191. package/src/lib/evolution/rrsi-registry-runtime-policy.js +648 -0
  192. package/src/lib/evolution/rrsi-registry-store-policy.js +1271 -0
  193. package/src/lib/evolution/rrsi-runtime-composition.js +79 -0
  194. package/src/lib/evolution/rrsi-selector.js +434 -0
  195. package/src/lib/evolution/rrsi-statistics-simulation.js +354 -0
  196. package/src/lib/evolution/rrsi-tenant-index-anchor-contracts.js +223 -0
  197. package/src/lib/evolution/rrsi-tenant-index-anchor-history.js +157 -0
  198. package/src/lib/evolution/skill-candidate-registry.js +216 -29
  199. package/src/lib/evolution/skill-registry-maintenance.js +80 -0
  200. package/src/lib/evolution/skill-registry-writer-control.js +138 -0
  201. package/src/lib/evolution/skill-release-registry.js +414 -169
  202. package/src/lib/formal-quality-eval-runtime.js +2 -14
  203. package/src/lib/goal-store.js +225 -16
  204. package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +291 -30
  205. package/src/lib/record-replay/skill-recorder.js +38 -3
  206. package/src/lib/remote-read-loop-guard.js +227 -24
  207. package/src/lib/scheduler-kernel/authority-resolver.js +12 -163
  208. package/src/lib/scheduler-kernel/contract.js +27 -414
  209. package/src/lib/scheduler-kernel/runtime.js +21 -823
  210. package/src/lib/scheduler-kernel/service.js +11 -328
  211. package/src/lib/scheduler-kernel/source-locator-path.js +7 -142
  212. package/src/lib/scheduler-kernel/store.js +67 -5931
  213. package/src/lib/secure-fs.js +16 -1314
  214. package/src/lib/task-progress-tracker.js +6 -1
  215. package/src/lib/with-file-lock.js +122 -20
  216. package/src/runtime/agent-core.js +71 -23
  217. package/src/assets/web-panel/assets/ChatBubbleRenderer-fcc_Tvqu.js +0 -1
  218. package/src/assets/web-panel/assets/OrderTableRenderer-BtvN-Qwh.js +0 -1
  219. package/src/assets/web-panel/assets/devWarning-CfB8DxT2.js +0 -1
  220. package/src/assets/web-panel/assets/index-CCsRfd0k.js +0 -1
  221. package/src/assets/web-panel/assets/index-CsmiZIQ4.js +0 -1
@@ -6,6 +6,12 @@ import { types as utilTypes } from "node:util";
6
6
  import { getHomeDir } from "../paths.js";
7
7
  import { ensurePrivateDirectory, ensurePrivateFile } from "../secure-fs.js";
8
8
  import { withEvolutionFileIdentity } from "./evolution-file-identity.js";
9
+ import { createSkillRegistryWriterControl } from "./skill-registry-writer-control.js";
10
+ import {
11
+ captureRrsiRegistryComponentBinding,
12
+ assertOutsideRrsiRegistryNamespace,
13
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
14
+ } from "./rrsi-registry-store-policy.js";
9
15
  import {
10
16
  SKILL_CANDIDATE_MIGRATION_RECEIPT_SCHEMA,
11
17
  SKILL_CANDIDATE_MIGRATION_RECORD_SCHEMA,
@@ -62,6 +68,7 @@ export const SKILL_RELEASE_JOURNAL_ARCHIVE_SCHEMA =
62
68
 
63
69
  const JOURNAL_SCHEMA = "chainlesschain.skill-release-journal/v4";
64
70
  const REGISTRY_READERS = new WeakMap();
71
+ const REGISTRY_WRITERS = new WeakMap();
65
72
 
66
73
  export function captureSkillReleaseRegistryReader(value) {
67
74
  const reader = REGISTRY_READERS.get(value);
@@ -72,6 +79,16 @@ export function captureSkillReleaseRegistryReader(value) {
72
79
  throw new TypeError("a genuine SkillReleaseRegistry reader is required");
73
80
  return reader;
74
81
  }
82
+
83
+ export function captureSkillReleaseRegistryWriterControl(value) {
84
+ captureSkillReleaseRegistryReader(value);
85
+ const control = REGISTRY_WRITERS.get(value);
86
+ if (!control)
87
+ throw new TypeError(
88
+ "a genuine release Registry writer control is required",
89
+ );
90
+ return control;
91
+ }
75
92
  const INTENT_SCHEMA = "chainlesschain.skill-release-transition-intent/v2";
76
93
  const RELEASE_DOMAIN = `${SKILL_RELEASE_SCHEMA}\0`;
77
94
  const STATE_DOMAIN = `${SKILL_RELEASE_STATE_SCHEMA}\0`;
@@ -1850,128 +1867,151 @@ export function archiveLegacySkillReleaseJournal(input) {
1850
1867
  ) {
1851
1868
  throw migrationRequired("legacy journal archive paths are invalid");
1852
1869
  }
1853
- const sourcePath = path.join(
1854
- sourceDirectory,
1855
- path.basename(requestedSourcePath),
1856
- );
1857
- if (input.secure) {
1858
- ensurePrivateDirectory(archiveDirectory, {
1859
- applyWindowsAcl: true,
1860
- failIfUnavailable: true,
1861
- });
1862
- }
1863
- const archivePath = path.join(
1864
- archiveDirectory,
1865
- `${disposition.planDigest.slice("sha256:".length)}.json`,
1866
- );
1867
- const expectedBytes = serialize(archive);
1868
- let created = false;
1869
- if (lstatOrNull(fsImpl, archivePath) === null) {
1870
- const source = readBoundedSingleLinkFile(
1871
- fsImpl,
1872
- sourcePath,
1873
- MAX_FILE_BYTES,
1874
- SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1875
- "legacy release journal source",
1870
+ // An independent archive helper can also retire bytes under a tenant's
1871
+ // journals directory. It must participate in that physical root's writer
1872
+ // protocol rather than bypassing the class-method maintenance boundary.
1873
+ const writer = createSkillRegistryWriterControl({
1874
+ rootDir: path.dirname(sourceDirectory),
1875
+ tenantId: disposition.tenantId,
1876
+ component: TENANT_MARKER_COMPONENT,
1877
+ fsImpl,
1878
+ });
1879
+ return writer.runSync(() => {
1880
+ const sourcePath = path.join(
1881
+ sourceDirectory,
1882
+ path.basename(requestedSourcePath),
1876
1883
  );
1877
- if (!source.bytes.equals(serialize(journal))) {
1878
- throw migrationRequired(
1879
- "legacy release journal source bytes differ from the verified input",
1880
- );
1884
+ if (input.secure) {
1885
+ ensurePrivateDirectory(archiveDirectory, {
1886
+ applyWindowsAcl: true,
1887
+ failIfUnavailable: true,
1888
+ });
1881
1889
  }
1882
- const temporaryPath = path.join(
1890
+ const archivePath = path.join(
1883
1891
  archiveDirectory,
1884
- `.journal-${process.pid}-${crypto.randomBytes(16).toString("hex")}.tmp`,
1892
+ `${disposition.planDigest.slice("sha256:".length)}.json`,
1885
1893
  );
1886
- let descriptor = null;
1887
- try {
1888
- descriptor = fsImpl.openSync(temporaryPath, "wx", 0o600);
1889
- fsImpl.writeFileSync(descriptor, expectedBytes);
1890
- fsImpl.fsyncSync(descriptor);
1891
- fsImpl.closeSync(descriptor);
1892
- descriptor = null;
1893
- if (input.secure) {
1894
- ensurePrivateFile(temporaryPath, {
1895
- applyWindowsAcl: true,
1896
- failIfUnavailable: true,
1897
- });
1898
- }
1899
- const staged = readBoundedSingleLinkFile(
1894
+ const expectedBytes = serialize(archive);
1895
+ let created = false;
1896
+ if (lstatOrNull(fsImpl, archivePath) === null) {
1897
+ const source = readBoundedSingleLinkFile(
1900
1898
  fsImpl,
1901
- temporaryPath,
1899
+ sourcePath,
1902
1900
  MAX_FILE_BYTES,
1903
1901
  SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1904
- "legacy journal archive temporary",
1902
+ "legacy release journal source",
1905
1903
  );
1906
- if (!staged.bytes.equals(expectedBytes)) {
1907
- throw migrationRequired("legacy journal archive write was incomplete");
1904
+ if (!source.bytes.equals(serialize(journal))) {
1905
+ throw migrationRequired(
1906
+ "legacy release journal source bytes differ from the verified input",
1907
+ );
1908
1908
  }
1909
- checkpoint("after-archive-fsync", {
1910
- archiveDigest: archive.archiveDigest,
1911
- dispositionPlanDigest: disposition.planDigest,
1912
- });
1909
+ const temporaryPath = path.join(
1910
+ archiveDirectory,
1911
+ `.journal-${process.pid}-${crypto.randomBytes(16).toString("hex")}.tmp`,
1912
+ );
1913
+ let descriptor = null;
1913
1914
  try {
1914
- fsImpl.linkSync(temporaryPath, archivePath);
1915
- created = true;
1916
- } catch (error) {
1917
- if (error?.code !== "EEXIST") throw error;
1918
- }
1919
- fsImpl.unlinkSync(temporaryPath);
1920
- fsyncDirectory(fsImpl, archiveDirectory);
1921
- checkpoint("after-archive-publish", {
1922
- archiveDigest: archive.archiveDigest,
1923
- dispositionPlanDigest: disposition.planDigest,
1924
- });
1925
- } finally {
1926
- if (descriptor !== null) fsImpl.closeSync(descriptor);
1927
- if (lstatOrNull(fsImpl, temporaryPath) !== null)
1915
+ descriptor = fsImpl.openSync(temporaryPath, "wx", 0o600);
1916
+ fsImpl.writeFileSync(descriptor, expectedBytes);
1917
+ fsImpl.fsyncSync(descriptor);
1918
+ fsImpl.closeSync(descriptor);
1919
+ descriptor = null;
1920
+ if (input.secure) {
1921
+ ensurePrivateFile(temporaryPath, {
1922
+ applyWindowsAcl: true,
1923
+ failIfUnavailable: true,
1924
+ });
1925
+ }
1926
+ const staged = readBoundedSingleLinkFile(
1927
+ fsImpl,
1928
+ temporaryPath,
1929
+ MAX_FILE_BYTES,
1930
+ SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1931
+ "legacy journal archive temporary",
1932
+ );
1933
+ if (!staged.bytes.equals(expectedBytes)) {
1934
+ throw migrationRequired(
1935
+ "legacy journal archive write was incomplete",
1936
+ );
1937
+ }
1938
+ checkpoint("after-archive-fsync", {
1939
+ archiveDigest: archive.archiveDigest,
1940
+ dispositionPlanDigest: disposition.planDigest,
1941
+ });
1942
+ try {
1943
+ writer.assertIfWriting();
1944
+ fsImpl.linkSync(temporaryPath, archivePath);
1945
+ created = true;
1946
+ } catch (error) {
1947
+ if (error?.code !== "EEXIST") throw error;
1948
+ }
1928
1949
  fsImpl.unlinkSync(temporaryPath);
1950
+ fsyncDirectory(fsImpl, archiveDirectory);
1951
+ checkpoint("after-archive-publish", {
1952
+ archiveDigest: archive.archiveDigest,
1953
+ dispositionPlanDigest: disposition.planDigest,
1954
+ });
1955
+ } finally {
1956
+ if (descriptor !== null) fsImpl.closeSync(descriptor);
1957
+ let cleanupOwned = false;
1958
+ try {
1959
+ writer.assertIfWriting();
1960
+ cleanupOwned = true;
1961
+ } catch {
1962
+ /* Preserve private debris after lost ownership. */
1963
+ }
1964
+ if (cleanupOwned && lstatOrNull(fsImpl, temporaryPath) !== null)
1965
+ fsImpl.unlinkSync(temporaryPath);
1966
+ }
1929
1967
  }
1930
- }
1931
- const persisted = readBoundedSingleLinkFile(
1932
- fsImpl,
1933
- archivePath,
1934
- MAX_FILE_BYTES,
1935
- SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1936
- "legacy journal archive",
1937
- );
1938
- if (
1939
- !persisted.bytes.equals(expectedBytes) ||
1940
- canonicalJson(
1941
- verifySkillReleaseJournalArchive(
1942
- JSON.parse(
1943
- new TextDecoder("utf-8", { fatal: true }).decode(persisted.bytes),
1944
- ),
1945
- ),
1946
- ) !== canonicalJson(archive)
1947
- ) {
1948
- throw migrationRequired("legacy journal archive readback differs");
1949
- }
1950
- checkpoint("after-archive-readback", {
1951
- archiveDigest: archive.archiveDigest,
1952
- dispositionPlanDigest: disposition.planDigest,
1953
- });
1954
- if (lstatOrNull(fsImpl, sourcePath) !== null) {
1955
- const source = readBoundedSingleLinkFile(
1968
+ const persisted = readBoundedSingleLinkFile(
1956
1969
  fsImpl,
1957
- sourcePath,
1970
+ archivePath,
1958
1971
  MAX_FILE_BYTES,
1959
1972
  SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1960
- "legacy release journal source",
1973
+ "legacy journal archive",
1961
1974
  );
1962
- if (!source.bytes.equals(serialize(journal))) {
1963
- throw migrationRequired(
1964
- "legacy release journal changed before retirement",
1965
- );
1975
+ if (
1976
+ !persisted.bytes.equals(expectedBytes) ||
1977
+ canonicalJson(
1978
+ verifySkillReleaseJournalArchive(
1979
+ JSON.parse(
1980
+ new TextDecoder("utf-8", { fatal: true }).decode(persisted.bytes),
1981
+ ),
1982
+ ),
1983
+ ) !== canonicalJson(archive)
1984
+ ) {
1985
+ throw migrationRequired("legacy journal archive readback differs");
1966
1986
  }
1967
- fsImpl.unlinkSync(sourcePath);
1968
- fsyncDirectory(fsImpl, sourceDirectory);
1969
- checkpoint("after-source-retire", {
1987
+ checkpoint("after-archive-readback", {
1970
1988
  archiveDigest: archive.archiveDigest,
1971
1989
  dispositionPlanDigest: disposition.planDigest,
1972
1990
  });
1973
- }
1974
- return deepFreeze({ archive, archivePath, created, sourceRetired: true });
1991
+ if (lstatOrNull(fsImpl, sourcePath) !== null) {
1992
+ const source = readBoundedSingleLinkFile(
1993
+ fsImpl,
1994
+ sourcePath,
1995
+ MAX_FILE_BYTES,
1996
+ SKILL_RELEASE_MIGRATION_REQUIRED_CODE,
1997
+ "legacy release journal source",
1998
+ );
1999
+ if (!source.bytes.equals(serialize(journal))) {
2000
+ throw migrationRequired(
2001
+ "legacy release journal changed before retirement",
2002
+ );
2003
+ }
2004
+ writer.assertIfWriting();
2005
+ fsImpl.unlinkSync(sourcePath);
2006
+ fsyncDirectory(fsImpl, sourceDirectory);
2007
+ checkpoint("after-source-retire", {
2008
+ archiveDigest: archive.archiveDigest,
2009
+ dispositionPlanDigest: disposition.planDigest,
2010
+ });
2011
+ }
2012
+ writer.assertIfWriting();
2013
+ return deepFreeze({ archive, archivePath, created, sourceRetired: true });
2014
+ });
1975
2015
  }
1976
2016
 
1977
2017
  /**
@@ -2472,6 +2512,7 @@ const REGISTRY_OPTION_KEYS = new Set([
2472
2512
  "randomToken",
2473
2513
  "rootDir",
2474
2514
  "secure",
2515
+ "storePolicyBinding",
2475
2516
  "tenantId",
2476
2517
  "transactionLedger",
2477
2518
  ]);
@@ -2659,6 +2700,7 @@ function normalizeRegistryOptions(options) {
2659
2700
  data.rootDir ??
2660
2701
  path.join(getHomeDir(), "evolution", "registry", "releases"),
2661
2702
  secure: data.secure ?? true,
2703
+ storePolicyBinding: data.storePolicyBinding,
2662
2704
  tenantId: tenantId(data.tenantId),
2663
2705
  transactionLedger: data.transactionLedger,
2664
2706
  };
@@ -2696,6 +2738,9 @@ export class SkillReleaseRegistry {
2696
2738
  #ledgerQuery;
2697
2739
 
2698
2740
  #pins = new WeakMap();
2741
+ #writerControl;
2742
+ #storeBinding;
2743
+ #runtimeMode = "initialized";
2699
2744
 
2700
2745
  constructor(options) {
2701
2746
  const {
@@ -2706,9 +2751,34 @@ export class SkillReleaseRegistry {
2706
2751
  randomToken,
2707
2752
  rootDir,
2708
2753
  secure,
2754
+ storePolicyBinding,
2709
2755
  tenantId: ownerTenantId,
2710
2756
  transactionLedger,
2711
2757
  } = normalizeRegistryOptions(options);
2758
+ const requestedBase = path.resolve(rootDir);
2759
+ if (storePolicyBinding !== undefined) {
2760
+ this.#storeBinding =
2761
+ captureRrsiRegistryComponentBinding(storePolicyBinding);
2762
+ const descriptor = this.#storeBinding.descriptor;
2763
+ if (
2764
+ new.target !== SkillReleaseRegistry ||
2765
+ fsImpl !== fs ||
2766
+ secure !== true ||
2767
+ descriptor.component !== TENANT_MARKER_COMPONENT ||
2768
+ descriptor.tenantId !== ownerTenantId ||
2769
+ !samePath(descriptor.baseDir, requestedBase)
2770
+ )
2771
+ throw failure(
2772
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
2773
+ "release v2 binding or native storage options differ",
2774
+ );
2775
+ // Authenticate the original port object before reading any caller method.
2776
+ this.#storeBinding.assertTransactionLedger(transactionLedger);
2777
+ this.#storeBinding.recheckForOpen();
2778
+ this.#runtimeMode = this.#storeBinding.runtimeDirectories
2779
+ ? "authenticated-empty-read-only"
2780
+ : "uninitialized";
2781
+ } else assertOutsideRrsiRegistryNamespace(requestedBase);
2712
2782
  if (
2713
2783
  !transactionLedger ||
2714
2784
  typeof transactionLedger.prepare !== "function" ||
@@ -2742,57 +2812,104 @@ export class SkillReleaseRegistry {
2742
2812
  this.#now = now;
2743
2813
  this.#leaseTtlMs = leaseTtlMs;
2744
2814
  this.#crashHook = crashHook;
2745
- this.#ledgerPrepare = transactionLedger.prepare.bind(transactionLedger);
2746
- this.#ledgerFinalize = transactionLedger.finalize.bind(transactionLedger);
2747
- this.#ledgerMigrate =
2748
- typeof transactionLedger.migrate === "function"
2749
- ? transactionLedger.migrate.bind(transactionLedger)
2815
+ const captureTransactionMethod = (name) => {
2816
+ const method = transactionLedger[name];
2817
+ return typeof method === "function"
2818
+ ? (...args) => Reflect.apply(method, transactionLedger, args)
2750
2819
  : null;
2751
- this.#ledgerQuery = transactionLedger.query.bind(transactionLedger);
2820
+ };
2821
+ this.#ledgerPrepare = captureTransactionMethod("prepare");
2822
+ this.#ledgerFinalize = captureTransactionMethod("finalize");
2823
+ this.#ledgerMigrate = captureTransactionMethod("migrate");
2824
+ this.#ledgerQuery = captureTransactionMethod("query");
2752
2825
  Object.freeze(transactionLedger);
2753
2826
 
2754
2827
  this.tenantId = ownerTenantId;
2755
2828
  this.tenantKey = deriveSkillReleaseTenantKey(ownerTenantId);
2756
- const requestedBase = path.resolve(rootDir);
2757
2829
  try {
2758
- const base = this.#initializeDirectory(requestedBase, {
2759
- recursive: true,
2760
- });
2761
- this.baseDir = base.path;
2762
- this.#assertNoLegacyBaseLayout();
2763
- const tenants = this.#initializeDirectory(
2764
- path.join(this.baseDir, "tenants"),
2765
- { parent: base },
2766
- );
2767
- const tenantRoot = this.#initializeDirectory(
2768
- path.join(tenants.path, this.tenantKey),
2769
- { parent: tenants },
2770
- );
2771
- this.rootDir = tenantRoot.path;
2772
- this.#boundaries = deepFreeze({ base, tenantRoot, tenants });
2773
- this.#rootIdentity = tenantRoot.identity;
2774
- this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2775
- this.#initializeTenantMarker();
2776
- this.#directories = {};
2777
- for (const name of [
2778
- "artifacts",
2779
- "active",
2780
- "journals",
2781
- "locks",
2782
- "state-migrations",
2783
- "staging",
2784
- ]) {
2785
- const directory = path.join(this.rootDir, name);
2786
- this.#directories[name] = this.#initializeDirectory(directory, {
2787
- parent: tenantRoot,
2830
+ if (this.#storeBinding) {
2831
+ this.#boundaries = this.#storeBinding.boundaries;
2832
+ this.baseDir = this.#boundaries.base.path;
2833
+ this.rootDir = this.#boundaries.tenantRoot.path;
2834
+ this.#rootIdentity = this.#boundaries.tenantRoot.identity;
2835
+ this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2836
+ this.#markerIdentity = this.#storeBinding.marker.identity;
2837
+ this.#directories =
2838
+ this.#storeBinding.runtimeDirectories ?? deepFreeze({});
2839
+ this.#assertBoundary();
2840
+ } else {
2841
+ const base = this.#initializeDirectory(requestedBase, {
2842
+ recursive: true,
2843
+ harden: false,
2844
+ });
2845
+ this.baseDir = base.path;
2846
+ this.#assertUnboundNamespace();
2847
+ this.#assertNoLegacyBaseLayout();
2848
+ const tenants = this.#initializeDirectory(
2849
+ path.join(this.baseDir, "tenants"),
2850
+ { parent: base, harden: false },
2851
+ );
2852
+ const tenantRoot = this.#initializeDirectory(
2853
+ path.join(tenants.path, this.tenantKey),
2854
+ { parent: tenants, harden: false },
2855
+ );
2856
+ this.rootDir = tenantRoot.path;
2857
+ this.#assertUnboundNamespace();
2858
+ this.#boundaries = deepFreeze({ base, tenantRoot, tenants });
2859
+ this.#rootIdentity = tenantRoot.identity;
2860
+ this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2861
+ this.#writerControl = createSkillRegistryWriterControl({
2862
+ rootDir: this.rootDir,
2863
+ tenantId: this.tenantId,
2864
+ component: TENANT_MARKER_COMPONENT,
2865
+ fsImpl: this.#fs,
2866
+ });
2867
+ this.#writerControl.runSync(() => {
2868
+ if (this.#secure) {
2869
+ for (const [entry, parent] of [
2870
+ [base, null],
2871
+ [tenants, base],
2872
+ [tenantRoot, tenants],
2873
+ ]) {
2874
+ this.#writerControl.assertIfWriting();
2875
+ const hardened = this.#initializeDirectory(entry.path, {
2876
+ parent,
2877
+ });
2878
+ if (
2879
+ hardened.identity !== entry.identity ||
2880
+ !samePath(hardened.path, entry.path)
2881
+ )
2882
+ throw failure(
2883
+ "SKILL_RELEASE_STORE_UNSAFE",
2884
+ "release bootstrap identity changed before permission hardening",
2885
+ );
2886
+ }
2887
+ }
2888
+ this.#writerControl.assertIfWriting();
2889
+ this.#initializeTenantMarker();
2890
+ this.#directories = {};
2891
+ for (const name of [
2892
+ "artifacts",
2893
+ "active",
2894
+ "journals",
2895
+ "locks",
2896
+ "state-migrations",
2897
+ "staging",
2898
+ ]) {
2899
+ const directory = path.join(this.rootDir, name);
2900
+ this.#directories[name] = this.#initializeDirectory(directory, {
2901
+ parent: tenantRoot,
2902
+ });
2903
+ }
2904
+ this.#directories = deepFreeze(this.#directories);
2905
+ this.#assertBoundary();
2906
+ this.#assertNoLegacyTenantSchemas();
2907
+ this.#recoverAll();
2908
+ this.#cleanupDebris();
2788
2909
  });
2789
2910
  }
2790
- this.#directories = deepFreeze(this.#directories);
2791
- this.#assertBoundary();
2792
- this.#assertNoLegacyTenantSchemas();
2793
- this.#recoverAll();
2794
- this.#cleanupDebris();
2795
2911
  } catch (cause) {
2912
+ if (cause?.code === RRSI_REGISTRY_STORE_POLICY_HOLD_CODE) throw cause;
2796
2913
  if (cause instanceof SkillReleaseRegistryError) throw cause;
2797
2914
  throw failure(
2798
2915
  "SKILL_RELEASE_STORE_UNSAFE",
@@ -2804,20 +2921,28 @@ export class SkillReleaseRegistry {
2804
2921
  this,
2805
2922
  Object.freeze({
2806
2923
  tenantId: ownerTenantId,
2807
- readActive: SkillReleaseRegistry.prototype.readActive.bind(this),
2808
- readState: SkillReleaseRegistry.prototype.readState.bind(this),
2809
- readRelease: SkillReleaseRegistry.prototype.readRelease.bind(this),
2810
- readInventory: SkillReleaseRegistry.prototype.readInventory.bind(this),
2924
+ storePolicyDescriptor: this.#storeBinding?.descriptor ?? null,
2925
+ matchesStorePolicyBinding: (value) =>
2926
+ value === storePolicyBinding && this.#storeBinding !== undefined,
2927
+ // Private reads never dispatch through a genuine subclass or mutable
2928
+ // function.bind property. Constructor recovery uses these paths too.
2929
+ readActive: (name) => this.#readActive(name),
2930
+ readState: (name) => this.#readState(name),
2931
+ readRelease: (value) => this.#readRelease(value),
2932
+ readInventory: () => this.#readInventory(),
2811
2933
  matchesTransactionLedger: (value) => value === transactionLedger,
2812
2934
  }),
2813
2935
  );
2936
+ REGISTRY_WRITERS.set(this, this.#writerControl);
2814
2937
  Object.freeze(this);
2815
2938
  }
2816
2939
 
2817
2940
  #initializeDirectory(
2818
2941
  requestedPath,
2819
- { parent = null, recursive = false } = {},
2942
+ { parent = null, recursive = false, harden = true } = {},
2820
2943
  ) {
2944
+ this.#assertMutationNamespace();
2945
+ const namespaceTarget = assertOutsideRrsiRegistryNamespace(requestedPath);
2821
2946
  const before = lstatOrNull(this.#fs, requestedPath);
2822
2947
  if (before && (!before.isDirectory() || before.isSymbolicLink())) {
2823
2948
  throw failure(
@@ -2826,6 +2951,16 @@ export class SkillReleaseRegistry {
2826
2951
  );
2827
2952
  }
2828
2953
  if (!before) {
2954
+ if (
2955
+ !samePath(
2956
+ assertOutsideRrsiRegistryNamespace(requestedPath),
2957
+ namespaceTarget,
2958
+ )
2959
+ )
2960
+ throw failure(
2961
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
2962
+ "release initialization ancestor changed",
2963
+ );
2829
2964
  this.#fs.mkdirSync(requestedPath, { recursive, mode: 0o700 });
2830
2965
  }
2831
2966
  let stat = this.#fs.lstatSync(requestedPath);
@@ -2837,6 +2972,12 @@ export class SkillReleaseRegistry {
2837
2972
  }
2838
2973
  const capturedIdentity = identity(stat);
2839
2974
  const canonical = realpath(this.#fs, requestedPath);
2975
+ assertOutsideRrsiRegistryNamespace(canonical);
2976
+ if (!samePath(canonical, namespaceTarget))
2977
+ throw failure(
2978
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
2979
+ "release canonical initialization target changed",
2980
+ );
2840
2981
  const canonicalStat = this.#fs.lstatSync(canonical);
2841
2982
  const canonicalParent = realpath(this.#fs, path.dirname(requestedPath));
2842
2983
  const expectedCanonical = path.join(
@@ -2857,7 +2998,7 @@ export class SkillReleaseRegistry {
2857
2998
  "release registry directory escaped its canonical parent",
2858
2999
  );
2859
3000
  }
2860
- if (this.#secure) {
3001
+ if (this.#secure && harden) {
2861
3002
  ensurePrivateDirectory(canonical, {
2862
3003
  applyWindowsAcl: true,
2863
3004
  failIfUnavailable: true,
@@ -2878,6 +3019,18 @@ export class SkillReleaseRegistry {
2878
3019
  return deepFreeze({ path: canonical, identity: capturedIdentity });
2879
3020
  }
2880
3021
 
3022
+ #assertUnboundNamespace() {
3023
+ if (this.#storeBinding) return;
3024
+ for (const directory of [this.baseDir, this.rootDir])
3025
+ if (directory !== undefined)
3026
+ assertOutsideRrsiRegistryNamespace(directory);
3027
+ }
3028
+
3029
+ #assertMutationNamespace() {
3030
+ this.#storeBinding?.assertMutationAllowed();
3031
+ this.#assertUnboundNamespace();
3032
+ }
3033
+
2881
3034
  #assertNoLegacyBaseLayout() {
2882
3035
  for (const entry of this.#fs.readdirSync(this.baseDir)) {
2883
3036
  if (entry !== "tenants") {
@@ -2890,6 +3043,7 @@ export class SkillReleaseRegistry {
2890
3043
  }
2891
3044
 
2892
3045
  #initializeTenantMarker() {
3046
+ this.#assertMutationNamespace();
2893
3047
  return withEvolutionFileIdentity(
2894
3048
  this.#fs,
2895
3049
  this.#markerPath,
@@ -2899,6 +3053,7 @@ export class SkillReleaseRegistry {
2899
3053
  }
2900
3054
 
2901
3055
  #initializeTenantMarkerWithIdentity(sameStable) {
3056
+ this.#assertMutationNamespace();
2902
3057
  const existing = lstatOrNull(this.#fs, this.#markerPath);
2903
3058
  if (existing) {
2904
3059
  const verified = this.#readAndVerifyTenantMarker();
@@ -3002,6 +3157,10 @@ export class SkillReleaseRegistry {
3002
3157
  }
3003
3158
 
3004
3159
  #readAndVerifyTenantMarker() {
3160
+ if (this.#storeBinding) {
3161
+ this.#storeBinding.recheck();
3162
+ return this.#storeBinding.marker;
3163
+ }
3005
3164
  try {
3006
3165
  const stored = readBoundedSingleLinkFile(
3007
3166
  this.#fs,
@@ -3053,6 +3212,12 @@ export class SkillReleaseRegistry {
3053
3212
  }
3054
3213
 
3055
3214
  #assertBoundary() {
3215
+ if (this.#storeBinding) {
3216
+ this.#storeBinding.recheck();
3217
+ return;
3218
+ }
3219
+ this.#assertUnboundNamespace();
3220
+ this.#writerControl?.assertIfWriting();
3056
3221
  for (const entry of [
3057
3222
  ...Object.values(this.#boundaries),
3058
3223
  ...Object.values(this.#directories),
@@ -3253,6 +3418,7 @@ export class SkillReleaseRegistry {
3253
3418
  }
3254
3419
 
3255
3420
  #writeTemporary(fileName, value) {
3421
+ this.#assertMutationNamespace();
3256
3422
  if (!TEMP_PATTERN.test(fileName)) {
3257
3423
  throw failure("SKILL_RELEASE_STORE_UNSAFE", "temporary name is invalid");
3258
3424
  }
@@ -3263,6 +3429,7 @@ export class SkillReleaseRegistry {
3263
3429
  }
3264
3430
 
3265
3431
  #writeTemporaryWithIdentity(filePath, value, sameStable) {
3432
+ this.#assertMutationNamespace();
3266
3433
  const bytes = serialize(value);
3267
3434
  let descriptor = null;
3268
3435
  let writtenIdentity = null;
@@ -3312,6 +3479,7 @@ export class SkillReleaseRegistry {
3312
3479
  }
3313
3480
 
3314
3481
  #atomicWrite(area, destination, value) {
3482
+ this.#assertMutationNamespace();
3315
3483
  const expectedBytes = serialize(value);
3316
3484
  const name = `.write-${process.pid}-${this.#token()}.tmp`;
3317
3485
  const temporary = this.#writeTemporary(name, value);
@@ -3357,6 +3525,7 @@ export class SkillReleaseRegistry {
3357
3525
  }
3358
3526
 
3359
3527
  #unlink(filePath, directory) {
3528
+ this.#assertMutationNamespace();
3360
3529
  try {
3361
3530
  this.#fs.unlinkSync(filePath);
3362
3531
  fsyncDirectory(this.#fs, directory);
@@ -3366,6 +3535,7 @@ export class SkillReleaseRegistry {
3366
3535
  }
3367
3536
 
3368
3537
  #publishRelease(release) {
3538
+ this.#assertMutationNamespace();
3369
3539
  const destination = this.#releasePath(release.releaseDigest);
3370
3540
  const name = `.release-${process.pid}-${this.#token()}.tmp`;
3371
3541
  const temporary = this.#writeTemporary(name, release);
@@ -3377,7 +3547,7 @@ export class SkillReleaseRegistry {
3377
3547
  this.#fs.linkSync(temporary, destination);
3378
3548
  } catch (error) {
3379
3549
  if (error?.code !== "EEXIST") throw error;
3380
- const existing = this.readRelease(release.releaseDigest);
3550
+ const existing = this.#readRelease(release.releaseDigest);
3381
3551
  if (!serialize(existing).equals(bytes)) {
3382
3552
  throw failure("SKILL_RELEASE_CONFLICT", "release digest collision");
3383
3553
  }
@@ -3428,17 +3598,26 @@ export class SkillReleaseRegistry {
3428
3598
  }
3429
3599
 
3430
3600
  #createRelease(input) {
3601
+ this.#assertMutationNamespace();
3431
3602
  const release = buildSkillRelease(input);
3432
3603
  const created = this.#publishRelease(release);
3433
3604
  return deepFreeze({ release, created });
3434
3605
  }
3435
3606
 
3436
3607
  migrateLegacyRelease(input, migrationAuthority) {
3608
+ this.#assertMutationNamespace();
3437
3609
  if (arguments.length !== 2) {
3438
3610
  throw migrationRequired(
3439
3611
  "legacy release migration requires input and a durable audit authority",
3440
3612
  );
3441
3613
  }
3614
+ return this.#writerControl.runSync(() =>
3615
+ this.#migrateLegacyRelease(input, migrationAuthority),
3616
+ );
3617
+ }
3618
+
3619
+ #migrateLegacyRelease(input, migrationAuthority) {
3620
+ this.#assertMutationNamespace();
3442
3621
  assertExactKeys(
3443
3622
  migrationAuthority,
3444
3623
  RELEASE_MIGRATION_AUTHORITY_KEYS,
@@ -3575,11 +3754,19 @@ export class SkillReleaseRegistry {
3575
3754
  }
3576
3755
 
3577
3756
  migrateLegacyState(planInput, migrationAuthority) {
3757
+ this.#assertMutationNamespace();
3578
3758
  if (arguments.length !== 2 || this.#ledgerMigrate === null) {
3579
3759
  throw migrationRequired(
3580
3760
  "legacy state migration requires a plan, durable authority, and authenticated ledger migration port",
3581
3761
  );
3582
3762
  }
3763
+ return this.#writerControl.runSync(() =>
3764
+ this.#migrateLegacyState(planInput, migrationAuthority),
3765
+ );
3766
+ }
3767
+
3768
+ #migrateLegacyState(planInput, migrationAuthority) {
3769
+ this.#assertMutationNamespace();
3583
3770
  const plan = verifySkillReleaseStateMigrationPlan(planInput);
3584
3771
  if (plan.tenantId !== this.tenantId) {
3585
3772
  throw migrationRequired("state migration plan belongs to another tenant");
@@ -3607,8 +3794,8 @@ export class SkillReleaseRegistry {
3607
3794
  migrationAuthority.handlerArtifactDigest,
3608
3795
  "stateMigrationAuthority.handlerArtifactDigest",
3609
3796
  );
3610
- const active = this.readRelease(plan.activeReleaseDigest);
3611
- const lastKnownGood = this.readRelease(plan.lastKnownGoodReleaseDigest);
3797
+ const active = this.#readRelease(plan.activeReleaseDigest);
3798
+ const lastKnownGood = this.#readRelease(plan.lastKnownGoodReleaseDigest);
3612
3799
  if (
3613
3800
  active.skillName !== plan.skillName ||
3614
3801
  lastKnownGood.skillName !== plan.skillName ||
@@ -3681,7 +3868,7 @@ export class SkillReleaseRegistry {
3681
3868
  { stateMigrationDigest: plan.stateMigrationDigest },
3682
3869
  );
3683
3870
  }
3684
- const existing = this.readState(plan.skillName);
3871
+ const existing = this.#readState(plan.skillName);
3685
3872
  if (existing.revision > 0) {
3686
3873
  if (
3687
3874
  existing.transactionId !== plan.stateMigrationDigest ||
@@ -3783,7 +3970,19 @@ export class SkillReleaseRegistry {
3783
3970
  }
3784
3971
 
3785
3972
  readRelease(releaseDigest) {
3973
+ return this.#readRelease(releaseDigest);
3974
+ }
3975
+
3976
+ #readRelease(releaseDigest) {
3786
3977
  const expected = digest(releaseDigest, "releaseDigest");
3978
+ if (
3979
+ ["uninitialized", "authenticated-empty-read-only"].includes(
3980
+ this.#runtimeMode,
3981
+ )
3982
+ ) {
3983
+ this.#assertBoundary();
3984
+ throw failure("SKILL_RELEASE_NOT_FOUND", "release was not found");
3985
+ }
3787
3986
  let value;
3788
3987
  try {
3789
3988
  value = this.#readJson(
@@ -3819,6 +4018,14 @@ export class SkillReleaseRegistry {
3819
4018
 
3820
4019
  #readStateRaw(name) {
3821
4020
  const normalizedName = skillName(name);
4021
+ if (
4022
+ ["uninitialized", "authenticated-empty-read-only"].includes(
4023
+ this.#runtimeMode,
4024
+ )
4025
+ ) {
4026
+ this.#assertBoundary();
4027
+ return initialState(normalizedName, this.tenantId);
4028
+ }
3822
4029
  try {
3823
4030
  const state = verifySkillReleaseState(
3824
4031
  this.#readJson(
@@ -3888,8 +4095,8 @@ export class SkillReleaseRegistry {
3888
4095
  "active pointer is not finalized by the trusted transaction ledger",
3889
4096
  );
3890
4097
  }
3891
- const active = this.readRelease(state.activeReleaseDigest);
3892
- const lkg = this.readRelease(state.lastKnownGoodReleaseDigest);
4098
+ const active = this.#readRelease(state.activeReleaseDigest);
4099
+ const lkg = this.#readRelease(state.lastKnownGoodReleaseDigest);
3893
4100
  if (
3894
4101
  active.skillName !== state.skillName ||
3895
4102
  lkg.skillName !== state.skillName ||
@@ -3907,17 +4114,25 @@ export class SkillReleaseRegistry {
3907
4114
  }
3908
4115
 
3909
4116
  readState(name) {
4117
+ return this.#readState(name);
4118
+ }
4119
+
4120
+ #readState(name) {
3910
4121
  const state = this.#readStateRaw(name);
3911
4122
  return state.revision === 0 ? state : this.#verifyCommittedState(state);
3912
4123
  }
3913
4124
 
3914
4125
  readActive(name) {
3915
- const state = this.readState(name);
4126
+ return this.#readActive(name);
4127
+ }
4128
+
4129
+ #readActive(name) {
4130
+ const state = this.#readState(name);
3916
4131
  return state.revision === 0
3917
4132
  ? null
3918
4133
  : deepFreeze({
3919
4134
  state,
3920
- release: this.readRelease(state.activeReleaseDigest),
4135
+ release: this.#readRelease(state.activeReleaseDigest),
3921
4136
  });
3922
4137
  }
3923
4138
 
@@ -3981,7 +4196,17 @@ export class SkillReleaseRegistry {
3981
4196
  }
3982
4197
 
3983
4198
  readInventory() {
4199
+ return this.#readInventory();
4200
+ }
4201
+
4202
+ #readInventory() {
3984
4203
  this.#assertBoundary();
4204
+ if (
4205
+ ["uninitialized", "authenticated-empty-read-only"].includes(
4206
+ this.#runtimeMode,
4207
+ )
4208
+ )
4209
+ return deepFreeze({ active: [], releases: [] });
3985
4210
  const releasePattern = /^[a-f0-9]{64}\.json$/u;
3986
4211
  const statePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.json$/u;
3987
4212
  const beforeReleases = this.#readInventoryNames(
@@ -3999,11 +4224,11 @@ export class SkillReleaseRegistry {
3999
4224
  );
4000
4225
  }
4001
4226
  const releases = beforeReleases.map((name) =>
4002
- this.readRelease(`sha256:${name.slice(0, -".json".length)}`),
4227
+ this.#readRelease(`sha256:${name.slice(0, -".json".length)}`),
4003
4228
  );
4004
4229
  const active = beforeStates.map((name) => {
4005
4230
  const skill = name.slice(0, -".json".length);
4006
- const value = this.readActive(skill);
4231
+ const value = this.#readActive(skill);
4007
4232
  if (value === null) {
4008
4233
  throw failure(
4009
4234
  "SKILL_RELEASE_STATE_CORRUPT",
@@ -4041,7 +4266,7 @@ export class SkillReleaseRegistry {
4041
4266
  const afterReleases = this.#readInventoryNames("artifacts", releasePattern);
4042
4267
  const afterStates = this.#readInventoryNames("active", statePattern);
4043
4268
  const afterStateDigests = afterStates.map(
4044
- (name) => this.readState(name.slice(0, -".json".length)).stateDigest,
4269
+ (name) => this.#readState(name.slice(0, -".json".length)).stateDigest,
4045
4270
  );
4046
4271
  if (
4047
4272
  canonicalJson(beforeReleases) !== canonicalJson(afterReleases) ||
@@ -4060,7 +4285,7 @@ export class SkillReleaseRegistry {
4060
4285
  }
4061
4286
 
4062
4287
  pinActive(name) {
4063
- const active = this.readActive(name);
4288
+ const active = this.#readActive(name);
4064
4289
  if (!active)
4065
4290
  throw failure("SKILL_RELEASE_NOT_ACTIVE", "Skill has no active release");
4066
4291
  const pin = Object.freeze(Object.create(null));
@@ -4094,7 +4319,7 @@ export class SkillReleaseRegistry {
4094
4319
  "pinned activation is not committed",
4095
4320
  );
4096
4321
  }
4097
- return this.readRelease(binding.releaseDigest);
4322
+ return this.#readRelease(binding.releaseDigest);
4098
4323
  }
4099
4324
 
4100
4325
  #owner(kind, token, { skill = null, transactionId = null, fence = 0 } = {}) {
@@ -4210,6 +4435,7 @@ export class SkillReleaseRegistry {
4210
4435
  }
4211
4436
 
4212
4437
  #createLock(lockPath, owner) {
4438
+ this.#assertMutationNamespace();
4213
4439
  this.#fs.mkdirSync(lockPath, { mode: 0o700 });
4214
4440
  let descriptor = null;
4215
4441
  try {
@@ -4239,6 +4465,7 @@ export class SkillReleaseRegistry {
4239
4465
  }
4240
4466
 
4241
4467
  #removeLock(lockPath, expectedToken = null) {
4468
+ this.#assertMutationNamespace();
4242
4469
  let owner;
4243
4470
  try {
4244
4471
  owner = this.#readOwner(lockPath);
@@ -4300,6 +4527,7 @@ export class SkillReleaseRegistry {
4300
4527
  }
4301
4528
 
4302
4529
  #renewLease(lease) {
4530
+ this.#assertMutationNamespace();
4303
4531
  const current = this.#readOwner(lease.lockPath);
4304
4532
  if (
4305
4533
  current.token !== lease.token ||
@@ -4338,6 +4566,7 @@ export class SkillReleaseRegistry {
4338
4566
  }
4339
4567
 
4340
4568
  #acquireLease(name, transactionId, expectedRevision, expectedParentDigest) {
4569
+ this.#assertMutationNamespace();
4341
4570
  const journalPath = this.#journalPath(name);
4342
4571
  if (this.#exists(journalPath)) {
4343
4572
  this.#withRecoveryLock(() => this.#recoverSkill(name));
@@ -4350,11 +4579,11 @@ export class SkillReleaseRegistry {
4350
4579
  }
4351
4580
  const lockPath = this.#leasePath(name);
4352
4581
  for (let attempt = 0; attempt < 2; attempt += 1) {
4353
- const state = this.readState(name);
4582
+ const state = this.#readState(name);
4354
4583
  const active =
4355
4584
  state.activeReleaseDigest === null
4356
4585
  ? null
4357
- : this.readRelease(state.activeReleaseDigest);
4586
+ : this.#readRelease(state.activeReleaseDigest);
4358
4587
  const actualParent = active?.contentDigest ?? EMPTY_SKILL_ACTIVE_DIGEST;
4359
4588
  if (
4360
4589
  state.revision !== expectedRevision ||
@@ -4805,6 +5034,7 @@ export class SkillReleaseRegistry {
4805
5034
  }
4806
5035
 
4807
5036
  #prepare(intent, targetRelease) {
5037
+ this.#assertMutationNamespace();
4808
5038
  let projection;
4809
5039
  try {
4810
5040
  projection = this.#ledgerPrepare(intent, targetRelease);
@@ -4836,6 +5066,7 @@ export class SkillReleaseRegistry {
4836
5066
  }
4837
5067
 
4838
5068
  #finalize(journal, prepareReceipt) {
5069
+ this.#assertMutationNamespace();
4839
5070
  const request = deepFreeze({
4840
5071
  authorityReceiptDigest: journal.intent.authorityReceiptDigest,
4841
5072
  expectedPrepareReceiptDigest: prepareReceipt.receiptDigest,
@@ -4882,6 +5113,7 @@ export class SkillReleaseRegistry {
4882
5113
  }
4883
5114
 
4884
5115
  #writePointer(state, stagedFile) {
5116
+ this.#assertMutationNamespace();
4885
5117
  const stagedPath = this.#path("staging", stagedFile);
4886
5118
  if (!this.#exists(stagedPath)) this.#writeTemporary(stagedFile, state);
4887
5119
  const expectedBytes = serialize(state);
@@ -4994,7 +5226,7 @@ export class SkillReleaseRegistry {
4994
5226
  );
4995
5227
  }
4996
5228
 
4997
- const verifiedRelease = this.readRelease(release.releaseDigest);
5229
+ const verifiedRelease = this.#readRelease(release.releaseDigest);
4998
5230
  if (
4999
5231
  verifiedRelease.tenantId !== this.tenantId ||
5000
5232
  verifiedRelease.skillName !== state.skillName ||
@@ -5022,7 +5254,7 @@ export class SkillReleaseRegistry {
5022
5254
  #assertJournalFinalizationArtifacts(journal) {
5023
5255
  let release;
5024
5256
  try {
5025
- release = this.readRelease(journal.nextState.activeReleaseDigest);
5257
+ release = this.#readRelease(journal.nextState.activeReleaseDigest);
5026
5258
  } catch (cause) {
5027
5259
  throw failure(
5028
5260
  "SKILL_RELEASE_FINALIZATION_INPUT_INVALID",
@@ -5091,6 +5323,7 @@ export class SkillReleaseRegistry {
5091
5323
  }
5092
5324
 
5093
5325
  #recoverJournal(journal) {
5326
+ this.#assertMutationNamespace();
5094
5327
  const expected = {
5095
5328
  authorityReceiptDigest: journal.intent.authorityReceiptDigest,
5096
5329
  intentDigest: journal.intent.intentDigest,
@@ -5132,6 +5365,7 @@ export class SkillReleaseRegistry {
5132
5365
  }
5133
5366
 
5134
5367
  #recoverSkill(name, { force = false } = {}) {
5368
+ this.#assertMutationNamespace();
5135
5369
  const journalPath = this.#journalPath(name);
5136
5370
  const lockPath = this.#leasePath(name);
5137
5371
  if (!this.#exists(journalPath)) {
@@ -5174,6 +5408,7 @@ export class SkillReleaseRegistry {
5174
5408
  }
5175
5409
 
5176
5410
  #recoverStateMigration(journal, { force = false } = {}) {
5411
+ this.#assertMutationNamespace();
5177
5412
  const lockPath = this.#leasePath(journal.skillName);
5178
5413
  if (this.#exists(lockPath)) {
5179
5414
  const owner = this.#readOwner(lockPath);
@@ -5222,13 +5457,14 @@ export class SkillReleaseRegistry {
5222
5457
  journal.state,
5223
5458
  );
5224
5459
  }
5225
- const release = this.readRelease(journal.state.activeReleaseDigest);
5460
+ const release = this.#readRelease(journal.state.activeReleaseDigest);
5226
5461
  this.#assertFinalizationArtifacts(journal.state, release);
5227
5462
  this.#cleanupStateMigration(journal);
5228
5463
  return "committed";
5229
5464
  }
5230
5465
 
5231
5466
  #recoverAll() {
5467
+ this.#assertMutationNamespace();
5232
5468
  this.#withRecoveryLock(() => {
5233
5469
  for (const name of this.#fs.readdirSync(
5234
5470
  this.#directories["state-migrations"].path,
@@ -5275,6 +5511,7 @@ export class SkillReleaseRegistry {
5275
5511
  }
5276
5512
 
5277
5513
  #cleanupDebris() {
5514
+ this.#assertMutationNamespace();
5278
5515
  const referenced = new Set();
5279
5516
  for (const name of this.#fs.readdirSync(this.#directories.journals.path)) {
5280
5517
  if (name.endsWith(".json")) {
@@ -5463,6 +5700,14 @@ export class SkillReleaseRegistry {
5463
5700
  }
5464
5701
 
5465
5702
  async applyTransition(capability) {
5703
+ this.#assertMutationNamespace();
5704
+ return this.#writerControl.runAsync(() =>
5705
+ this.#applyTransition(capability),
5706
+ );
5707
+ }
5708
+
5709
+ async #applyTransition(capability) {
5710
+ this.#assertMutationNamespace();
5466
5711
  const payload = this.#validateTransitionPayload(
5467
5712
  consumeRegistryTransitionCapability(capability, this),
5468
5713
  );
@@ -5477,7 +5722,7 @@ export class SkillReleaseRegistry {
5477
5722
  target = created.release;
5478
5723
  releaseCreated = created.created;
5479
5724
  } else {
5480
- target = this.readRelease(payload.targetReleaseDigest);
5725
+ target = this.#readRelease(payload.targetReleaseDigest);
5481
5726
  }
5482
5727
  if (
5483
5728
  target.skillName !== payload.skillName ||