chainlesschain 0.166.90 → 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 (222) hide show
  1. package/README.md +15 -13
  2. package/package.json +4 -4
  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-CZzXRe1-.js → AIOps-C74YzqwJ.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-_AZfbW1Q.js → ActionButton-TFef1hOE.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CzaUx_wv.js → Analytics-CYsWpkkU.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-xHEeeD-m.js → AppLayout-CFf9kjwu.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-DmTbtudE.js → Artifacts-TQqa94YO.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-Cn4ng4fo.js → Audit-B79ayqfS.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DLUY1VD2.js → BackgroundAgents-pjkHfLP9.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-B2v--wB6.js → Backup-CE6A-t_r.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-Bgih7yAv.js → BaseInput-CwcgWMBY.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-1MiiA3yA.js → Chat-BIkDNesY.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CPLynmbb.js → ChatBubbleRenderer-DgaokYts.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-DsyBa_NO.js → Checkbox-MbypIy5V.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-B7WCFx9H.js → Codegen-DiFHWDnt.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-D2x4GBGm.js → Col-BNMlYMso.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-Rnwg9nea.js → Community-B3HVyHOX.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BPczlrRh.js → Compact-C7hlAubb.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-Br1L_wGU.js → Compliance-PaXZu6sE.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DlsWB_oS.js → Cowork-BGiojbm-.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-BWo_KGpG.js → Cron-Bmr-1QAx.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-Cug7N8ge.js → Crosschain-BwUvWCVd.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CMbyOZJN.js → DID-k_4QZocW.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-C4dl_UaE.js → Dashboard-_ieRo2C5.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-CBrC7M-9.js → Dropdown-DYHh6T27.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DTq7tU4b.js → EmailListRenderer-BNlQcWQX.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DWP3csxS.js → EvolutionSettings-DIkZ6U2D.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DZl7zuv_.js → FamilyGuardDashboard-Dq7qSr0P.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-W-GSlVK5.js → Federation-C64e3Cbx.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DMB7xYFV.js → FormItemContext-D-GE2vUa.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DNv8GEoq.js → GenericCardRenderer-DO3B2gis.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BZ0Bbzw6.js → Git-0ETirIQH.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BNEdcOM5.js → Governance-C9fnRygX.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-C8249gIz.js → Inference-CLJ9RTsK.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-ngzebU3e.js → KnowledgeGraph-D3C_GxrN.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-CP15th-f.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-CaH59OsY.js → Marketplace-GF_t6hJ_.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-C07vnJev.js → McpTools-BGsGzgQs.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-CqAOkVAS.js → Memory-CcrY2A0j.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-qp7mZimq.js → MobileBridge-Bi4T0RlS.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-DKhbqvTw.js → MobileProjects-DvjEGyvf.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-CRYCnWXv.js → Mtc-DL77Vf-k.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-Z08IrKws.js → MtcAudit-CDy_Uswb.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-BWdatUnH.js → Multisig-DL0BAO_c.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-BKWiCZ_m.js → NLProgramming-B-woh5IR.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Bgpzk3sm.js → Notes-CEFVCxk7.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-DvtZEktR.js → NotificationSettings-BqPPMuAP.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-CBcy0szc.js → OrderTableRenderer-GUKQ1xwp.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-DRRL6vW1.js → Organization-B1gX8jlr.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-COmfB8Ns.js → Overflow-CeMxuUZy.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-BqMq_DSa.js → P2P-B5aIRWwJ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-BX7iNvle.js → PdhVaultBrowser-6rYgejd4.js} +4 -4
  56. package/src/assets/web-panel/assets/{Permissions-DzYkjmV_.js → Permissions-CqCp2SIl.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BBTcxBbN.js → PersonalDataHub-BsA7DJWW.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-eRkYFSbO.js → Pipeline-CiW6HeZh.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Ch7IFKBh.js → Privacy-DckUOLYq.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-Ci8EcBYg.js → ProjectInit-CZppOOYR.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-B4lYHFbI.js → ProjectSettings-B9QPzhDU.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-zkE5cCo_.js → Projects-BErjjGha.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BKDVD3_e.js → Providers-DehU6Qiz.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BromrHlf.js → QrScannerModal-E1SUvv1m.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CCgoY1gR.js → QuickAsk-COWFxyH3.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DCPZvpq7.js → Recommend-D26pWKxX.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-DPnFP8HU.js → RemoteSession-DCOIaId3.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-l6r8ytAs.js → Reputation-DT_AHGAR.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-ke9Mk1cx.js → Row-B50S-1nl.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-DQOEzUEn.js → RssFeed-BaBnHg3Q.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BqgA0aUz.js → Search-BVdnLuuS.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-FeGD_jqV.js → Security-BnacH74J.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-4kiYYAjZ.js → Services-CxM08Zch.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-BbU8Xegs.js → Skeleton-DE7CIc1N.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-Dl2bUMUL.js → Skills-CGI0SJmf.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-xRGALeaZ.js → Sla-DpEzPcqc.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-DZfd4RDm.js → SpeechSettings-CTmnmMHn.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BRtCV9Ga.js → SyncSettings-Dxgrd9hd.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-DVRQklfG.js → Tasks-CW4slS0A.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-BbhE5jt5.js → Templates-DxvGWDgB.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-qXPDNKbK.js → Tenant-_Q0o2tNK.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CV48Ks7E.js → Terminal-BTZn8pow.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BLGfJIDr.js → TimelineRenderer-CauL0KFe.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-7G9H6Hrt.js → Tokens-CDoM2qeT.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger--F64N11F.js → Trigger-B-QYGEU7.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Cq1r-D_y.js → Trust-BD6XJHT-.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-Dqyu4RVh.js → UkeySign-x4TFwCy0.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DuFmWH_B.js → VideoEditing-t3imBK_0.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-C3mg7EWP.js → Wallet-BCfkWwNC.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-CDK-Aj_X.js → WebAuthn-WH314Mdm.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor--K7K-T1F.js → WorkflowEditor-jUlcjrUg.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BQDcS6VP.js → chat-Dg3VASTL.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BKxJL2-T.js → colors-BNvmBRKE.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-CFjQAMbY.js → compact-item-BGOfoqf4.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DbgCsdQd.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-BhkaOBNv.js → hasIn-Bg3AjCrq.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DvWWFJHJ.js → index--I3UF5t1.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DJ2OiRvh.js → index-2D04Zltx.js} +3 -3
  100. package/src/assets/web-panel/assets/{index-BuWPqSGT.js → index-60AnjUTX.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D2Zb-Kd1.js → index-7QJUWemf.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-C0DzhUOX.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-COGy6wXn.js → index-B0mgngoB.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-bMX8BBLE.js → index-BBCMulQ-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CE506mgj.js → index-BSNhW95G.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CoOu7sdP.js → index-B_JmInC0.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B4LlAJqc.js → index-BaPvEvB4.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CRtUDiXx.js → index-Bkz1tgFR.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Du_SxxBY.js → index-BmTacaQV.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CSUDlsIr.js → index-CCFZN66A.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-3uR0ThJO.js → index-COol3xfA.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DmYK9Tqt.js → index-CY8cRKHR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-T9ka3Xj3.js → index-Cbp-wp-U.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CB4oHynY.js → index-Co_LnCWD.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DEwHywz9.js → index-Cx2EXRfr.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CUs7XpUO.js → index-D-mSvCQK.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BRqlCTrz.js → index-D072oLjp.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-sKfUUldY.js → index-D6UqK83L.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Dhfa_BIl.js → index-DF_FKSVH.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-D9sVcw6v.js → index-DLwEXRrb.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-3djsY75k.js → index-DO0VlNtc.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BfGGsAU7.js → index-DS04wRll.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Dn2QSsuI.js → index-DYn5DnDk.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-D-Yh3-1z.js → index-D_O2ZjPk.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BNjYPJNU.js → index-DcCnO0RU.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DP1NrM9J.js → index-Dkp-okWa.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DdcrixaQ.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-7BY44UEv.js → index-Wo0f2iqb.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DjmVlpap.js → index-ZD5Kd8tx.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-3YutaXnp.js → index-fOwii3LP.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-aPdVzagA.js → index-hG7jXGEW.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-De7daEnc.js → index-pVdQieac.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CJoXgJ2N.js → index-uH2LnAs_.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-DFt48Z-x.js → index-xzaUx19r.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-wrqabmui.js → initDefaultProps-B8PN9AxJ.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BoyB3ilP.js → motion-BHivfw5Q.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Cq31cSFE.js → move-B0QU5nDd.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BkxNt-8H.js → mtc-parser-DRwRM3PE.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DofGni53.js → omit-SHt2rV2p.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-BnluLL16.js → pickAttrs-CcmDlEb2.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-C-yegJSP.js → placementArrow-DYatmXDS.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-CD3ziNhu.js → responsiveObserve-B7qrsXq5.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-ToZO4gQ1.js → slide-BRGhlOWd.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DFVmDmVl.js → statusUtils-CT-7NXsQ.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-De0Y8g1O.js → styleChecker-rZdw_Yyp.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-wBKIYFKX.js → useFlexGapSupport-D8YNIP4P.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CP9nmUMJ.js → useFs-B8pt0Gu-.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-vFGrVDyp.js → usePersonalDataHub-VMmYM1tt.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-BcBIjvjH.js → vnode-UNDuoPoq.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DnXDAQxA.js → zoom-dN-u667S.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/agent-process-ownership.js +121 -0
  156. package/src/commands/agent.js +2 -0
  157. package/src/commands/hub.js +86 -9
  158. package/src/data/changelog.json +54 -2
  159. package/src/lib/audit-logger.js +46 -20
  160. package/src/lib/checkpoint-restore-saga.js +11 -1
  161. package/src/lib/eval/verify01-host-evidence.js +36 -3
  162. package/src/lib/evolution/evolution-artifact-ports.js +26 -0
  163. package/src/lib/evolution/evolution-eval-cohort-enrollment.js +713 -47
  164. package/src/lib/evolution/evolution-eval-gate.js +146 -0
  165. package/src/lib/evolution/evolution-eval-launch-admission.js +168 -90
  166. package/src/lib/evolution/evolution-eval-ledger-capture.js +50 -0
  167. package/src/lib/evolution/evolution-eval-readonly-audit.js +106 -0
  168. package/src/lib/evolution/evolution-ledger-file-backend.js +20 -0
  169. package/src/lib/evolution/evolution-ledger-ports.js +59 -27
  170. package/src/lib/evolution/evolution-ledger-v2-journal.js +55 -18
  171. package/src/lib/evolution/evolution-workbench-file-resources.js +19 -1
  172. package/src/lib/evolution/rrsi-cohort-registration.js +275 -0
  173. package/src/lib/evolution/rrsi-contracts.js +742 -0
  174. package/src/lib/evolution/rrsi-data.js +196 -0
  175. package/src/lib/evolution/rrsi-evaluation-adapter.js +275 -0
  176. package/src/lib/evolution/rrsi-evaluation-variants.js +267 -0
  177. package/src/lib/evolution/rrsi-group-statistics.js +553 -0
  178. package/src/lib/evolution/rrsi-history-ledger-adapter.js +3261 -0
  179. package/src/lib/evolution/rrsi-native-batch-evidence.js +520 -0
  180. package/src/lib/evolution/rrsi-native-eval-row-collector.js +538 -0
  181. package/src/lib/evolution/rrsi-native-evaluation-batch.js +547 -0
  182. package/src/lib/evolution/rrsi-native-evaluation-plan.js +431 -0
  183. package/src/lib/evolution/rrsi-native-group-statistics-plan.js +121 -0
  184. package/src/lib/evolution/rrsi-native-group-statistics.js +482 -0
  185. package/src/lib/evolution/rrsi-native-quality-receipt-contracts.js +321 -0
  186. package/src/lib/evolution/rrsi-native-quality-receipt.js +256 -0
  187. package/src/lib/evolution/rrsi-native-statistics-protocol.js +330 -0
  188. package/src/lib/evolution/rrsi-parent-binding.js +290 -0
  189. package/src/lib/evolution/rrsi-pm-execution-bridge.js +500 -0
  190. package/src/lib/evolution/rrsi-pm-training-mapping.js +134 -0
  191. package/src/lib/evolution/rrsi-preparation-contracts.js +213 -0
  192. package/src/lib/evolution/rrsi-registry-history-binding.js +193 -0
  193. package/src/lib/evolution/rrsi-registry-store-policy.js +1191 -0
  194. package/src/lib/evolution/rrsi-runtime-composition.js +79 -0
  195. package/src/lib/evolution/rrsi-selector.js +434 -0
  196. package/src/lib/evolution/rrsi-statistics-simulation.js +354 -0
  197. package/src/lib/evolution/skill-candidate-registry.js +216 -29
  198. package/src/lib/evolution/skill-registry-maintenance.js +80 -0
  199. package/src/lib/evolution/skill-registry-writer-control.js +138 -0
  200. package/src/lib/evolution/skill-release-registry.js +399 -169
  201. package/src/lib/formal-quality-eval-runtime.js +2 -14
  202. package/src/lib/goal-store.js +225 -16
  203. package/src/lib/process-execution-broker/index.js +91 -1
  204. package/src/lib/process-execution-broker/platform-sandbox.js +42 -0
  205. package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +757 -0
  206. package/src/lib/process-execution-broker/windows-native-evaluator.js +316 -0
  207. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  208. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  209. package/src/lib/process-execution-broker/windows-sandbox.cs +383 -11
  210. package/src/lib/record-replay/skill-recorder.js +38 -3
  211. package/src/lib/scheduler-kernel/authority-resolver.js +12 -163
  212. package/src/lib/scheduler-kernel/contract.js +27 -414
  213. package/src/lib/scheduler-kernel/runtime.js +21 -823
  214. package/src/lib/scheduler-kernel/service.js +11 -328
  215. package/src/lib/scheduler-kernel/source-locator-path.js +7 -142
  216. package/src/lib/scheduler-kernel/store.js +67 -5931
  217. package/src/lib/secure-fs.js +16 -1314
  218. package/src/lib/with-file-lock.js +122 -20
  219. package/src/assets/web-panel/assets/MarkdownRenderer-CW3B3JDq.js +0 -1
  220. package/src/assets/web-panel/assets/devWarning-DlIv9Mbc.js +0 -1
  221. package/src/assets/web-panel/assets/index-BC972Grv.js +0 -1
  222. package/src/assets/web-panel/assets/index-CVifyQqL.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,32 @@ 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 = "uninitialized";
2779
+ } else assertOutsideRrsiRegistryNamespace(requestedBase);
2712
2780
  if (
2713
2781
  !transactionLedger ||
2714
2782
  typeof transactionLedger.prepare !== "function" ||
@@ -2742,57 +2810,103 @@ export class SkillReleaseRegistry {
2742
2810
  this.#now = now;
2743
2811
  this.#leaseTtlMs = leaseTtlMs;
2744
2812
  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)
2813
+ const captureTransactionMethod = (name) => {
2814
+ const method = transactionLedger[name];
2815
+ return typeof method === "function"
2816
+ ? (...args) => Reflect.apply(method, transactionLedger, args)
2750
2817
  : null;
2751
- this.#ledgerQuery = transactionLedger.query.bind(transactionLedger);
2818
+ };
2819
+ this.#ledgerPrepare = captureTransactionMethod("prepare");
2820
+ this.#ledgerFinalize = captureTransactionMethod("finalize");
2821
+ this.#ledgerMigrate = captureTransactionMethod("migrate");
2822
+ this.#ledgerQuery = captureTransactionMethod("query");
2752
2823
  Object.freeze(transactionLedger);
2753
2824
 
2754
2825
  this.tenantId = ownerTenantId;
2755
2826
  this.tenantKey = deriveSkillReleaseTenantKey(ownerTenantId);
2756
- const requestedBase = path.resolve(rootDir);
2757
2827
  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,
2828
+ if (this.#storeBinding) {
2829
+ this.#boundaries = this.#storeBinding.boundaries;
2830
+ this.baseDir = this.#boundaries.base.path;
2831
+ this.rootDir = this.#boundaries.tenantRoot.path;
2832
+ this.#rootIdentity = this.#boundaries.tenantRoot.identity;
2833
+ this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2834
+ this.#markerIdentity = this.#storeBinding.marker.identity;
2835
+ this.#directories = deepFreeze({});
2836
+ this.#assertBoundary();
2837
+ } else {
2838
+ const base = this.#initializeDirectory(requestedBase, {
2839
+ recursive: true,
2840
+ harden: false,
2841
+ });
2842
+ this.baseDir = base.path;
2843
+ this.#assertUnboundNamespace();
2844
+ this.#assertNoLegacyBaseLayout();
2845
+ const tenants = this.#initializeDirectory(
2846
+ path.join(this.baseDir, "tenants"),
2847
+ { parent: base, harden: false },
2848
+ );
2849
+ const tenantRoot = this.#initializeDirectory(
2850
+ path.join(tenants.path, this.tenantKey),
2851
+ { parent: tenants, harden: false },
2852
+ );
2853
+ this.rootDir = tenantRoot.path;
2854
+ this.#assertUnboundNamespace();
2855
+ this.#boundaries = deepFreeze({ base, tenantRoot, tenants });
2856
+ this.#rootIdentity = tenantRoot.identity;
2857
+ this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2858
+ this.#writerControl = createSkillRegistryWriterControl({
2859
+ rootDir: this.rootDir,
2860
+ tenantId: this.tenantId,
2861
+ component: TENANT_MARKER_COMPONENT,
2862
+ fsImpl: this.#fs,
2863
+ });
2864
+ this.#writerControl.runSync(() => {
2865
+ if (this.#secure) {
2866
+ for (const [entry, parent] of [
2867
+ [base, null],
2868
+ [tenants, base],
2869
+ [tenantRoot, tenants],
2870
+ ]) {
2871
+ this.#writerControl.assertIfWriting();
2872
+ const hardened = this.#initializeDirectory(entry.path, {
2873
+ parent,
2874
+ });
2875
+ if (
2876
+ hardened.identity !== entry.identity ||
2877
+ !samePath(hardened.path, entry.path)
2878
+ )
2879
+ throw failure(
2880
+ "SKILL_RELEASE_STORE_UNSAFE",
2881
+ "release bootstrap identity changed before permission hardening",
2882
+ );
2883
+ }
2884
+ }
2885
+ this.#writerControl.assertIfWriting();
2886
+ this.#initializeTenantMarker();
2887
+ this.#directories = {};
2888
+ for (const name of [
2889
+ "artifacts",
2890
+ "active",
2891
+ "journals",
2892
+ "locks",
2893
+ "state-migrations",
2894
+ "staging",
2895
+ ]) {
2896
+ const directory = path.join(this.rootDir, name);
2897
+ this.#directories[name] = this.#initializeDirectory(directory, {
2898
+ parent: tenantRoot,
2899
+ });
2900
+ }
2901
+ this.#directories = deepFreeze(this.#directories);
2902
+ this.#assertBoundary();
2903
+ this.#assertNoLegacyTenantSchemas();
2904
+ this.#recoverAll();
2905
+ this.#cleanupDebris();
2788
2906
  });
2789
2907
  }
2790
- this.#directories = deepFreeze(this.#directories);
2791
- this.#assertBoundary();
2792
- this.#assertNoLegacyTenantSchemas();
2793
- this.#recoverAll();
2794
- this.#cleanupDebris();
2795
2908
  } catch (cause) {
2909
+ if (cause?.code === RRSI_REGISTRY_STORE_POLICY_HOLD_CODE) throw cause;
2796
2910
  if (cause instanceof SkillReleaseRegistryError) throw cause;
2797
2911
  throw failure(
2798
2912
  "SKILL_RELEASE_STORE_UNSAFE",
@@ -2804,20 +2918,28 @@ export class SkillReleaseRegistry {
2804
2918
  this,
2805
2919
  Object.freeze({
2806
2920
  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),
2921
+ storePolicyDescriptor: this.#storeBinding?.descriptor ?? null,
2922
+ matchesStorePolicyBinding: (value) =>
2923
+ value === storePolicyBinding && this.#storeBinding !== undefined,
2924
+ // Private reads never dispatch through a genuine subclass or mutable
2925
+ // function.bind property. Constructor recovery uses these paths too.
2926
+ readActive: (name) => this.#readActive(name),
2927
+ readState: (name) => this.#readState(name),
2928
+ readRelease: (value) => this.#readRelease(value),
2929
+ readInventory: () => this.#readInventory(),
2811
2930
  matchesTransactionLedger: (value) => value === transactionLedger,
2812
2931
  }),
2813
2932
  );
2933
+ REGISTRY_WRITERS.set(this, this.#writerControl);
2814
2934
  Object.freeze(this);
2815
2935
  }
2816
2936
 
2817
2937
  #initializeDirectory(
2818
2938
  requestedPath,
2819
- { parent = null, recursive = false } = {},
2939
+ { parent = null, recursive = false, harden = true } = {},
2820
2940
  ) {
2941
+ this.#assertMutationNamespace();
2942
+ const namespaceTarget = assertOutsideRrsiRegistryNamespace(requestedPath);
2821
2943
  const before = lstatOrNull(this.#fs, requestedPath);
2822
2944
  if (before && (!before.isDirectory() || before.isSymbolicLink())) {
2823
2945
  throw failure(
@@ -2826,6 +2948,16 @@ export class SkillReleaseRegistry {
2826
2948
  );
2827
2949
  }
2828
2950
  if (!before) {
2951
+ if (
2952
+ !samePath(
2953
+ assertOutsideRrsiRegistryNamespace(requestedPath),
2954
+ namespaceTarget,
2955
+ )
2956
+ )
2957
+ throw failure(
2958
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
2959
+ "release initialization ancestor changed",
2960
+ );
2829
2961
  this.#fs.mkdirSync(requestedPath, { recursive, mode: 0o700 });
2830
2962
  }
2831
2963
  let stat = this.#fs.lstatSync(requestedPath);
@@ -2837,6 +2969,12 @@ export class SkillReleaseRegistry {
2837
2969
  }
2838
2970
  const capturedIdentity = identity(stat);
2839
2971
  const canonical = realpath(this.#fs, requestedPath);
2972
+ assertOutsideRrsiRegistryNamespace(canonical);
2973
+ if (!samePath(canonical, namespaceTarget))
2974
+ throw failure(
2975
+ RRSI_REGISTRY_STORE_POLICY_HOLD_CODE,
2976
+ "release canonical initialization target changed",
2977
+ );
2840
2978
  const canonicalStat = this.#fs.lstatSync(canonical);
2841
2979
  const canonicalParent = realpath(this.#fs, path.dirname(requestedPath));
2842
2980
  const expectedCanonical = path.join(
@@ -2857,7 +2995,7 @@ export class SkillReleaseRegistry {
2857
2995
  "release registry directory escaped its canonical parent",
2858
2996
  );
2859
2997
  }
2860
- if (this.#secure) {
2998
+ if (this.#secure && harden) {
2861
2999
  ensurePrivateDirectory(canonical, {
2862
3000
  applyWindowsAcl: true,
2863
3001
  failIfUnavailable: true,
@@ -2878,6 +3016,18 @@ export class SkillReleaseRegistry {
2878
3016
  return deepFreeze({ path: canonical, identity: capturedIdentity });
2879
3017
  }
2880
3018
 
3019
+ #assertUnboundNamespace() {
3020
+ if (this.#storeBinding) return;
3021
+ for (const directory of [this.baseDir, this.rootDir])
3022
+ if (directory !== undefined)
3023
+ assertOutsideRrsiRegistryNamespace(directory);
3024
+ }
3025
+
3026
+ #assertMutationNamespace() {
3027
+ this.#storeBinding?.assertMutationAllowed();
3028
+ this.#assertUnboundNamespace();
3029
+ }
3030
+
2881
3031
  #assertNoLegacyBaseLayout() {
2882
3032
  for (const entry of this.#fs.readdirSync(this.baseDir)) {
2883
3033
  if (entry !== "tenants") {
@@ -2890,6 +3040,7 @@ export class SkillReleaseRegistry {
2890
3040
  }
2891
3041
 
2892
3042
  #initializeTenantMarker() {
3043
+ this.#assertMutationNamespace();
2893
3044
  return withEvolutionFileIdentity(
2894
3045
  this.#fs,
2895
3046
  this.#markerPath,
@@ -2899,6 +3050,7 @@ export class SkillReleaseRegistry {
2899
3050
  }
2900
3051
 
2901
3052
  #initializeTenantMarkerWithIdentity(sameStable) {
3053
+ this.#assertMutationNamespace();
2902
3054
  const existing = lstatOrNull(this.#fs, this.#markerPath);
2903
3055
  if (existing) {
2904
3056
  const verified = this.#readAndVerifyTenantMarker();
@@ -3002,6 +3154,10 @@ export class SkillReleaseRegistry {
3002
3154
  }
3003
3155
 
3004
3156
  #readAndVerifyTenantMarker() {
3157
+ if (this.#storeBinding) {
3158
+ this.#storeBinding.recheck();
3159
+ return this.#storeBinding.marker;
3160
+ }
3005
3161
  try {
3006
3162
  const stored = readBoundedSingleLinkFile(
3007
3163
  this.#fs,
@@ -3053,6 +3209,12 @@ export class SkillReleaseRegistry {
3053
3209
  }
3054
3210
 
3055
3211
  #assertBoundary() {
3212
+ if (this.#storeBinding) {
3213
+ this.#storeBinding.recheck();
3214
+ return;
3215
+ }
3216
+ this.#assertUnboundNamespace();
3217
+ this.#writerControl?.assertIfWriting();
3056
3218
  for (const entry of [
3057
3219
  ...Object.values(this.#boundaries),
3058
3220
  ...Object.values(this.#directories),
@@ -3253,6 +3415,7 @@ export class SkillReleaseRegistry {
3253
3415
  }
3254
3416
 
3255
3417
  #writeTemporary(fileName, value) {
3418
+ this.#assertMutationNamespace();
3256
3419
  if (!TEMP_PATTERN.test(fileName)) {
3257
3420
  throw failure("SKILL_RELEASE_STORE_UNSAFE", "temporary name is invalid");
3258
3421
  }
@@ -3263,6 +3426,7 @@ export class SkillReleaseRegistry {
3263
3426
  }
3264
3427
 
3265
3428
  #writeTemporaryWithIdentity(filePath, value, sameStable) {
3429
+ this.#assertMutationNamespace();
3266
3430
  const bytes = serialize(value);
3267
3431
  let descriptor = null;
3268
3432
  let writtenIdentity = null;
@@ -3312,6 +3476,7 @@ export class SkillReleaseRegistry {
3312
3476
  }
3313
3477
 
3314
3478
  #atomicWrite(area, destination, value) {
3479
+ this.#assertMutationNamespace();
3315
3480
  const expectedBytes = serialize(value);
3316
3481
  const name = `.write-${process.pid}-${this.#token()}.tmp`;
3317
3482
  const temporary = this.#writeTemporary(name, value);
@@ -3357,6 +3522,7 @@ export class SkillReleaseRegistry {
3357
3522
  }
3358
3523
 
3359
3524
  #unlink(filePath, directory) {
3525
+ this.#assertMutationNamespace();
3360
3526
  try {
3361
3527
  this.#fs.unlinkSync(filePath);
3362
3528
  fsyncDirectory(this.#fs, directory);
@@ -3366,6 +3532,7 @@ export class SkillReleaseRegistry {
3366
3532
  }
3367
3533
 
3368
3534
  #publishRelease(release) {
3535
+ this.#assertMutationNamespace();
3369
3536
  const destination = this.#releasePath(release.releaseDigest);
3370
3537
  const name = `.release-${process.pid}-${this.#token()}.tmp`;
3371
3538
  const temporary = this.#writeTemporary(name, release);
@@ -3377,7 +3544,7 @@ export class SkillReleaseRegistry {
3377
3544
  this.#fs.linkSync(temporary, destination);
3378
3545
  } catch (error) {
3379
3546
  if (error?.code !== "EEXIST") throw error;
3380
- const existing = this.readRelease(release.releaseDigest);
3547
+ const existing = this.#readRelease(release.releaseDigest);
3381
3548
  if (!serialize(existing).equals(bytes)) {
3382
3549
  throw failure("SKILL_RELEASE_CONFLICT", "release digest collision");
3383
3550
  }
@@ -3428,17 +3595,26 @@ export class SkillReleaseRegistry {
3428
3595
  }
3429
3596
 
3430
3597
  #createRelease(input) {
3598
+ this.#assertMutationNamespace();
3431
3599
  const release = buildSkillRelease(input);
3432
3600
  const created = this.#publishRelease(release);
3433
3601
  return deepFreeze({ release, created });
3434
3602
  }
3435
3603
 
3436
3604
  migrateLegacyRelease(input, migrationAuthority) {
3605
+ this.#assertMutationNamespace();
3437
3606
  if (arguments.length !== 2) {
3438
3607
  throw migrationRequired(
3439
3608
  "legacy release migration requires input and a durable audit authority",
3440
3609
  );
3441
3610
  }
3611
+ return this.#writerControl.runSync(() =>
3612
+ this.#migrateLegacyRelease(input, migrationAuthority),
3613
+ );
3614
+ }
3615
+
3616
+ #migrateLegacyRelease(input, migrationAuthority) {
3617
+ this.#assertMutationNamespace();
3442
3618
  assertExactKeys(
3443
3619
  migrationAuthority,
3444
3620
  RELEASE_MIGRATION_AUTHORITY_KEYS,
@@ -3575,11 +3751,19 @@ export class SkillReleaseRegistry {
3575
3751
  }
3576
3752
 
3577
3753
  migrateLegacyState(planInput, migrationAuthority) {
3754
+ this.#assertMutationNamespace();
3578
3755
  if (arguments.length !== 2 || this.#ledgerMigrate === null) {
3579
3756
  throw migrationRequired(
3580
3757
  "legacy state migration requires a plan, durable authority, and authenticated ledger migration port",
3581
3758
  );
3582
3759
  }
3760
+ return this.#writerControl.runSync(() =>
3761
+ this.#migrateLegacyState(planInput, migrationAuthority),
3762
+ );
3763
+ }
3764
+
3765
+ #migrateLegacyState(planInput, migrationAuthority) {
3766
+ this.#assertMutationNamespace();
3583
3767
  const plan = verifySkillReleaseStateMigrationPlan(planInput);
3584
3768
  if (plan.tenantId !== this.tenantId) {
3585
3769
  throw migrationRequired("state migration plan belongs to another tenant");
@@ -3607,8 +3791,8 @@ export class SkillReleaseRegistry {
3607
3791
  migrationAuthority.handlerArtifactDigest,
3608
3792
  "stateMigrationAuthority.handlerArtifactDigest",
3609
3793
  );
3610
- const active = this.readRelease(plan.activeReleaseDigest);
3611
- const lastKnownGood = this.readRelease(plan.lastKnownGoodReleaseDigest);
3794
+ const active = this.#readRelease(plan.activeReleaseDigest);
3795
+ const lastKnownGood = this.#readRelease(plan.lastKnownGoodReleaseDigest);
3612
3796
  if (
3613
3797
  active.skillName !== plan.skillName ||
3614
3798
  lastKnownGood.skillName !== plan.skillName ||
@@ -3681,7 +3865,7 @@ export class SkillReleaseRegistry {
3681
3865
  { stateMigrationDigest: plan.stateMigrationDigest },
3682
3866
  );
3683
3867
  }
3684
- const existing = this.readState(plan.skillName);
3868
+ const existing = this.#readState(plan.skillName);
3685
3869
  if (existing.revision > 0) {
3686
3870
  if (
3687
3871
  existing.transactionId !== plan.stateMigrationDigest ||
@@ -3783,7 +3967,15 @@ export class SkillReleaseRegistry {
3783
3967
  }
3784
3968
 
3785
3969
  readRelease(releaseDigest) {
3970
+ return this.#readRelease(releaseDigest);
3971
+ }
3972
+
3973
+ #readRelease(releaseDigest) {
3786
3974
  const expected = digest(releaseDigest, "releaseDigest");
3975
+ if (this.#runtimeMode === "uninitialized") {
3976
+ this.#assertBoundary();
3977
+ throw failure("SKILL_RELEASE_NOT_FOUND", "release was not found");
3978
+ }
3787
3979
  let value;
3788
3980
  try {
3789
3981
  value = this.#readJson(
@@ -3819,6 +4011,10 @@ export class SkillReleaseRegistry {
3819
4011
 
3820
4012
  #readStateRaw(name) {
3821
4013
  const normalizedName = skillName(name);
4014
+ if (this.#runtimeMode === "uninitialized") {
4015
+ this.#assertBoundary();
4016
+ return initialState(normalizedName, this.tenantId);
4017
+ }
3822
4018
  try {
3823
4019
  const state = verifySkillReleaseState(
3824
4020
  this.#readJson(
@@ -3888,8 +4084,8 @@ export class SkillReleaseRegistry {
3888
4084
  "active pointer is not finalized by the trusted transaction ledger",
3889
4085
  );
3890
4086
  }
3891
- const active = this.readRelease(state.activeReleaseDigest);
3892
- const lkg = this.readRelease(state.lastKnownGoodReleaseDigest);
4087
+ const active = this.#readRelease(state.activeReleaseDigest);
4088
+ const lkg = this.#readRelease(state.lastKnownGoodReleaseDigest);
3893
4089
  if (
3894
4090
  active.skillName !== state.skillName ||
3895
4091
  lkg.skillName !== state.skillName ||
@@ -3907,17 +4103,25 @@ export class SkillReleaseRegistry {
3907
4103
  }
3908
4104
 
3909
4105
  readState(name) {
4106
+ return this.#readState(name);
4107
+ }
4108
+
4109
+ #readState(name) {
3910
4110
  const state = this.#readStateRaw(name);
3911
4111
  return state.revision === 0 ? state : this.#verifyCommittedState(state);
3912
4112
  }
3913
4113
 
3914
4114
  readActive(name) {
3915
- const state = this.readState(name);
4115
+ return this.#readActive(name);
4116
+ }
4117
+
4118
+ #readActive(name) {
4119
+ const state = this.#readState(name);
3916
4120
  return state.revision === 0
3917
4121
  ? null
3918
4122
  : deepFreeze({
3919
4123
  state,
3920
- release: this.readRelease(state.activeReleaseDigest),
4124
+ release: this.#readRelease(state.activeReleaseDigest),
3921
4125
  });
3922
4126
  }
3923
4127
 
@@ -3981,7 +4185,13 @@ export class SkillReleaseRegistry {
3981
4185
  }
3982
4186
 
3983
4187
  readInventory() {
4188
+ return this.#readInventory();
4189
+ }
4190
+
4191
+ #readInventory() {
3984
4192
  this.#assertBoundary();
4193
+ if (this.#runtimeMode === "uninitialized")
4194
+ return deepFreeze({ active: [], releases: [] });
3985
4195
  const releasePattern = /^[a-f0-9]{64}\.json$/u;
3986
4196
  const statePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.json$/u;
3987
4197
  const beforeReleases = this.#readInventoryNames(
@@ -3999,11 +4209,11 @@ export class SkillReleaseRegistry {
3999
4209
  );
4000
4210
  }
4001
4211
  const releases = beforeReleases.map((name) =>
4002
- this.readRelease(`sha256:${name.slice(0, -".json".length)}`),
4212
+ this.#readRelease(`sha256:${name.slice(0, -".json".length)}`),
4003
4213
  );
4004
4214
  const active = beforeStates.map((name) => {
4005
4215
  const skill = name.slice(0, -".json".length);
4006
- const value = this.readActive(skill);
4216
+ const value = this.#readActive(skill);
4007
4217
  if (value === null) {
4008
4218
  throw failure(
4009
4219
  "SKILL_RELEASE_STATE_CORRUPT",
@@ -4041,7 +4251,7 @@ export class SkillReleaseRegistry {
4041
4251
  const afterReleases = this.#readInventoryNames("artifacts", releasePattern);
4042
4252
  const afterStates = this.#readInventoryNames("active", statePattern);
4043
4253
  const afterStateDigests = afterStates.map(
4044
- (name) => this.readState(name.slice(0, -".json".length)).stateDigest,
4254
+ (name) => this.#readState(name.slice(0, -".json".length)).stateDigest,
4045
4255
  );
4046
4256
  if (
4047
4257
  canonicalJson(beforeReleases) !== canonicalJson(afterReleases) ||
@@ -4060,7 +4270,7 @@ export class SkillReleaseRegistry {
4060
4270
  }
4061
4271
 
4062
4272
  pinActive(name) {
4063
- const active = this.readActive(name);
4273
+ const active = this.#readActive(name);
4064
4274
  if (!active)
4065
4275
  throw failure("SKILL_RELEASE_NOT_ACTIVE", "Skill has no active release");
4066
4276
  const pin = Object.freeze(Object.create(null));
@@ -4094,7 +4304,7 @@ export class SkillReleaseRegistry {
4094
4304
  "pinned activation is not committed",
4095
4305
  );
4096
4306
  }
4097
- return this.readRelease(binding.releaseDigest);
4307
+ return this.#readRelease(binding.releaseDigest);
4098
4308
  }
4099
4309
 
4100
4310
  #owner(kind, token, { skill = null, transactionId = null, fence = 0 } = {}) {
@@ -4210,6 +4420,7 @@ export class SkillReleaseRegistry {
4210
4420
  }
4211
4421
 
4212
4422
  #createLock(lockPath, owner) {
4423
+ this.#assertMutationNamespace();
4213
4424
  this.#fs.mkdirSync(lockPath, { mode: 0o700 });
4214
4425
  let descriptor = null;
4215
4426
  try {
@@ -4239,6 +4450,7 @@ export class SkillReleaseRegistry {
4239
4450
  }
4240
4451
 
4241
4452
  #removeLock(lockPath, expectedToken = null) {
4453
+ this.#assertMutationNamespace();
4242
4454
  let owner;
4243
4455
  try {
4244
4456
  owner = this.#readOwner(lockPath);
@@ -4300,6 +4512,7 @@ export class SkillReleaseRegistry {
4300
4512
  }
4301
4513
 
4302
4514
  #renewLease(lease) {
4515
+ this.#assertMutationNamespace();
4303
4516
  const current = this.#readOwner(lease.lockPath);
4304
4517
  if (
4305
4518
  current.token !== lease.token ||
@@ -4338,6 +4551,7 @@ export class SkillReleaseRegistry {
4338
4551
  }
4339
4552
 
4340
4553
  #acquireLease(name, transactionId, expectedRevision, expectedParentDigest) {
4554
+ this.#assertMutationNamespace();
4341
4555
  const journalPath = this.#journalPath(name);
4342
4556
  if (this.#exists(journalPath)) {
4343
4557
  this.#withRecoveryLock(() => this.#recoverSkill(name));
@@ -4350,11 +4564,11 @@ export class SkillReleaseRegistry {
4350
4564
  }
4351
4565
  const lockPath = this.#leasePath(name);
4352
4566
  for (let attempt = 0; attempt < 2; attempt += 1) {
4353
- const state = this.readState(name);
4567
+ const state = this.#readState(name);
4354
4568
  const active =
4355
4569
  state.activeReleaseDigest === null
4356
4570
  ? null
4357
- : this.readRelease(state.activeReleaseDigest);
4571
+ : this.#readRelease(state.activeReleaseDigest);
4358
4572
  const actualParent = active?.contentDigest ?? EMPTY_SKILL_ACTIVE_DIGEST;
4359
4573
  if (
4360
4574
  state.revision !== expectedRevision ||
@@ -4805,6 +5019,7 @@ export class SkillReleaseRegistry {
4805
5019
  }
4806
5020
 
4807
5021
  #prepare(intent, targetRelease) {
5022
+ this.#assertMutationNamespace();
4808
5023
  let projection;
4809
5024
  try {
4810
5025
  projection = this.#ledgerPrepare(intent, targetRelease);
@@ -4836,6 +5051,7 @@ export class SkillReleaseRegistry {
4836
5051
  }
4837
5052
 
4838
5053
  #finalize(journal, prepareReceipt) {
5054
+ this.#assertMutationNamespace();
4839
5055
  const request = deepFreeze({
4840
5056
  authorityReceiptDigest: journal.intent.authorityReceiptDigest,
4841
5057
  expectedPrepareReceiptDigest: prepareReceipt.receiptDigest,
@@ -4882,6 +5098,7 @@ export class SkillReleaseRegistry {
4882
5098
  }
4883
5099
 
4884
5100
  #writePointer(state, stagedFile) {
5101
+ this.#assertMutationNamespace();
4885
5102
  const stagedPath = this.#path("staging", stagedFile);
4886
5103
  if (!this.#exists(stagedPath)) this.#writeTemporary(stagedFile, state);
4887
5104
  const expectedBytes = serialize(state);
@@ -4994,7 +5211,7 @@ export class SkillReleaseRegistry {
4994
5211
  );
4995
5212
  }
4996
5213
 
4997
- const verifiedRelease = this.readRelease(release.releaseDigest);
5214
+ const verifiedRelease = this.#readRelease(release.releaseDigest);
4998
5215
  if (
4999
5216
  verifiedRelease.tenantId !== this.tenantId ||
5000
5217
  verifiedRelease.skillName !== state.skillName ||
@@ -5022,7 +5239,7 @@ export class SkillReleaseRegistry {
5022
5239
  #assertJournalFinalizationArtifacts(journal) {
5023
5240
  let release;
5024
5241
  try {
5025
- release = this.readRelease(journal.nextState.activeReleaseDigest);
5242
+ release = this.#readRelease(journal.nextState.activeReleaseDigest);
5026
5243
  } catch (cause) {
5027
5244
  throw failure(
5028
5245
  "SKILL_RELEASE_FINALIZATION_INPUT_INVALID",
@@ -5091,6 +5308,7 @@ export class SkillReleaseRegistry {
5091
5308
  }
5092
5309
 
5093
5310
  #recoverJournal(journal) {
5311
+ this.#assertMutationNamespace();
5094
5312
  const expected = {
5095
5313
  authorityReceiptDigest: journal.intent.authorityReceiptDigest,
5096
5314
  intentDigest: journal.intent.intentDigest,
@@ -5132,6 +5350,7 @@ export class SkillReleaseRegistry {
5132
5350
  }
5133
5351
 
5134
5352
  #recoverSkill(name, { force = false } = {}) {
5353
+ this.#assertMutationNamespace();
5135
5354
  const journalPath = this.#journalPath(name);
5136
5355
  const lockPath = this.#leasePath(name);
5137
5356
  if (!this.#exists(journalPath)) {
@@ -5174,6 +5393,7 @@ export class SkillReleaseRegistry {
5174
5393
  }
5175
5394
 
5176
5395
  #recoverStateMigration(journal, { force = false } = {}) {
5396
+ this.#assertMutationNamespace();
5177
5397
  const lockPath = this.#leasePath(journal.skillName);
5178
5398
  if (this.#exists(lockPath)) {
5179
5399
  const owner = this.#readOwner(lockPath);
@@ -5222,13 +5442,14 @@ export class SkillReleaseRegistry {
5222
5442
  journal.state,
5223
5443
  );
5224
5444
  }
5225
- const release = this.readRelease(journal.state.activeReleaseDigest);
5445
+ const release = this.#readRelease(journal.state.activeReleaseDigest);
5226
5446
  this.#assertFinalizationArtifacts(journal.state, release);
5227
5447
  this.#cleanupStateMigration(journal);
5228
5448
  return "committed";
5229
5449
  }
5230
5450
 
5231
5451
  #recoverAll() {
5452
+ this.#assertMutationNamespace();
5232
5453
  this.#withRecoveryLock(() => {
5233
5454
  for (const name of this.#fs.readdirSync(
5234
5455
  this.#directories["state-migrations"].path,
@@ -5275,6 +5496,7 @@ export class SkillReleaseRegistry {
5275
5496
  }
5276
5497
 
5277
5498
  #cleanupDebris() {
5499
+ this.#assertMutationNamespace();
5278
5500
  const referenced = new Set();
5279
5501
  for (const name of this.#fs.readdirSync(this.#directories.journals.path)) {
5280
5502
  if (name.endsWith(".json")) {
@@ -5463,6 +5685,14 @@ export class SkillReleaseRegistry {
5463
5685
  }
5464
5686
 
5465
5687
  async applyTransition(capability) {
5688
+ this.#assertMutationNamespace();
5689
+ return this.#writerControl.runAsync(() =>
5690
+ this.#applyTransition(capability),
5691
+ );
5692
+ }
5693
+
5694
+ async #applyTransition(capability) {
5695
+ this.#assertMutationNamespace();
5466
5696
  const payload = this.#validateTransitionPayload(
5467
5697
  consumeRegistryTransitionCapability(capability, this),
5468
5698
  );
@@ -5477,7 +5707,7 @@ export class SkillReleaseRegistry {
5477
5707
  target = created.release;
5478
5708
  releaseCreated = created.created;
5479
5709
  } else {
5480
- target = this.readRelease(payload.targetReleaseDigest);
5710
+ target = this.#readRelease(payload.targetReleaseDigest);
5481
5711
  }
5482
5712
  if (
5483
5713
  target.skillName !== payload.skillName ||