chainlesschain 0.166.92 → 0.166.94

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 (182) hide show
  1. package/README.md +16 -7
  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-C74YzqwJ.js → AIOps-CzxfrB7_.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-TFef1hOE.js → ActionButton-6a4WFIb0.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CYsWpkkU.js → Analytics-O3Hv5QVR.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-CFf9kjwu.js → AppLayout-D96Jtyrz.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-TQqa94YO.js → Artifacts-BxbCrGsv.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-B79ayqfS.js → Audit-Dvhj3ev4.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-pjkHfLP9.js → BackgroundAgents-zgrU13eK.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-CE6A-t_r.js → Backup-B3ePsQ8z.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-CwcgWMBY.js → BaseInput-CemgxVZi.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-BIkDNesY.js → Chat-BNxuigZo.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DgaokYts.js → ChatBubbleRenderer-DE73IMLf.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-MbypIy5V.js → Checkbox-BvHaZkOM.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-DiFHWDnt.js → Codegen--DNXNLnq.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-BNMlYMso.js → Col-C8xvHu-3.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-B3HVyHOX.js → Community-v19Cxqtl.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-C7hlAubb.js → Compact-BdQ659sW.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-PaXZu6sE.js → Compliance-CE0-97Ph.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BGiojbm-.js → Cowork-YCuhzIZE.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-Bmr-1QAx.js → Cron-C5xa6iEB.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BwUvWCVd.js → Crosschain-CmsyQp8f.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-k_4QZocW.js → DID-FY-oN652.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-_ieRo2C5.js → Dashboard-CFJD_yB7.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-DYHh6T27.js → Dropdown-QM5qyalT.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BNlQcWQX.js → EmailListRenderer-BbA-SPX0.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DIkZ6U2D.js → EvolutionSettings-BGH3oR71.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dq7qSr0P.js → FamilyGuardDashboard-C4s2LeR4.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-C64e3Cbx.js → Federation-Cfb8190f.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-D-GE2vUa.js → FormItemContext-DFVYcD2A.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-DO3B2gis.js → GenericCardRenderer-CU-yqT1M.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-0ETirIQH.js → Git-tYiQuWYO.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-C9fnRygX.js → Governance-DRH8tKKy.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CLJ9RTsK.js → Inference-v2GbRYb4.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-D3C_GxrN.js → KnowledgeGraph-B5Ff0wSA.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-C5ctGbkN.js → Logs-mcHQsQZC.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-Ce-eWK3j.js → MarkdownRenderer-rk-aXvLV.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-GF_t6hJ_.js → Marketplace-LUstH49t.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BGsGzgQs.js → McpTools-kFFP54H9.js} +2 -2
  42. package/src/assets/web-panel/assets/{Memory-CcrY2A0j.js → Memory--KBUL4b_.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Bi4T0RlS.js → MobileBridge-CQL_xVyD.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-DoIR8HA0.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-DL77Vf-k.js → Mtc-BrUPLX-C.js} +6 -6
  46. package/src/assets/web-panel/assets/{MtcAudit-CDy_Uswb.js → MtcAudit-46jjW0Ne.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-DL0BAO_c.js → Multisig-3XX8crha.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-B-woh5IR.js → NLProgramming-C53SRk52.js} +1 -1
  49. package/src/assets/web-panel/assets/Notes-RxpNEOb6.js +7 -0
  50. package/src/assets/web-panel/assets/{NotificationSettings-BqPPMuAP.js → NotificationSettings-C2R6A0rD.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-Bhhp4H-K.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-B1gX8jlr.js → Organization-B48YmG99.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-CeMxuUZy.js → Overflow-BYPoJ7Qo.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-B5aIRWwJ.js → P2P-CI9F_5Xz.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-6rYgejd4.js → PdhVaultBrowser-C50vLFTe.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-CqCp2SIl.js → Permissions-CKMhcV4D.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BsA7DJWW.js → PersonalDataHub-CFwVht-l.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-CiW6HeZh.js → Pipeline-BQliRCrn.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-DckUOLYq.js → Privacy-z-9F-MIF.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-CZppOOYR.js → ProjectInit-DAuaSe48.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-B9QPzhDU.js → ProjectSettings-BpCCZLAx.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-BErjjGha.js → Projects-CguDJz4k.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-DehU6Qiz.js → Providers-DOXv8vOy.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-E1SUvv1m.js → QrScannerModal-BiMsPToH.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-COWFxyH3.js → QuickAsk-Dxjfq39w.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-D26pWKxX.js → Recommend-Y5kQ_a2f.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-DCOIaId3.js → RemoteSession-BSIDk0es.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-DT_AHGAR.js → Reputation-BLjwaybi.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-B50S-1nl.js → Row-7geSc2GW.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-BaBnHg3Q.js → RssFeed-BophPGWk.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-BVdnLuuS.js → Search-iBXsRvIQ.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-BnacH74J.js → Security-sM5aX0dn.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-CxM08Zch.js → Services-8n708_pG.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-DE7CIc1N.js → Skeleton-D2rl_ikr.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-CGI0SJmf.js → Skills-DJpknGnz.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-DpEzPcqc.js → Sla-mA8eEXRj.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-CTmnmMHn.js → SpeechSettings-BVrmiTgd.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-Dxgrd9hd.js → SyncSettings-Cd-KRX72.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-CW4slS0A.js → Tasks-DYAvmen_.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DxvGWDgB.js → Templates-DPdlYX7S.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-_Q0o2tNK.js → Tenant-wfSNgGDT.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BTZn8pow.js → Terminal-BqJDIQEC.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-CauL0KFe.js → TimelineRenderer-eeuMKufC.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-CDoM2qeT.js → Tokens-DW9xE5CY.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-B-QYGEU7.js → Trigger-BBniBnCp.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-BD6XJHT-.js → Trust-C7fZAxYI.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-x4TFwCy0.js → UkeySign-X_cT1LN_.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-t3imBK_0.js → VideoEditing-C95qSEAg.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BCfkWwNC.js → Wallet-_Y76V1eI.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-WH314Mdm.js → WebAuthn-CUpi7QWI.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-jUlcjrUg.js → WorkflowEditor-CdTwu4JZ.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-Dg3VASTL.js → chat-D2hW7s3x.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BNvmBRKE.js → colors-Cxes7tn4.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-BGOfoqf4.js → compact-item-BuLnefA8.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BNQeqKAs.js → createContext-DSJr7jrZ.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BHLx7Ctv.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-Bg3AjCrq.js → hasIn-CPtCYTi-.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-2D04Zltx.js → index--J0mLXrw.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-COol3xfA.js → index--gm5GIKK.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DcCnO0RU.js → index-5Vtfy09g.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-fOwii3LP.js → index-B5GXCqB0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-OUFoxUgH.js → index-BC-FDx0Y.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-Bkz1tgFR.js → index-BDaNLJss.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DLwEXRrb.js → index-BOKMxs4C.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BBCMulQ-.js → index-BOXgWdJY.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B_JmInC0.js → index-BSHkOFqM.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-pVdQieac.js → index-B_mChW9O.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BmTacaQV.js → index-Bq-CMI2h.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Wo0f2iqb.js → index-BudaM8zA.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B--0QM0S.js → index-C2qdbxEw.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BaPvEvB4.js → index-C6jDeixf.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Dkp-okWa.js → index-C88mhge1.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BSNhW95G.js → index-C8xMmdFz.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-7QJUWemf.js → index-CCI2rS5G.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-xzaUx19r.js → index-CFTO4avR.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Cbp-wp-U.js → index-CVgzXcvk.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Co_LnCWD.js → index-C_RLdbKl.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CY8cRKHR.js → index-CighFQgt.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B0mgngoB.js → index-CmV_i-tY.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-ZD5Kd8tx.js → index-Ct9hZUrk.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-uH2LnAs_.js → index-D4YILZTK.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CCFZN66A.js → index-DDSmCL8t.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DYn5DnDk.js → index-DFSJeXBu.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Cx2EXRfr.js → index-DGIumCxN.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-D6UqK83L.js → index-DIkV-pwg.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DO0VlNtc.js → index-DTtVX2yD.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-D_O2ZjPk.js → index-Dz6h62uC.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-D-mSvCQK.js → index-PyLgXmQZ.js} +1 -1
  129. package/src/assets/web-panel/assets/index-V4IYxvvE.js +1 -0
  130. package/src/assets/web-panel/assets/{index--I3UF5t1.js → index-_AYMw6sF.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-hG7jXGEW.js → index-ePTIQg1n.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-60AnjUTX.js → index-f1fHG0MC.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DS04wRll.js → index-lOl7QbP4.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-DF_FKSVH.js → index-vsUYvuDU.js} +1 -1
  135. package/src/assets/web-panel/assets/index-y4vqXg0S.js +1 -0
  136. package/src/assets/web-panel/assets/{index-D072oLjp.js → index-ystQEkV4.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-B8PN9AxJ.js → initDefaultProps-CAxtYUKo.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BHivfw5Q.js → motion-CgPmr4vy.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-B0QU5nDd.js → move-XGK3_B35.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-DRwRM3PE.js → mtc-parser-C6Vfqz8e.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-SHt2rV2p.js → omit-DquSN-3H.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-CcmDlEb2.js → pickAttrs-BH-ir5eD.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-DYatmXDS.js → placementArrow-Drf-QXk8.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-B7qrsXq5.js → responsiveObserve-BUBMbJsH.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-BRGhlOWd.js → slide-BCqinMKC.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-CT-7NXsQ.js → statusUtils-CAp3-0Ss.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-rZdw_Yyp.js → styleChecker-DIuQh0dB.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-D8YNIP4P.js → useFlexGapSupport-CWXPAfZR.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-B8pt0Gu-.js → useFs-905ulWWY.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-VMmYM1tt.js → usePersonalDataHub-DajnovG6.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-UNDuoPoq.js → vnode-BE_Yg3pz.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-dN-u667S.js → zoom-BLndEna7.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +26 -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 +209 -129
  158. package/src/lib/evolution/rrsi-history-ledger-adapter.js +25 -0
  159. package/src/lib/evolution/rrsi-installation-route-contracts.js +275 -0
  160. package/src/lib/evolution/rrsi-installation-route-reader.js +282 -0
  161. package/src/lib/evolution/rrsi-observed-text-index.js +978 -0
  162. package/src/lib/evolution/rrsi-registry-runtime-policy.js +648 -0
  163. package/src/lib/evolution/rrsi-registry-store-policy.js +95 -15
  164. package/src/lib/evolution/rrsi-tenant-index-anchor-contracts.js +223 -0
  165. package/src/lib/evolution/rrsi-tenant-index-anchor-history.js +157 -0
  166. package/src/lib/evolution/skill-release-registry.js +20 -5
  167. package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +291 -30
  168. package/src/lib/process-execution-broker/windows-native-evaluator.js +247 -28
  169. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  170. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  171. package/src/lib/process-execution-broker/windows-sandbox.cs +140 -6
  172. package/src/lib/remote-read-loop-guard.js +227 -24
  173. package/src/lib/settings-loader.cjs +10 -1
  174. package/src/lib/task-progress-tracker.js +6 -1
  175. package/src/lib/with-file-lock.js +86 -16
  176. package/src/runtime/agent-core.js +71 -23
  177. package/src/assets/web-panel/assets/MobileProjects-DvjEGyvf.js +0 -1
  178. package/src/assets/web-panel/assets/Notes-CEFVCxk7.js +0 -7
  179. package/src/assets/web-panel/assets/OrderTableRenderer-GUKQ1xwp.js +0 -1
  180. package/src/assets/web-panel/assets/devWarning-B7_ypN1G.js +0 -1
  181. package/src/assets/web-panel/assets/index-B-jSKJK6.js +0 -1
  182. package/src/assets/web-panel/assets/index-P4FXZJqI.js +0 -1
@@ -33,6 +33,7 @@ import {
33
33
  import { deriveSkillCandidateTenantKey } from "./skill-candidate-registry.js";
34
34
  import { deriveSkillReleaseTenantKey } from "./skill-release-registry.js";
35
35
  import { captureSkillReleaseOperationReader } from "./evolution-ledger-ports.js";
36
+ import { captureRrsiRegistryRuntimePolicy } from "./rrsi-registry-runtime-policy.js";
36
37
  import {
37
38
  snapshotRrsiData,
38
39
  rrsiExact,
@@ -129,7 +130,13 @@ function assertPrivateParent(expected) {
129
130
  assertDirectory(expected);
130
131
  const permission = inspectPrivatePath(expected.path);
131
132
  if (permission?.ok !== true || permission.exists !== true)
132
- hold("provisioning parent must have verified owner-only permissions");
133
+ hold(
134
+ "provisioning parent must have verified owner-only permissions",
135
+ new Error(
136
+ permission?.error ||
137
+ "owner-only permission inspection was not successful",
138
+ ),
139
+ );
133
140
  assertDirectory(expected);
134
141
  }
135
142
  function syncDirectory(value) {
@@ -950,20 +957,32 @@ export function createRrsiRegistryStorePolicy(input) {
950
957
  const policy = Object.freeze({
951
958
  descriptor,
952
959
  bindComponent(input) {
953
- const request = snapshotRrsiData(input);
954
- rrsiExact(
955
- request,
956
- ["operationId", "component"],
957
- "Registry component binding",
958
- );
960
+ if (
961
+ !input ||
962
+ isProxy(input) ||
963
+ Object.getPrototypeOf(input) !== Object.prototype
964
+ )
965
+ hold("Registry component binding requires plain own fields");
966
+ const names = ["operationId", "component"];
967
+ if (Object.hasOwn(input ?? {}, "runtimePolicy"))
968
+ names.push("runtimePolicy");
969
+ const request = ownOptions(input, names);
959
970
  rrsiId(request.operationId, "provision operation ID");
960
971
  if (!["candidate", "release"].includes(request.component))
961
972
  rrsiFail("Registry binding component is invalid");
962
973
  // Do not take a policy operation lock or repair any Registry path. The
963
974
  // retained head and both physical markers bookend this read-only open.
964
- let original;
975
+ let original,
976
+ runtime = null;
977
+ if (request.runtimePolicy !== undefined) {
978
+ runtime = captureRrsiRegistryRuntimePolicy(request.runtimePolicy);
979
+ if (!runtime.matchesPolicy(policy))
980
+ hold("runtime attachment requires the original store policy");
981
+ }
965
982
  try {
966
- original = status(load(), request.operationId);
983
+ original = status(load(), request.operationId, {
984
+ boundaryOnly: runtime !== null,
985
+ });
967
986
  } catch (cause) {
968
987
  if (["ENOENT", "ENOTDIR"].includes(cause?.code))
969
988
  hold("an authenticated Registry binding boundary is missing", cause);
@@ -976,6 +995,7 @@ export function createRrsiRegistryStorePolicy(input) {
976
995
  const store = prepared[component];
977
996
  const peer =
978
997
  prepared[component === "candidate" ? "release" : "candidate"];
998
+ const runtimeOriginal = runtime?.read(request.operationId) ?? null;
979
999
  const componentDescriptor = freezeRrsiData({
980
1000
  schema: "chainlesschain.rrsi-registry-component-binding/v1",
981
1001
  operationId: request.operationId,
@@ -986,7 +1006,10 @@ export function createRrsiRegistryStorePolicy(input) {
986
1006
  journalIdentity: prepared.journalIdentity,
987
1007
  committedRecordDigest: original.records.at(-1).recordDigest,
988
1008
  writerFloor: RRSI_REGISTRY_STORE_WRITER_FLOOR,
989
- registryRuntimeMode: "uninitialized-read-only",
1009
+ registryRuntimeMode: runtime
1010
+ ? "authenticated-empty-read-only"
1011
+ : "uninitialized-read-only",
1012
+ runtimeRecordDigest: runtimeOriginal?.committedRecordDigest ?? null,
990
1013
  persistentStoreIdentityAuthenticated: true,
991
1014
  originCutoverAuthenticated: false,
992
1015
  originClassificationAvailable: false,
@@ -994,7 +1017,8 @@ export function createRrsiRegistryStorePolicy(input) {
994
1017
  });
995
1018
  function recheckUnchecked() {
996
1019
  // Invalid existing physical state needs no journal recovery or locks.
997
- assertLayout(prepared, [true, true]);
1020
+ if (runtime) runtime.read(request.operationId);
1021
+ else assertLayout(prepared, [true, true]);
998
1022
  if (!equal(markerProof(prepared, true), original.markers))
999
1023
  hold("Registry marker identity changed after capture");
1000
1024
  const result = status(load(), request.operationId, {
@@ -1007,9 +1031,17 @@ export function createRrsiRegistryStorePolicy(input) {
1007
1031
  !equal(result.records, original.records)
1008
1032
  )
1009
1033
  hold("Registry component binding changed after capture");
1010
- // No origin or runtime attachment exists yet. Unknown content and
1011
- // even empty runtime containers remain HOLD, with no adoption/cleanup.
1012
- assertLayout(prepared, [true, true]);
1034
+ // An explicit runtime attachment authenticates only its empty layout.
1035
+ // Unknown content remains HOLD, with no adoption or cleanup.
1036
+ if (runtime) {
1037
+ const current = runtime.read(request.operationId);
1038
+ if (
1039
+ !equal(current.directories, runtimeOriginal.directories) ||
1040
+ current.committedRecordDigest !==
1041
+ runtimeOriginal.committedRecordDigest
1042
+ )
1043
+ hold("runtime attachment changed after component capture");
1044
+ } else assertLayout(prepared, [true, true]);
1013
1045
  if (!equal(markerProof(prepared, true), original.markers))
1014
1046
  hold("Registry markers changed during uninitialized inventory read");
1015
1047
  if (!equal(result.currentHead, headData(methods.verify())))
@@ -1047,10 +1079,15 @@ export function createRrsiRegistryStorePolicy(input) {
1047
1079
  identity: original.markers[component].identity,
1048
1080
  marker: markerFor(prepared, component),
1049
1081
  }),
1082
+ runtimeDirectories:
1083
+ component === "release"
1084
+ ? (runtimeOriginal?.directories ?? null)
1085
+ : null,
1050
1086
  recheck,
1051
1087
  recheckForOpen() {
1052
1088
  try {
1053
1089
  assertPrivateParent(prepared.parent);
1090
+ runtime?.verifyPrivateDirectories(request.operationId);
1054
1091
  return recheck();
1055
1092
  } catch (cause) {
1056
1093
  if (["ENOENT", "ENOTDIR"].includes(cause?.code))
@@ -1084,7 +1121,7 @@ export function createRrsiRegistryStorePolicy(input) {
1084
1121
  },
1085
1122
  assertMutationAllowed() {
1086
1123
  hold(
1087
- "Registry origin admission and runtime initialization are not implemented",
1124
+ "Registry origin admission and business mutation are not implemented",
1088
1125
  );
1089
1126
  },
1090
1127
  }),
@@ -1145,6 +1182,49 @@ export function createRrsiRegistryStorePolicy(input) {
1145
1182
  matchesArtifactPorts: (value) => value === options.artifactPorts,
1146
1183
  matchesArtifactResolver: (value) => value === resolver,
1147
1184
  read: policy.read,
1185
+ captureCommittedBoundary(operationId) {
1186
+ rrsiId(operationId, "provision operation ID");
1187
+ try {
1188
+ const state = load();
1189
+ const result = status(state, operationId, {
1190
+ boundaryOnly: true,
1191
+ verifyPermissions: false,
1192
+ });
1193
+ if (!result.freshPhysicalPairProvisioningCommitted)
1194
+ hold("runtime requires committed store provisioning");
1195
+ return Object.freeze({
1196
+ snapshot: result,
1197
+ recheck() {
1198
+ // Reuse only this authenticated immutable history at its exact
1199
+ // captured head. No caller-supplied state or newer head is used.
1200
+ try {
1201
+ return status(state, operationId, {
1202
+ boundaryOnly: true,
1203
+ verifyPermissions: false,
1204
+ });
1205
+ } catch (cause) {
1206
+ if (["ENOENT", "ENOTDIR"].includes(cause?.code))
1207
+ hold("an authenticated store boundary is missing", cause);
1208
+ throw cause;
1209
+ }
1210
+ },
1211
+ });
1212
+ } catch (cause) {
1213
+ if (["ENOENT", "ENOTDIR"].includes(cause?.code))
1214
+ hold("an authenticated store boundary is missing", cause);
1215
+ throw cause;
1216
+ }
1217
+ },
1218
+ maintain(operation) {
1219
+ if (typeof operation !== "function" || isProxy(operation))
1220
+ hold("runtime maintenance requires an original synchronous callback");
1221
+ return locked((assertOwnership) => {
1222
+ const result = operation(assertOwnership);
1223
+ if (result && typeof result.then === "function")
1224
+ hold("runtime maintenance cannot return a Promise");
1225
+ return result;
1226
+ });
1227
+ },
1148
1228
  }),
1149
1229
  );
1150
1230
  return policy;
@@ -0,0 +1,223 @@
1
+ /** Signed anchor declarations. A valid signature is never tenant authority. */
2
+ import { createHash, createPublicKey, verify } from "node:crypto";
3
+ import {
4
+ rrsiCanonical,
5
+ rrsiHash,
6
+ rrsiExact,
7
+ rrsiId,
8
+ rrsiDigest,
9
+ rrsiInteger,
10
+ rrsiEnvelope,
11
+ verifyRrsiEnvelope,
12
+ snapshotRrsiData,
13
+ rrsiFail,
14
+ } from "./rrsi-data.js";
15
+
16
+ export const RRSI_TENANT_INDEX_ANCHOR_SCHEMA =
17
+ "chainlesschain.rrsi-tenant-index-anchor/v1";
18
+ export const RRSI_TENANT_INDEX_ANCHOR_SIGNATURE_SCHEMA =
19
+ "chainlesschain.rrsi-tenant-index-anchor-signature-check/v1";
20
+ export const RRSI_TENANT_INDEX_ANCHOR_HOLD_CODE =
21
+ "CC_RRSI_TENANT_INDEX_ANCHOR_HOLD";
22
+ const SIGNATURE_DOMAIN = "chainlesschain.rrsi-tenant-index-anchor-signature/v1";
23
+ const INPUT_KEYS = [
24
+ "deploymentId",
25
+ "tenantId",
26
+ "routingScope",
27
+ "indexId",
28
+ "ledgerIdentity",
29
+ "artifactScope",
30
+ "storageGraphDigest",
31
+ "rootPublicKeyDigest",
32
+ "revision",
33
+ "previousAnchorDigest",
34
+ "checkpoint",
35
+ "restrictionHistory",
36
+ ];
37
+ const sha = (bytes) =>
38
+ `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
39
+ const same = (a, b) => rrsiCanonical(a) === rrsiCanonical(b);
40
+ function hold(message) {
41
+ rrsiFail(message, RRSI_TENANT_INDEX_ANCHOR_HOLD_CODE);
42
+ }
43
+ function ledgerId(value, label) {
44
+ if (
45
+ typeof value !== "string" ||
46
+ !/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,159}$/u.test(value)
47
+ )
48
+ hold(`${label} is not a Ledger identifier`);
49
+ }
50
+ function journalIdentity(value) {
51
+ rrsiExact(
52
+ value,
53
+ ["ledgerId", "identityDigest", "epoch"],
54
+ "anchor journal identity",
55
+ );
56
+ ledgerId(value.ledgerId, "ledgerId");
57
+ ledgerId(value.epoch, "epoch");
58
+ rrsiDigest(value.identityDigest, "identity digest");
59
+ }
60
+
61
+ export function buildRrsiTenantIndexAnchor(input) {
62
+ const value = snapshotRrsiData(input);
63
+ rrsiExact(value, INPUT_KEYS, "tenant index anchor input");
64
+ rrsiId(value.deploymentId, "deployment ID");
65
+ rrsiId(value.tenantId, "tenant ID");
66
+ if (!["installation", "shared-tenant-authority"].includes(value.routingScope))
67
+ hold("anchor routing scope must be explicit");
68
+ const expectedIndex = `rrsi-text.${rrsiHash("chainlesschain.rrsi-observed-text-index/v1", value.tenantId).slice(7)}`;
69
+ if (value.indexId !== expectedIndex)
70
+ hold("anchor index ID must derive only from tenant");
71
+ journalIdentity(value.ledgerIdentity);
72
+ rrsiExact(
73
+ value.artifactScope,
74
+ ["artifactTenantId", "audience", "purpose"],
75
+ "anchor artifact scope",
76
+ );
77
+ for (const [name, entry] of Object.entries(value.artifactScope))
78
+ rrsiId(entry, name);
79
+ if (value.artifactScope.purpose !== "evolution-ledger")
80
+ hold("anchor requires original Ledger retention purpose");
81
+ rrsiDigest(value.storageGraphDigest, "storage graph digest");
82
+ rrsiDigest(value.rootPublicKeyDigest, "declared root public key digest");
83
+ rrsiInteger(value.revision, "anchor revision", 1, 2 ** 31 - 1);
84
+ if (value.revision === 1) {
85
+ if (value.previousAnchorDigest !== null)
86
+ hold("first anchor must not claim a predecessor");
87
+ } else rrsiDigest(value.previousAnchorDigest, "previous anchor digest");
88
+ rrsiExact(
89
+ value.checkpoint,
90
+ ["ledgerId", "identityDigest", "epoch", "sequence", "headDigest"],
91
+ "anchor checkpoint",
92
+ );
93
+ const checkpointIdentity = Object.fromEntries(
94
+ ["ledgerId", "identityDigest", "epoch"].map((name) => [
95
+ name,
96
+ value.checkpoint[name],
97
+ ]),
98
+ );
99
+ if (!same(checkpointIdentity, value.ledgerIdentity))
100
+ hold("anchor checkpoint belongs to another journal");
101
+ rrsiInteger(value.checkpoint.sequence, "checkpoint sequence", 0);
102
+ rrsiDigest(value.checkpoint.headDigest, "checkpoint head digest");
103
+ rrsiExact(
104
+ value.restrictionHistory,
105
+ ["recordCount", "tailRecordDigest", "restrictionsDigest"],
106
+ "anchor restriction history",
107
+ );
108
+ rrsiInteger(
109
+ value.restrictionHistory.recordCount,
110
+ "restriction record count",
111
+ 0,
112
+ 256,
113
+ );
114
+ if (value.restrictionHistory.recordCount > value.checkpoint.sequence)
115
+ hold("restriction count exceeds the declared journal checkpoint");
116
+ if (value.restrictionHistory.recordCount === 0) {
117
+ if (value.restrictionHistory.tailRecordDigest !== null)
118
+ hold("empty restriction history must have no tail");
119
+ } else
120
+ rrsiDigest(
121
+ value.restrictionHistory.tailRecordDigest,
122
+ "restriction tail digest",
123
+ );
124
+ rrsiDigest(
125
+ value.restrictionHistory.restrictionsDigest,
126
+ "restriction set digest",
127
+ );
128
+ return rrsiEnvelope(RRSI_TENANT_INDEX_ANCHOR_SCHEMA, "anchorDigest", value);
129
+ }
130
+
131
+ export function verifyRrsiTenantIndexAnchor(input) {
132
+ return verifyRrsiEnvelope(
133
+ input,
134
+ RRSI_TENANT_INDEX_ANCHOR_SCHEMA,
135
+ "anchorDigest",
136
+ INPUT_KEYS,
137
+ buildRrsiTenantIndexAnchor,
138
+ );
139
+ }
140
+
141
+ /** Exact domain-separated bytes for an external signer; no signer default. */
142
+ export function serializeRrsiTenantIndexAnchorSignatureMessage(anchor) {
143
+ const checked = verifyRrsiTenantIndexAnchor(anchor);
144
+ return Buffer.from(`${SIGNATURE_DOMAIN}\0${rrsiCanonical(checked)}`, "utf8");
145
+ }
146
+
147
+ /**
148
+ * Mathematical verification against an explicitly supplied public key only.
149
+ * This deliberately creates no trusted-root brand, pin store or routing grant.
150
+ */
151
+ export function verifyRrsiTenantIndexAnchorSignature(input) {
152
+ const value = snapshotRrsiData(input);
153
+ rrsiExact(
154
+ value,
155
+ ["anchor", "publicKeySpki", "signature"],
156
+ "anchor signature input",
157
+ );
158
+ const anchor = verifyRrsiTenantIndexAnchor(value.anchor);
159
+ if (
160
+ typeof value.publicKeySpki !== "string" ||
161
+ value.publicKeySpki.length > 128
162
+ )
163
+ hold("anchor public key must be bounded canonical Ed25519 SPKI");
164
+ const publicBytes = Buffer.from(value.publicKeySpki, "base64url");
165
+ if (
166
+ publicBytes.length !== 44 ||
167
+ publicBytes.toString("base64url") !== value.publicKeySpki
168
+ )
169
+ hold("anchor public key SPKI encoding differs");
170
+ let publicKey;
171
+ try {
172
+ publicKey = createPublicKey({
173
+ key: publicBytes,
174
+ format: "der",
175
+ type: "spki",
176
+ });
177
+ } catch {
178
+ hold("anchor public key SPKI cannot be parsed");
179
+ }
180
+ if (
181
+ publicKey.asymmetricKeyType !== "ed25519" ||
182
+ !publicKey.export({ format: "der", type: "spki" }).equals(publicBytes)
183
+ )
184
+ hold("anchor public key must be exact Ed25519 SPKI");
185
+ if (sha(publicBytes) !== anchor.rootPublicKeyDigest)
186
+ hold("anchor public key differs from the declared root digest");
187
+ if (typeof value.signature !== "string" || value.signature.length !== 86)
188
+ hold("anchor signature must be bounded canonical Ed25519 bytes");
189
+ const signatureBytes = Buffer.from(value.signature, "base64url");
190
+ if (
191
+ signatureBytes.length !== 64 ||
192
+ signatureBytes.toString("base64url") !== value.signature
193
+ )
194
+ hold("anchor signature encoding differs");
195
+ if (
196
+ !verify(
197
+ null,
198
+ serializeRrsiTenantIndexAnchorSignatureMessage(anchor),
199
+ publicKey,
200
+ signatureBytes,
201
+ )
202
+ )
203
+ hold("anchor signature was rejected");
204
+ return rrsiEnvelope(
205
+ RRSI_TENANT_INDEX_ANCHOR_SIGNATURE_SCHEMA,
206
+ "signatureCheckDigest",
207
+ {
208
+ anchorDigest: anchor.anchorDigest,
209
+ publicKeyDigest: anchor.rootPublicKeyDigest,
210
+ declaredDeploymentId: anchor.deploymentId,
211
+ declaredTenantId: anchor.tenantId,
212
+ declaredRoutingScope: anchor.routingScope,
213
+ signatureVerifiedRelativeToKey: true,
214
+ rootAuthorityVerified: false,
215
+ routingPinVerified: false,
216
+ historyTransferVerified: false,
217
+ tenantWideIndexAuthorityVerified: false,
218
+ generationProvenanceVerified: false,
219
+ grantsMutationOrPromotionAuthority: false,
220
+ decision: "HOLD",
221
+ },
222
+ );
223
+ }
@@ -0,0 +1,157 @@
1
+ /** Real local history prefixes. Installation/root/routing authority remains HOLD. */
2
+ import { isProxy } from "node:util/types";
3
+ import { captureRrsiObservedTextIndex } from "./rrsi-observed-text-index.js";
4
+ import { verifyRrsiTenantIndexAnchorSignature } from "./rrsi-tenant-index-anchor-contracts.js";
5
+ import { rrsiCanonical, rrsiEnvelope, snapshotRrsiData } from "./rrsi-data.js";
6
+
7
+ export const RRSI_TENANT_INDEX_ANCHOR_HISTORY_HOLD_CODE =
8
+ "CC_RRSI_ANCHOR_HISTORY_HOLD";
9
+ const same = (a, b) => rrsiCanonical(a) === rrsiCanonical(b);
10
+ const FIXED_KEYS = [
11
+ "deploymentId",
12
+ "tenantId",
13
+ "routingScope",
14
+ "indexId",
15
+ "ledgerIdentity",
16
+ "artifactScope",
17
+ "storageGraphDigest",
18
+ "rootPublicKeyDigest",
19
+ ];
20
+ function hold(message, cause) {
21
+ throw Object.assign(new Error(message, cause ? { cause } : undefined), {
22
+ code: RRSI_TENANT_INDEX_ANCHOR_HISTORY_HOLD_CODE,
23
+ });
24
+ }
25
+ function guard(operation) {
26
+ try {
27
+ return operation();
28
+ } catch (cause) {
29
+ if (cause?.code === RRSI_TENANT_INDEX_ANCHOR_HISTORY_HOLD_CODE) throw cause;
30
+ hold(
31
+ "anchor history could not authenticate the original local prefix",
32
+ cause,
33
+ );
34
+ }
35
+ }
36
+ function own(value, names) {
37
+ if (
38
+ !value ||
39
+ isProxy(value) ||
40
+ Object.getPrototypeOf(value) !== Object.prototype ||
41
+ Reflect.ownKeys(value).length !== names.length
42
+ )
43
+ hold("anchor history requires exact plain own fields");
44
+ return Object.fromEntries(
45
+ names.map((name) => {
46
+ const field = Object.getOwnPropertyDescriptor(value, name);
47
+ if (!field?.enumerable || !("value" in field))
48
+ hold("anchor history cannot use accessors");
49
+ return [name, field.value];
50
+ }),
51
+ );
52
+ }
53
+
54
+ export function inspectRrsiTenantIndexHistory(input) {
55
+ return guard(() => {
56
+ const request = own(input, ["observedTextIndex"]);
57
+ const captured = captureRrsiObservedTextIndex(request.observedTextIndex);
58
+ const history = captured.captureHistoryCheckpoints({ checkpoints: [] });
59
+ history.recheck();
60
+ return history.snapshot;
61
+ });
62
+ }
63
+
64
+ export function verifyRrsiTenantIndexAnchorHistory(input) {
65
+ return guard(() => {
66
+ const request = own(input, ["observedTextIndex", "previous", "current"]);
67
+ const index = captureRrsiObservedTextIndex(request.observedTextIndex);
68
+ const data = snapshotRrsiData({
69
+ previous: request.previous,
70
+ current: request.current,
71
+ });
72
+ verifyRrsiTenantIndexAnchorSignature(data.previous);
73
+ verifyRrsiTenantIndexAnchorSignature(data.current);
74
+ const previous = data.previous.anchor,
75
+ current = data.current.anchor;
76
+ if (
77
+ previous.routingScope !== "installation" ||
78
+ current.routingScope !== "installation"
79
+ )
80
+ hold("local history verification requires installation scope");
81
+ if (data.previous.publicKeySpki !== data.current.publicKeySpki)
82
+ hold("local anchor history cannot change root key");
83
+ for (const key of FIXED_KEYS)
84
+ if (!same(previous[key], current[key]))
85
+ hold(`local anchor history cannot change ${key}`);
86
+ if (current.revision === previous.revision) {
87
+ if (current.anchorDigest !== previous.anchorDigest)
88
+ hold("same revision has a different history anchor");
89
+ } else if (
90
+ current.revision !== previous.revision + 1 ||
91
+ current.previousAnchorDigest !== previous.anchorDigest
92
+ )
93
+ hold("local history anchor must be the exact declared successor");
94
+ for (const anchor of [previous, current]) {
95
+ if (
96
+ anchor.tenantId !== index.descriptor.tenantId ||
97
+ anchor.indexId !== index.descriptor.indexId ||
98
+ !same(anchor.ledgerIdentity, index.descriptor.ledgerIdentity) ||
99
+ !same(anchor.artifactScope, {
100
+ artifactTenantId: index.descriptor.artifactTenantId,
101
+ audience: index.descriptor.audience,
102
+ purpose: index.descriptor.purpose,
103
+ })
104
+ )
105
+ hold("history anchor differs from the original observed index scope");
106
+ }
107
+ if (previous.checkpoint.sequence > current.checkpoint.sequence)
108
+ hold("local history anchor cannot move its checkpoint backward");
109
+ const history = index.captureHistoryCheckpoints({
110
+ checkpoints: [previous.checkpoint, current.checkpoint],
111
+ });
112
+ const snapshot = history.snapshot;
113
+ if (!same(current.checkpoint, snapshot.current.checkpoint))
114
+ hold("current anchor is not the actual captured journal head");
115
+ for (const [anchor, prefix] of [
116
+ [previous, snapshot.prefixes[0]],
117
+ [current, snapshot.prefixes[1]],
118
+ ])
119
+ if (!same(anchor.restrictionHistory, prefix.restrictionHistory))
120
+ hold(
121
+ "anchor restriction declaration differs from retained prefix history",
122
+ );
123
+ history.recheck();
124
+ return rrsiEnvelope(
125
+ "chainlesschain.rrsi-tenant-index-anchor-history-check/v1",
126
+ "historyCheckDigest",
127
+ {
128
+ previousAnchorDigest: previous.anchorDigest,
129
+ currentAnchorDigest: current.anchorDigest,
130
+ indexDescriptorDigest: snapshot.indexDescriptorDigest,
131
+ localCompositionDigest: snapshot.localCompositionDigest,
132
+ artifactStoreDirectoryBoundaryDigest:
133
+ snapshot.artifactStoreDirectoryBoundaryDigest,
134
+ artifactStoreDirectoryBoundaryRechecked: true,
135
+ artifactStoreBoundaryScope: "root-and-files-directories",
136
+ previous: snapshot.prefixes[0],
137
+ current: snapshot.current,
138
+ signaturesVerifiedRelativeToExplicitKey: true,
139
+ localJournalPrefixVerified: true,
140
+ localRestrictionPrefixVerified: true,
141
+ localRetainedHistoryReplayed: true,
142
+ selectedContextOnly: true,
143
+ storageGraphDigestVerified: false,
144
+ rootAuthorityVerified: false,
145
+ installationBindingSignatureVerified: false,
146
+ routingPinVerified: false,
147
+ crossProcessRollbackProtectionVerified: false,
148
+ historyTransferVerified: false,
149
+ originCutoverAuthenticated: false,
150
+ tenantWideIndexAuthorityVerified: false,
151
+ generationProvenanceVerified: false,
152
+ grantsMutationOrPromotionAuthority: false,
153
+ decision: "HOLD",
154
+ },
155
+ );
156
+ });
157
+ }
@@ -2775,7 +2775,9 @@ export class SkillReleaseRegistry {
2775
2775
  // Authenticate the original port object before reading any caller method.
2776
2776
  this.#storeBinding.assertTransactionLedger(transactionLedger);
2777
2777
  this.#storeBinding.recheckForOpen();
2778
- this.#runtimeMode = "uninitialized";
2778
+ this.#runtimeMode = this.#storeBinding.runtimeDirectories
2779
+ ? "authenticated-empty-read-only"
2780
+ : "uninitialized";
2779
2781
  } else assertOutsideRrsiRegistryNamespace(requestedBase);
2780
2782
  if (
2781
2783
  !transactionLedger ||
@@ -2832,7 +2834,8 @@ export class SkillReleaseRegistry {
2832
2834
  this.#rootIdentity = this.#boundaries.tenantRoot.identity;
2833
2835
  this.#markerPath = path.join(this.rootDir, TENANT_MARKER_FILE);
2834
2836
  this.#markerIdentity = this.#storeBinding.marker.identity;
2835
- this.#directories = deepFreeze({});
2837
+ this.#directories =
2838
+ this.#storeBinding.runtimeDirectories ?? deepFreeze({});
2836
2839
  this.#assertBoundary();
2837
2840
  } else {
2838
2841
  const base = this.#initializeDirectory(requestedBase, {
@@ -3972,7 +3975,11 @@ export class SkillReleaseRegistry {
3972
3975
 
3973
3976
  #readRelease(releaseDigest) {
3974
3977
  const expected = digest(releaseDigest, "releaseDigest");
3975
- if (this.#runtimeMode === "uninitialized") {
3978
+ if (
3979
+ ["uninitialized", "authenticated-empty-read-only"].includes(
3980
+ this.#runtimeMode,
3981
+ )
3982
+ ) {
3976
3983
  this.#assertBoundary();
3977
3984
  throw failure("SKILL_RELEASE_NOT_FOUND", "release was not found");
3978
3985
  }
@@ -4011,7 +4018,11 @@ export class SkillReleaseRegistry {
4011
4018
 
4012
4019
  #readStateRaw(name) {
4013
4020
  const normalizedName = skillName(name);
4014
- if (this.#runtimeMode === "uninitialized") {
4021
+ if (
4022
+ ["uninitialized", "authenticated-empty-read-only"].includes(
4023
+ this.#runtimeMode,
4024
+ )
4025
+ ) {
4015
4026
  this.#assertBoundary();
4016
4027
  return initialState(normalizedName, this.tenantId);
4017
4028
  }
@@ -4190,7 +4201,11 @@ export class SkillReleaseRegistry {
4190
4201
 
4191
4202
  #readInventory() {
4192
4203
  this.#assertBoundary();
4193
- if (this.#runtimeMode === "uninitialized")
4204
+ if (
4205
+ ["uninitialized", "authenticated-empty-read-only"].includes(
4206
+ this.#runtimeMode,
4207
+ )
4208
+ )
4194
4209
  return deepFreeze({ active: [], releases: [] });
4195
4210
  const releasePattern = /^[a-f0-9]{64}\.json$/u;
4196
4211
  const statePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.json$/u;