chainlesschain 0.166.91 → 0.166.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/README.md +17 -17
  2. package/package.json +3 -3
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-DgV7xb8F.js → AIOps-oo9rE0gh.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CgANpkKu.js → ActionButton-CVJVVv4i.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DnvpX7RB.js → Analytics-CUXuwmia.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-C2bHccBM.js → AppLayout-iM4PvCuY.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-BIhijC9g.js → Artifacts-DKUIJbf9.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-CKRjWGdp.js → Audit-C4_SzFN2.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CblYtgBE.js → BackgroundAgents-C3427uy-.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-Cq35b78a.js → Backup-BpEQQiog.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-DcB7NoRz.js → BaseInput-C_exQomZ.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-tc3b-s7i.js → Chat-DzpkLtWa.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-DX4XmTWm.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BLD5bH5u.js → Checkbox-CxAC1CU8.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BLOsoazN.js → Codegen-wDFAGCLp.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-Bdr7JwIx.js → Col-BvwirhMf.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-C84BsWE0.js → Community-BJuA7paY.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-Dzdwd04z.js → Compact-DzV35_u2.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CCG-R0EV.js → Compliance-CIDPPvr9.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BYj72SK0.js → Cowork-DyTMxP3N.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-B6iKAwOf.js → Cron-PcNLjMFx.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BJ-oDC6u.js → Crosschain-B_O7ck6Z.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-BnMckGLr.js → DID-CII35Me1.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-Cyje-gCO.js → Dashboard-DU56fkNz.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BpNlenjK.js → Dropdown-DHC8HVeJ.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-BhonO7Nv.js → EmailListRenderer-oUOHFNsD.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DVoNU-Id.js → EvolutionSettings-D7RCAWNl.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-tdn-KC67.js → FamilyGuardDashboard-CGONPZxC.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation--EEVrHhz.js → Federation-BbDlPWcl.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Cy8zr0-4.js → FormItemContext-BBJbFQQT.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-BuUhpgFi.js → GenericCardRenderer-iuxAero4.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-Ctd3E5Pe.js → Git-Dw0prdY5.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Ce7dV6aU.js → Governance-DOGqi_uV.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CD1vExIH.js → Inference-BY5oUGGj.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-Dn64OdQ7.js → KnowledgeGraph-CcE2EVYX.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-PmElVRrT.js → Logs-DyfN4R5w.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-BFiVKf5t.js → MarkdownRenderer-Bj62Aq0M.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-OW4jTXwx.js → Marketplace-CuuuAXUh.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BEq2Ib4x.js → McpTools-948Fithv.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Can_P2oK.js → Memory-D4PINvyy.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DJ8R-dn3.js → MobileBridge-ECKMaLzX.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-B7kV9GOt.js → MobileProjects-CB5MAcvD.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-BfxamolS.js → Mtc-BRzIM3HJ.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-DHtuv7av.js → MtcAudit-CGeAXJGn.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-DLkLpvxc.js → Multisig-C_qJ-8K-.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-u4XtJTIt.js → NLProgramming-DAEyCn7T.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BwuuPJLS.js → Notes-DmD3MEec.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-HEeu-E9v.js → NotificationSettings-Cv4Q3VC9.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-BNlpaFjH.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-Yh-czs3b.js → Organization-DqAFdz6p.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DmE8mYVM.js → Overflow-8Ye9cIcE.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CWVck8WN.js → P2P-755SfHoJ.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DgFqekod.js → PdhVaultBrowser-CgZLiucX.js} +4 -4
  56. package/src/assets/web-panel/assets/{Permissions-BtJBVOHV.js → Permissions-C-vFF_rL.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-6VBObXzd.js → PersonalDataHub-Diz1oXM3.js} +5 -5
  58. package/src/assets/web-panel/assets/{Pipeline-D222FmqY.js → Pipeline-D4kIzsZG.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Bi9FMikp.js → Privacy-QKLkSAUH.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-Bo52H47H.js → ProjectInit-I0S9o_RT.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BPkesfOc.js → ProjectSettings-DdgV3-Ho.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-GynohSFX.js → Projects-BJHHegtj.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-DVdMg04n.js → Providers-uVa1zfbS.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-DqJCb595.js → QrScannerModal-YLVpOChR.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-J7loQbXi.js → QuickAsk-535AYH61.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BI5aURVc.js → Recommend-C_P6eNSw.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BN2sqGvz.js → RemoteSession-EXH1SbNj.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BGOND-Fi.js → Reputation-Cxc7d3eU.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-77dfwaUk.js → Row-EDqJy-wS.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-FtBAxS3g.js → RssFeed-C03Xeg9_.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BaYVLFb7.js → Search-DsIga9DK.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-LE3Vv6ab.js → Security-DgArMFc-.js} +3 -3
  73. package/src/assets/web-panel/assets/{Services-C5pP-Whz.js → Services-MooDpHBP.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CLqKUVsF.js → Skeleton-B10P1Dr6.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-BPjN0SX5.js → Skills-DHLHEkLl.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-14jD70kg.js → Sla-D4RT7d4g.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Dr9ij42W.js → SpeechSettings-D8u6F-LV.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BzLHP7B8.js → SyncSettings-4nvNzRq8.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-YqV9b0rV.js → Tasks-CmCb8zNO.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-CxxAE4PK.js → Templates-CzESIa21.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CRb3PcKJ.js → Tenant-Ch_N3p4d.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CTzPpBaP.js → Terminal-BZccUf_X.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-DjFUj_hy.js → TimelineRenderer-FrKcNy_3.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Bbb8tPvx.js → Tokens-4xvLpXfD.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CSeWGM0W.js → Trigger-84UjyxXd.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-JgESMBo3.js → Trust-M6UtHnji.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CiObLk0T.js → UkeySign-L_xEgtCg.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CFEZaQ2x.js → VideoEditing-BLJCX9ru.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-DR8ZGDNn.js → Wallet-DwL6uJCj.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DxZukvu7.js → WebAuthn-Bmn9pdzz.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CKgSZQwn.js → WorkflowEditor-DSsZ5xG1.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CTxEQE66.js → chat--FGNUaa8.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CAjKMUu3.js → colors-DeuwNdqX.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-BXuz49at.js → compact-item-I4XKxRFU.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-CFN_Hwr9.js → createContext-RoD2p5Ba.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-ctnml4IW.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BwoSBSfP.js → hasIn-BsvyddUM.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CB3kVd9c.js → index-0tRU1Sv-.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-o9DpkZKf.js → index-4xHc2WjT.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BmQITjMU.js → index-B8-eGLN9.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DY-gBSm8.js → index-BS_uqSTa.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-F2E5RCwz.js → index-BYEVBlCl.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CF9lWi1o.js → index-BcBM065G.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bu2P6u8m.js → index-BnrL4s-3.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Dv7V2kg6.js → index-BrZPb0On.js} +1 -1
  106. package/src/assets/web-panel/assets/index-C7PN8mh1.js +1 -0
  107. package/src/assets/web-panel/assets/{index-DViK2bkv.js → index-CBazK4-7.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BmXpdcHI.js → index-CPS3zv1c.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bqv_Cray.js → index-CSrZiiAs.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B7kp-zRE.js → index-CVwZMt9Z.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-B0QbLlWn.js → index-CdgKZYgm.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DjF5BOZx.js → index-CesTu01s.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CSmFby3Q.js → index-CiHlSuMl.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-B2o_BBjg.js → index-CsLVac9n.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CehdwJ_Q.js → index-D1ONyBTW.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Bj4hIiLW.js → index-D4IZsKbF.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-_ZtCyUdz.js → index-D4P4vpmv.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B9yR7zqr.js → index-D6J8dz7X.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-u9_DM3ZC.js → index-DChy2sHE.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C8er4W9u.js → index-DKUCl_Lk.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BK4ftQ4d.js → index-DRluW3_r.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B2tEnBPx.js → index-DWUmhNO-.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-IY9bd5az.js → index-DXnpVGG3.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Cp5y7lX_.js → index-DYOpAS6-.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-T3MTE6jB.js → index-DiH-3cR2.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DxunxaTw.js → index-DlEfwgzr.js} +1 -1
  127. package/src/assets/web-panel/assets/index-KnbBJAO-.js +1 -0
  128. package/src/assets/web-panel/assets/{index-DTX9CJPx.js → index-R4St_zjR.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Tz5dheZa.js → index-ScgoDU9V.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DmkbAADP.js → index-UWdT_lty.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Bw9s2d3c.js → index-VAlor744.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CN53dE_u.js → index-Wco_uvRo.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DpdDnZX_.js → index-ZgFED_Zd.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-IahILygB.js → index-jaHeti4i.js} +3 -3
  135. package/src/assets/web-panel/assets/{index-Cgk0YEiq.js → index-rJDabtw4.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-t2Ch_JKn.js → index-vRiGKIP0.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-BoiGJDoO.js → initDefaultProps-BHT0PacY.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-5eL4E0pA.js → motion-CBYsMtsC.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-DjggDi_1.js → move-DnHfFV4K.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Ce8Vo2T3.js → mtc-parser-DfGkRYrx.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-D1yOBaO2.js → omit-SjLcPQA9.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-8NLceQe8.js → pickAttrs-CCZHF4ep.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CsIdBRmQ.js → placementArrow-DjCGn2sJ.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-GM5NE8En.js → responsiveObserve-BCFCl2on.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-44yj3u49.js → slide-DsfmuIZu.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-B8tqtWcX.js → statusUtils-hPKuJUia.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-NhDPBbyB.js → styleChecker-DOXKH7Kf.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-C8Qz1GtN.js → useFlexGapSupport-B_G7yqio.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-ClUv4kih.js → useFs-BXOTOm2l.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BwkOVEh6.js → usePersonalDataHub-CRvie3g7.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode--gMF33R0.js → vnode-D9_zMmww.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DXg3TqOP.js → zoom-C4tW03qI.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +52 -0
  155. package/src/lib/artifact-store.js +51 -3
  156. package/src/lib/bounded-artifact-file-read.js +131 -0
  157. package/src/lib/evolution/evolution-artifact-ports.js +235 -129
  158. package/src/lib/evolution/evolution-eval-cohort-enrollment.js +713 -47
  159. package/src/lib/evolution/evolution-eval-gate.js +146 -0
  160. package/src/lib/evolution/evolution-eval-launch-admission.js +168 -90
  161. package/src/lib/evolution/evolution-eval-ledger-capture.js +50 -0
  162. package/src/lib/evolution/evolution-eval-readonly-audit.js +106 -0
  163. package/src/lib/evolution/evolution-ledger-file-backend.js +20 -0
  164. package/src/lib/evolution/evolution-ledger-ports.js +59 -27
  165. package/src/lib/evolution/evolution-ledger-v2-journal.js +55 -18
  166. package/src/lib/evolution/evolution-workbench-file-resources.js +19 -1
  167. package/src/lib/evolution/rrsi-cohort-registration.js +275 -0
  168. package/src/lib/evolution/rrsi-contracts.js +742 -0
  169. package/src/lib/evolution/rrsi-data.js +196 -0
  170. package/src/lib/evolution/rrsi-evaluation-adapter.js +275 -0
  171. package/src/lib/evolution/rrsi-evaluation-variants.js +267 -0
  172. package/src/lib/evolution/rrsi-group-statistics.js +553 -0
  173. package/src/lib/evolution/rrsi-history-ledger-adapter.js +3286 -0
  174. package/src/lib/evolution/rrsi-installation-route-contracts.js +275 -0
  175. package/src/lib/evolution/rrsi-installation-route-reader.js +282 -0
  176. package/src/lib/evolution/rrsi-native-batch-evidence.js +520 -0
  177. package/src/lib/evolution/rrsi-native-eval-row-collector.js +538 -0
  178. package/src/lib/evolution/rrsi-native-evaluation-batch.js +547 -0
  179. package/src/lib/evolution/rrsi-native-evaluation-plan.js +431 -0
  180. package/src/lib/evolution/rrsi-native-group-statistics-plan.js +121 -0
  181. package/src/lib/evolution/rrsi-native-group-statistics.js +482 -0
  182. package/src/lib/evolution/rrsi-native-quality-receipt-contracts.js +321 -0
  183. package/src/lib/evolution/rrsi-native-quality-receipt.js +256 -0
  184. package/src/lib/evolution/rrsi-native-statistics-protocol.js +330 -0
  185. package/src/lib/evolution/rrsi-observed-text-index.js +978 -0
  186. package/src/lib/evolution/rrsi-parent-binding.js +290 -0
  187. package/src/lib/evolution/rrsi-pm-execution-bridge.js +500 -0
  188. package/src/lib/evolution/rrsi-pm-training-mapping.js +134 -0
  189. package/src/lib/evolution/rrsi-preparation-contracts.js +213 -0
  190. package/src/lib/evolution/rrsi-registry-history-binding.js +193 -0
  191. package/src/lib/evolution/rrsi-registry-runtime-policy.js +648 -0
  192. package/src/lib/evolution/rrsi-registry-store-policy.js +1271 -0
  193. package/src/lib/evolution/rrsi-runtime-composition.js +79 -0
  194. package/src/lib/evolution/rrsi-selector.js +434 -0
  195. package/src/lib/evolution/rrsi-statistics-simulation.js +354 -0
  196. package/src/lib/evolution/rrsi-tenant-index-anchor-contracts.js +223 -0
  197. package/src/lib/evolution/rrsi-tenant-index-anchor-history.js +157 -0
  198. package/src/lib/evolution/skill-candidate-registry.js +216 -29
  199. package/src/lib/evolution/skill-registry-maintenance.js +80 -0
  200. package/src/lib/evolution/skill-registry-writer-control.js +138 -0
  201. package/src/lib/evolution/skill-release-registry.js +414 -169
  202. package/src/lib/formal-quality-eval-runtime.js +2 -14
  203. package/src/lib/goal-store.js +225 -16
  204. package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +291 -30
  205. package/src/lib/record-replay/skill-recorder.js +38 -3
  206. package/src/lib/remote-read-loop-guard.js +227 -24
  207. package/src/lib/scheduler-kernel/authority-resolver.js +12 -163
  208. package/src/lib/scheduler-kernel/contract.js +27 -414
  209. package/src/lib/scheduler-kernel/runtime.js +21 -823
  210. package/src/lib/scheduler-kernel/service.js +11 -328
  211. package/src/lib/scheduler-kernel/source-locator-path.js +7 -142
  212. package/src/lib/scheduler-kernel/store.js +67 -5931
  213. package/src/lib/secure-fs.js +16 -1314
  214. package/src/lib/task-progress-tracker.js +6 -1
  215. package/src/lib/with-file-lock.js +122 -20
  216. package/src/runtime/agent-core.js +71 -23
  217. package/src/assets/web-panel/assets/ChatBubbleRenderer-fcc_Tvqu.js +0 -1
  218. package/src/assets/web-panel/assets/OrderTableRenderer-BtvN-Qwh.js +0 -1
  219. package/src/assets/web-panel/assets/devWarning-CfB8DxT2.js +0 -1
  220. package/src/assets/web-panel/assets/index-CCsRfd0k.js +0 -1
  221. package/src/assets/web-panel/assets/index-CsmiZIQ4.js +0 -1
@@ -6563,6 +6563,125 @@ export class EvolutionEvalReceiptVerifier {
6563
6563
  }
6564
6564
  return receiptSnapshot;
6565
6565
  }
6566
+
6567
+ #captureReceiptValidityWindows(input) {
6568
+ if (
6569
+ !input ||
6570
+ isProxy(input) ||
6571
+ !Array.isArray(input) ||
6572
+ Object.getPrototypeOf(input) !== Array.prototype ||
6573
+ input.length > 64 ||
6574
+ Reflect.ownKeys(input).length !== input.length + 1
6575
+ ) {
6576
+ throw evalError(
6577
+ EVOLUTION_EVAL_INVALID_CODE,
6578
+ "receipt freshness set must contain at most 64 dense own receipts",
6579
+ );
6580
+ }
6581
+ const windows = Array.from({ length: input.length }, (_, index) => {
6582
+ const field = Object.getOwnPropertyDescriptor(input, String(index));
6583
+ const receipt = field?.value;
6584
+ if (
6585
+ !field?.enumerable ||
6586
+ !("value" in field) ||
6587
+ !receipt ||
6588
+ typeof receipt !== "object" ||
6589
+ isProxy(receipt) ||
6590
+ ![Object.prototype, null].includes(Object.getPrototypeOf(receipt))
6591
+ ) {
6592
+ throw evalError(
6593
+ EVOLUTION_EVAL_INVALID_CODE,
6594
+ "receipt validity windows require own data records",
6595
+ );
6596
+ }
6597
+ const captured = {};
6598
+ for (const key of ["issuedAt", "expiresAt"]) {
6599
+ const timestamp = Object.getOwnPropertyDescriptor(receipt, key);
6600
+ if (
6601
+ !timestamp?.enumerable ||
6602
+ !("value" in timestamp) ||
6603
+ typeof timestamp.value !== "string"
6604
+ )
6605
+ throw evalError(
6606
+ EVOLUTION_EVAL_INVALID_CODE,
6607
+ "receipt validity timestamps require own strings",
6608
+ );
6609
+ captured[key] = normalizeTimestamp(timestamp.value, `receipt.${key}`);
6610
+ }
6611
+ // Only temporal fields are needed. Independent signed documents never
6612
+ // become a larger aggregate canonical document just for a clock check.
6613
+ const { issuedAt, expiresAt } = captured;
6614
+ return {
6615
+ issuedAt,
6616
+ expiresAt,
6617
+ issuedMs: new Date(issuedAt).getTime(),
6618
+ expiresMs: new Date(expiresAt).getTime(),
6619
+ };
6620
+ });
6621
+ return windows;
6622
+ }
6623
+
6624
+ #assertReceiptValidityWindows(windows) {
6625
+ // Read the captured trusted clock once, after all bounded synchronous work.
6626
+ // Repeated asynchronous verification cannot establish a set-wide instant.
6627
+ const checked = readClock(this.#clock);
6628
+ if (
6629
+ windows.some(
6630
+ ({ issuedMs, expiresMs }) =>
6631
+ expiresMs <= issuedMs ||
6632
+ expiresMs - issuedMs > this.#maximumReceiptTtlMs ||
6633
+ issuedMs > checked.milliseconds + this.#maximumClockSkewMs ||
6634
+ expiresMs <= checked.milliseconds,
6635
+ )
6636
+ ) {
6637
+ throw evalError(
6638
+ EVOLUTION_EVAL_AUTHORITY_FAILED_CODE,
6639
+ "evaluation receipt set is stale or has an invalid validity window",
6640
+ );
6641
+ }
6642
+ return Object.freeze({
6643
+ checkedAt: checked.timestamp,
6644
+ earliestExpiresAt: windows.length
6645
+ ? new Date(
6646
+ Math.min(...windows.map((window) => window.expiresMs)),
6647
+ ).toISOString()
6648
+ : null,
6649
+ signatureAuthenticated: false,
6650
+ });
6651
+ }
6652
+
6653
+ /** Temporal check only: signature and run-context verification remain separate. */
6654
+ assertReceiptSetFreshness(input) {
6655
+ return this.#assertReceiptValidityWindows(
6656
+ this.#captureReceiptValidityWindows(input),
6657
+ );
6658
+ }
6659
+
6660
+ assertReceiptChunkSetFreshness(input) {
6661
+ if (
6662
+ !input ||
6663
+ isProxy(input) ||
6664
+ !Array.isArray(input) ||
6665
+ Object.getPrototypeOf(input) !== Array.prototype ||
6666
+ input.length > 128 ||
6667
+ Reflect.ownKeys(input).length !== input.length + 1
6668
+ )
6669
+ throw evalError(
6670
+ EVOLUTION_EVAL_INVALID_CODE,
6671
+ "receipt validity chunks require at most 128 dense own lists",
6672
+ );
6673
+ const windows = [];
6674
+ for (let index = 0; index < input.length; index++) {
6675
+ const field = Object.getOwnPropertyDescriptor(input, String(index));
6676
+ if (!field?.enumerable || !("value" in field))
6677
+ throw evalError(
6678
+ EVOLUTION_EVAL_INVALID_CODE,
6679
+ "receipt validity chunks cannot use accessors or holes",
6680
+ );
6681
+ windows.push(...this.#captureReceiptValidityWindows(field.value));
6682
+ }
6683
+ return this.#assertReceiptValidityWindows(windows);
6684
+ }
6566
6685
  }
6567
6686
 
6568
6687
  // The exported classes are composition roots. Freezing their prototypes keeps
@@ -6636,6 +6755,33 @@ export async function verifyEvolutionEvalReceipt(verifier, value, expected) {
6636
6755
  );
6637
6756
  }
6638
6757
 
6758
+ /** Use the genuine verifier's captured clock without exposing a callable clock port. */
6759
+ export function assertEvolutionEvalReceiptSetFreshness(verifier, receipts) {
6760
+ if (!RECEIPT_VERIFIER_INSTANCES.has(verifier)) {
6761
+ throw evalError(
6762
+ EVOLUTION_EVAL_INVALID_CODE,
6763
+ "receipt set freshness requires a trusted read-only verifier instance",
6764
+ );
6765
+ }
6766
+ return EvolutionEvalReceiptVerifier.prototype.assertReceiptSetFreshness.call(
6767
+ verifier,
6768
+ receipts,
6769
+ );
6770
+ }
6771
+
6772
+ /** Independently bounded cohort windows share one final captured-clock reading. */
6773
+ export function assertEvolutionEvalReceiptChunkSetFreshness(verifier, chunks) {
6774
+ if (!RECEIPT_VERIFIER_INSTANCES.has(verifier))
6775
+ throw evalError(
6776
+ EVOLUTION_EVAL_INVALID_CODE,
6777
+ "receipt chunk freshness requires a trusted read-only verifier instance",
6778
+ );
6779
+ return EvolutionEvalReceiptVerifier.prototype.assertReceiptChunkSetFreshness.call(
6780
+ verifier,
6781
+ chunks,
6782
+ );
6783
+ }
6784
+
6639
6785
  const RESULT_ROW_KEYS = new Set([
6640
6786
  "taskDigest",
6641
6787
  "seed",
@@ -10,8 +10,12 @@ import {
10
10
  import {
11
11
  EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
12
12
  EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
13
- EvolutionLedger,
14
13
  } from "./evolution-ledger.js";
14
+ import {
15
+ captureEvolutionEvalLedger,
16
+ readEvolutionEvalLedger,
17
+ } from "./evolution-eval-ledger-capture.js";
18
+ import { captureEvolutionEvalReadonlyAudit } from "./evolution-eval-readonly-audit.js";
15
19
 
16
20
  export const EVOLUTION_EVAL_LAUNCH_ADMISSION_SCHEMA =
17
21
  "chainlesschain.evolution-eval-launch-admission/v1";
@@ -112,11 +116,13 @@ function text(value, label) {
112
116
  }
113
117
 
114
118
  function digest(value, label) {
115
- if (!DIGEST.test(value ?? "")) fail(`${label} must be a sha256 digest`);
119
+ if (typeof value !== "string" || !DIGEST.test(value))
120
+ fail(`${label} must be a sha256 digest`);
116
121
  return value;
117
122
  }
118
123
 
119
124
  function timestamp(value, label) {
125
+ if (typeof value !== "string") fail(`${label} is invalid`);
120
126
  const parsed = Date.parse(value);
121
127
  if (
122
128
  typeof value !== "string" ||
@@ -248,16 +254,14 @@ function eventId(state) {
248
254
  }
249
255
 
250
256
  function events(state) {
251
- return EvolutionLedger.prototype.read
252
- .call(state.ledger)
253
- .filter(
254
- (event) =>
255
- event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
256
- event.eventId === eventId(state),
257
- );
257
+ return readEvolutionEvalLedger(state.ledgerMethods).filter(
258
+ (event) =>
259
+ event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
260
+ event.eventId === eventId(state),
261
+ );
258
262
  }
259
263
 
260
- function resolveEvent(state, event) {
264
+ function resolveEvent(state, event, capturedIdentity = null) {
261
265
  if (
262
266
  event.type !== EVOLUTION_EVAL_LAUNCH_ADMISSION_EVENT_TYPE ||
263
267
  event.tenantId !== state.descriptor.tenantId ||
@@ -270,7 +274,7 @@ function resolveEvent(state, event) {
270
274
  canonical(state.enrollment ? [state.enrollment.enrollmentRef] : [])
271
275
  )
272
276
  fail("admission ledger event is substituted");
273
- const identity = EvolutionLedger.prototype.verify.call(state.ledger);
277
+ const identity = capturedIdentity ?? state.ledgerMethods.verify();
274
278
  const resolution = state.resolveArtifact({
275
279
  epoch: identity.epoch,
276
280
  ledgerId: identity.ledgerId,
@@ -332,13 +336,20 @@ export function createEvolutionEvalLaunchAdmissionAuthority({
332
336
  if (
333
337
  !(artifactPorts instanceof EvolutionArtifactPorts) ||
334
338
  isProxy(artifactPorts) ||
335
- !(ledger instanceof EvolutionLedger) ||
336
339
  isProxy(ledger) ||
337
340
  !isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)
338
341
  )
339
342
  fail(
340
343
  "admission requires real artifact ports, Ledger and a branded resolver",
341
344
  );
345
+ let ledgerMethods;
346
+ try {
347
+ ledgerMethods = captureEvolutionEvalLedger(ledger);
348
+ } catch {
349
+ fail(
350
+ "admission requires real artifact ports, Ledger and a branded resolver",
351
+ );
352
+ }
342
353
  if (typeof now !== "function" || isProxy(now) || !signer || isProxy(signer))
343
354
  fail("admission signer and clock are required");
344
355
  const sign = Object.getOwnPropertyDescriptor(signer, "sign")?.value;
@@ -357,6 +368,7 @@ export function createEvolutionEvalLaunchAdmissionAuthority({
357
368
  sign: sign.bind(signer),
358
369
  artifactPorts,
359
370
  ledger,
371
+ ledgerMethods,
360
372
  resolveArtifact: ledgerArtifactResolver,
361
373
  now,
362
374
  enrollment:
@@ -389,6 +401,12 @@ export function captureEvolutionEvalLaunchAdmissionBinding(authority) {
389
401
  enrollmentDigest: state.enrollment?.enrollmentDigest ?? null,
390
402
  cohortCompletenessAuthenticated: false,
391
403
  promotionAuthority: false,
404
+ ...(state.enrollment?.registrationKind
405
+ ? {
406
+ registrationKind: state.enrollment.registrationKind,
407
+ historyBinding: state.enrollment.historyBinding,
408
+ }
409
+ : {}),
392
410
  });
393
411
  }
394
412
 
@@ -402,85 +420,102 @@ function authorityState(authority) {
402
420
  export async function admitEvolutionEvalLaunch(authority, input) {
403
421
  const state = authorityState(authority);
404
422
  const captured = request(input, state, true);
405
- // Capture head BEFORE the occupancy read: a concurrent append cannot escape CAS.
406
- const head = EvolutionLedger.prototype.verify.call(state.ledger);
407
- if (state.enrollment) state.enrollment.assertOpen(captured);
408
- if (events(state).length !== 0) fail("admission slot is already occupied");
409
- const core = {
410
- schema: state.enrollment
411
- ? EVOLUTION_EVAL_ENROLLED_LAUNCH_ADMISSION_SCHEMA
412
- : EVOLUTION_EVAL_LAUNCH_ADMISSION_SCHEMA,
413
- descriptorDigest: state.descriptorDigest,
414
- ...captured,
415
- ...(state.enrollment
416
- ? {
417
- enrollmentDigest: state.enrollment.enrollmentDigest,
418
- descriptor: state.descriptor,
419
- }
420
- : {}),
421
- };
422
- const signature = state.sign(
423
- Object.freeze({ message: message(core).toString("utf8") }),
424
- );
425
- const evidence = verifyEvidence(
426
- {
427
- ...core,
428
- attestation: {
429
- algorithm: "ed25519",
430
- issuer: state.descriptor.authorityId,
431
- keyId: state.descriptor.keyId,
432
- trustPolicyDigest: state.descriptor.trustPolicyDigest,
433
- value: signature,
423
+ let nativePrepared = false;
424
+ try {
425
+ // A native claim appends its paired budget intent before the admission CAS
426
+ // snapshot. Both subsequent assertOpen calls are strictly read-only.
427
+ if (state.enrollment?.prepare) {
428
+ state.enrollment.prepare(captured);
429
+ nativePrepared = true;
430
+ }
431
+ // Capture head BEFORE the occupancy read: a concurrent append cannot escape CAS.
432
+ const head = state.ledgerMethods.verify();
433
+ if (state.enrollment) state.enrollment.assertOpen(captured);
434
+ if (events(state).length !== 0) fail("admission slot is already occupied");
435
+ const core = {
436
+ schema: state.enrollment
437
+ ? EVOLUTION_EVAL_ENROLLED_LAUNCH_ADMISSION_SCHEMA
438
+ : EVOLUTION_EVAL_LAUNCH_ADMISSION_SCHEMA,
439
+ descriptorDigest: state.descriptorDigest,
440
+ ...captured,
441
+ ...(state.enrollment
442
+ ? {
443
+ enrollmentDigest: state.enrollment.enrollmentDigest,
444
+ descriptor: state.descriptor,
445
+ }
446
+ : {}),
447
+ };
448
+ const signature = state.sign(
449
+ Object.freeze({ message: message(core).toString("utf8") }),
450
+ );
451
+ const evidence = verifyEvidence(
452
+ {
453
+ ...core,
454
+ attestation: {
455
+ algorithm: "ed25519",
456
+ issuer: state.descriptor.authorityId,
457
+ keyId: state.descriptor.keyId,
458
+ trustPolicyDigest: state.descriptor.trustPolicyDigest,
459
+ value: signature,
460
+ },
434
461
  },
435
- },
436
- state,
437
- );
438
- request(captured, state, true);
439
- const published = EvolutionArtifactPorts.prototype.putCanonical.call(
440
- state.artifactPorts,
441
- ARTIFACT_TYPE,
442
- evidence,
443
- {
444
- audience: state.descriptor.audience,
445
- purpose: state.descriptor.purpose,
446
- retention: "ledger",
447
- },
448
- );
449
- if (
450
- published?.receipt?.persisted !== true ||
451
- published.receipt.readbackVerified !== true ||
452
- published.receipt.integrityVerified !== true ||
453
- published.receipt.retention !== "ledger"
454
- )
455
- fail("admission artifact persistence failed");
456
- request(captured, state, true);
457
- if (state.enrollment) state.enrollment.assertOpen(captured);
458
- const receipt = EvolutionLedger.prototype.appendDomainEvent.call(
459
- state.ledger,
460
- {
461
- type: EVOLUTION_EVAL_LAUNCH_ADMISSION_EVENT_TYPE,
462
- eventId: eventId(state),
463
- tenantId: state.descriptor.tenantId,
464
- artifactTenantId: state.descriptor.artifactTenantId,
465
- correlationId: state.descriptor.streamId,
466
- decision: "accepted",
467
- skillName: "evolution-eval",
468
- reason: "signed attempt admission; Actor execution is unproven",
469
- sourceRefs: state.enrollment ? [state.enrollment.enrollmentRef] : [],
470
- subjectRef: published.ref,
471
- timestamp: captured.admittedAt,
472
- },
473
- { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
474
- );
475
- if (receipt?.authenticated !== true || receipt.durable !== true)
476
- fail("admission ledger append failed");
477
- const matches = events(state);
478
- if (matches.length !== 1) fail("admission slot is absent or ambiguous");
479
- const result = resolveEvent(state, matches[0]);
480
- if (canonical(result.evidence) !== canonical(evidence))
481
- fail("admission readback differs from signed bytes");
482
- request(captured, state, true);
483
- return result;
462
+ state,
463
+ );
464
+ request(captured, state, true);
465
+ const published = EvolutionArtifactPorts.prototype.putCanonical.call(
466
+ state.artifactPorts,
467
+ ARTIFACT_TYPE,
468
+ evidence,
469
+ {
470
+ audience: state.descriptor.audience,
471
+ purpose: state.descriptor.purpose,
472
+ retention: "ledger",
473
+ },
474
+ );
475
+ if (
476
+ published?.receipt?.persisted !== true ||
477
+ published.receipt.readbackVerified !== true ||
478
+ published.receipt.integrityVerified !== true ||
479
+ published.receipt.retention !== "ledger"
480
+ )
481
+ fail("admission artifact persistence failed");
482
+ request(captured, state, true);
483
+ if (state.enrollment) state.enrollment.assertOpen(captured);
484
+ const receipt = state.ledgerMethods.appendDomainEvent(
485
+ {
486
+ type: EVOLUTION_EVAL_LAUNCH_ADMISSION_EVENT_TYPE,
487
+ eventId: eventId(state),
488
+ tenantId: state.descriptor.tenantId,
489
+ artifactTenantId: state.descriptor.artifactTenantId,
490
+ correlationId: state.descriptor.streamId,
491
+ decision: "accepted",
492
+ skillName: "evolution-eval",
493
+ reason: "signed attempt admission; Actor execution is unproven",
494
+ sourceRefs: state.enrollment ? [state.enrollment.enrollmentRef] : [],
495
+ subjectRef: published.ref,
496
+ timestamp: captured.admittedAt,
497
+ },
498
+ { expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
499
+ );
500
+ if (receipt?.authenticated !== true || receipt.durable !== true)
501
+ fail("admission ledger append failed");
502
+ const matches = events(state);
503
+ if (matches.length !== 1) fail("admission slot is absent or ambiguous");
504
+ const result = resolveEvent(state, matches[0]);
505
+ if (canonical(result.evidence) !== canonical(evidence))
506
+ fail("admission readback differs from signed bytes");
507
+ request(captured, state, true);
508
+ return result;
509
+ } catch (error) {
510
+ if (nativePrepared && state.enrollment?.recordFailure) {
511
+ try {
512
+ state.enrollment.recordFailure();
513
+ } catch {
514
+ /* Preserve the original failure; durable intent and ceilings remain. */
515
+ }
516
+ }
517
+ throw error;
518
+ }
484
519
  }
485
520
 
486
521
  /** Durable audit/recovery may outlive the execution deadline; it grants no execution permit. */
@@ -503,3 +538,46 @@ export async function resolveEvolutionEvalLaunch(authority, input) {
503
538
  fail("admission lookup differs from the recorded attempt");
504
539
  return result;
505
540
  }
541
+
542
+ /**
543
+ * Verify an admission within a genuine immutable journal view. The caller must
544
+ * complete the whole audit with assertUnchanged before publishing its result.
545
+ * This does not call admission preparation or grant an execution permit.
546
+ */
547
+ export async function resolveEvolutionEvalLaunchFromReadonlyAudit(
548
+ authority,
549
+ input,
550
+ audit,
551
+ ) {
552
+ const state = authorityState(authority);
553
+ const captured = captureEvolutionEvalReadonlyAudit(audit, state.ledger);
554
+ const expected = record(
555
+ input,
556
+ ["runId", "runNonce", "requestDigest"],
557
+ "admission lookup",
558
+ );
559
+ text(expected.runId, "runId");
560
+ text(expected.runNonce, "runNonce");
561
+ digest(expected.requestDigest, "requestDigest");
562
+ const matches = captured
563
+ .eventsById(eventId(state))
564
+ .filter((event) => event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA);
565
+ if (matches.length !== 1) fail("admission slot is absent or ambiguous");
566
+ const result = resolveEvent(state, matches[0], captured.identity);
567
+ if (
568
+ Object.keys(expected).some((key) => result.evidence[key] !== expected[key])
569
+ )
570
+ fail("admission lookup differs from the recorded attempt");
571
+ // An artifact resolver can reenter another audit operation. Respect any
572
+ // invalidation already detected there without another full journal scan.
573
+ captureEvolutionEvalReadonlyAudit(audit, state.ledger);
574
+ return frozen({
575
+ ...result,
576
+ schema:
577
+ "chainlesschain.evolution-eval-launch-admission-audit-resolution/v1",
578
+ auditHead: captured.identity,
579
+ historicalSnapshotOnly: true,
580
+ requiresFinalAuditHeadCheck: true,
581
+ readyForExecution: false,
582
+ });
583
+ }
@@ -0,0 +1,50 @@
1
+ /** Capture the actual journal; never follow a v2 journal back to its source Ledger. */
2
+ import { isProxy } from "node:util/types";
3
+ import {
4
+ EvolutionLedger,
5
+ EVOLUTION_LEDGER_MAX_EVENTS,
6
+ } from "./evolution-ledger.js";
7
+ import { isEvolutionLedgerV2Journal } from "./evolution-ledger-v2-journal.js";
8
+
9
+ export function captureEvolutionEvalLedger(ledger) {
10
+ if (!ledger || isProxy(ledger))
11
+ throw new TypeError("Eval requires a genuine Ledger journal");
12
+ const methods = {};
13
+ for (const name of ["read", "verify", "appendDomainEvent"]) {
14
+ if (ledger instanceof EvolutionLedger)
15
+ methods[name] = (...args) =>
16
+ Reflect.apply(EvolutionLedger.prototype[name], ledger, args);
17
+ else if (isEvolutionLedgerV2Journal(ledger)) {
18
+ const method = Object.getOwnPropertyDescriptor(ledger, name)?.value;
19
+ if (typeof method !== "function" || isProxy(method))
20
+ throw new TypeError("Eval v2 journal method is missing");
21
+ methods[name] = (...args) => Reflect.apply(method, ledger, args);
22
+ } else throw new TypeError("Eval requires a genuine Ledger journal");
23
+ }
24
+ return Object.freeze(methods);
25
+ }
26
+
27
+ /** Complete, contiguous census with bookends; defaults must not truncate at 10,000. */
28
+ export function readEvolutionEvalLedger(methods) {
29
+ for (let attempt = 0; attempt < 3; attempt++) {
30
+ const before = methods.verify();
31
+ const events = methods.read({
32
+ afterSequence: 0,
33
+ limit: EVOLUTION_LEDGER_MAX_EVENTS,
34
+ });
35
+ const after = methods.verify();
36
+ if (
37
+ !["ledgerId", "identityDigest", "epoch", "headDigest", "sequence"].every(
38
+ (name) => before[name] === after[name],
39
+ )
40
+ )
41
+ continue;
42
+ if (
43
+ events.length !== after.sequence ||
44
+ events.some((event, index) => event.sequence !== index + 1)
45
+ )
46
+ throw new Error("Eval requires complete contiguous Ledger coverage");
47
+ return events;
48
+ }
49
+ throw new Error("Ledger changed during Eval census; retry audit");
50
+ }
@@ -0,0 +1,106 @@
1
+ /** One immutable journal view; authentication finishes at its final head check. */
2
+ import {
3
+ captureEvolutionEvalLedger,
4
+ readEvolutionEvalLedger,
5
+ } from "./evolution-eval-ledger-capture.js";
6
+
7
+ const AUDITS = new WeakMap();
8
+ const HEAD_FIELDS = [
9
+ "ledgerId",
10
+ "identityDigest",
11
+ "epoch",
12
+ "sequence",
13
+ "headDigest",
14
+ ];
15
+ const EMPTY_EVENTS = Object.freeze([]);
16
+
17
+ function fail(message) {
18
+ const error = new Error(message);
19
+ error.code = "CC_EVOLUTION_EVAL_READONLY_AUDIT_FAILED";
20
+ throw error;
21
+ }
22
+
23
+ function readHead(methods) {
24
+ const current = methods.verify();
25
+ return Object.freeze(
26
+ Object.fromEntries(HEAD_FIELDS.map((field) => [field, current[field]])),
27
+ );
28
+ }
29
+
30
+ function sameHead(left, right) {
31
+ return HEAD_FIELDS.every((field) => left[field] === right[field]);
32
+ }
33
+
34
+ // Events come only from the genuine journal's verified read. Preserve native
35
+ // null-prototype references and freeze each event independently; the complete
36
+ // journal must not become one RRSI-sized canonical document.
37
+ function freezeEvent(value) {
38
+ if (value && typeof value === "object") {
39
+ Object.values(value).forEach(freezeEvent);
40
+ Object.freeze(value);
41
+ }
42
+ return value;
43
+ }
44
+
45
+ export function createEvolutionEvalReadonlyAudit(ledger) {
46
+ const methods = captureEvolutionEvalLedger(ledger);
47
+ const identity = readHead(methods);
48
+ const events = Object.freeze(
49
+ readEvolutionEvalLedger(methods).map(freezeEvent),
50
+ );
51
+ const byEventId = new Map();
52
+ for (const event of events) {
53
+ if (typeof event.eventId !== "string") continue;
54
+ let matches = byEventId.get(event.eventId);
55
+ if (!matches) byEventId.set(event.eventId, (matches = []));
56
+ matches.push(event);
57
+ }
58
+ for (const matches of byEventId.values()) Object.freeze(matches);
59
+ if (!sameHead(identity, readHead(methods)))
60
+ fail("Ledger changed while capturing the read-only audit");
61
+
62
+ let invalidated = false;
63
+ function assertActive() {
64
+ if (invalidated) fail("read-only audit was invalidated by a Ledger change");
65
+ }
66
+ const captured = Object.freeze({
67
+ identity,
68
+ events,
69
+ eventsById(id) {
70
+ assertActive();
71
+ if (typeof id !== "string") fail("audit event ID must be a string");
72
+ return byEventId.get(id) ?? EMPTY_EVENTS;
73
+ },
74
+ assertUnchanged() {
75
+ assertActive();
76
+ let current;
77
+ try {
78
+ current = readHead(methods);
79
+ } catch (error) {
80
+ invalidated = true;
81
+ throw error;
82
+ }
83
+ if (!sameHead(identity, current)) {
84
+ invalidated = true;
85
+ fail(
86
+ "Ledger changed during the read-only audit; retry with a new view",
87
+ );
88
+ }
89
+ return identity;
90
+ },
91
+ });
92
+ const audit = Object.freeze({
93
+ schema: "chainlesschain.evolution-eval-readonly-audit/v1",
94
+ });
95
+ AUDITS.set(audit, { ledger, captured, assertActive });
96
+ return audit;
97
+ }
98
+
99
+ /** Capture does not rescan the journal; the consumer must finish with assertUnchanged. */
100
+ export function captureEvolutionEvalReadonlyAudit(audit, ledger) {
101
+ const state = AUDITS.get(audit);
102
+ if (!state || state.ledger !== ledger)
103
+ fail("a genuine read-only audit of the same Ledger journal is required");
104
+ state.assertActive();
105
+ return state.captured;
106
+ }
@@ -11,6 +11,7 @@ export const EVOLUTION_LEDGER_FILE_BACKEND_SCHEMA =
11
11
  "chainlesschain.evolution-ledger-file-backend/v1";
12
12
 
13
13
  const BACKENDS = new WeakSet();
14
+ const BACKEND_BINDINGS = new WeakMap();
14
15
 
15
16
  function requiredString(value, label) {
16
17
  if (typeof value !== "string" || value.trim() === "") {
@@ -205,6 +206,15 @@ export function createEvolutionLedgerFileBackend({
205
206
  witness,
206
207
  });
207
208
  BACKENDS.add(backend);
209
+ BACKEND_BINDINGS.set(
210
+ backend,
211
+ Object.freeze({
212
+ matchesLedger: Object.freeze((value) => value === ledger),
213
+ matchesArtifactResolver: Object.freeze(
214
+ (value) => value === artifactResolver,
215
+ ),
216
+ }),
217
+ );
208
218
  return backend;
209
219
  }
210
220
 
@@ -214,3 +224,13 @@ export function captureEvolutionLedgerFileBackend(value) {
214
224
  }
215
225
  return value;
216
226
  }
227
+
228
+ /** Compare the original journal/resolver objects without exposing signing ports. */
229
+ export function captureEvolutionLedgerFileBackendBinding(value) {
230
+ const binding = BACKEND_BINDINGS.get(value);
231
+ if (!binding)
232
+ throw new TypeError(
233
+ "a branded EvolutionLedger file backend binding is required",
234
+ );
235
+ return binding;
236
+ }