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
@@ -0,0 +1,742 @@
1
+ /** Frozen planning contracts only. Digests do not authenticate source metadata. */
2
+ import {
3
+ RrsiContractError,
4
+ snapshotRrsiData,
5
+ rrsiExact,
6
+ rrsiId,
7
+ rrsiDigest,
8
+ rrsiInteger,
9
+ rrsiFinite,
10
+ rrsiBoolean,
11
+ rrsiHash,
12
+ rrsiFail,
13
+ rrsiEnvelope,
14
+ verifyRrsiEnvelope,
15
+ freezeRrsiData,
16
+ } from "./rrsi-data.js";
17
+
18
+ export { RrsiContractError };
19
+ export const RRSI_POLICY_SCHEMA = "chainlesschain.rrsi-policy/v1";
20
+ export const RRSI_DATASET_SCHEMA = "chainlesschain.rrsi-dataset-manifest/v1";
21
+ export const RRSI_CAMPAIGN_SCHEMA = "chainlesschain.rrsi-campaign/v1";
22
+ export const RRSI_CANDIDATE_SCHEMA = "chainlesschain.rrsi-candidate/v1";
23
+ export const RRSI_PARTITIONS = Object.freeze([
24
+ "train",
25
+ "select",
26
+ "gate-validation",
27
+ "gate-test",
28
+ "audit",
29
+ ]);
30
+ export const RRSI_GROUP_DIMENSIONS = Object.freeze([
31
+ "template",
32
+ "project",
33
+ "principal",
34
+ "timeWindow",
35
+ ]);
36
+ export const RRSI_BUDGET_FIELDS = Object.freeze([
37
+ "maxTokens",
38
+ "maxToolCalls",
39
+ "maxWallClockMs",
40
+ "maxCostMicrounits",
41
+ "maxExecutions",
42
+ ]);
43
+ const POLICY_KEYS = [
44
+ "policyId",
45
+ "limits",
46
+ "weights",
47
+ "cost",
48
+ "history",
49
+ "complexity",
50
+ "thresholds",
51
+ "calibrated",
52
+ ];
53
+ const DATASET_KEYS = ["manifestId", "datasetVersion", "tasks"];
54
+ const CAMPAIGN_KEYS = [
55
+ "campaignId",
56
+ "tenantId",
57
+ "goalId",
58
+ "candidateKind",
59
+ "sourceCommitSha",
60
+ "parentReleaseDigest",
61
+ "anchorReleaseDigest",
62
+ "policy",
63
+ "dataset",
64
+ "execution",
65
+ "experiment",
66
+ "budget",
67
+ ];
68
+ const CANDIDATE_KEYS = [
69
+ "candidateId",
70
+ "parentReleaseDigest",
71
+ "kind",
72
+ "targetId",
73
+ "lineageDepth",
74
+ "sourceTaskIds",
75
+ "artifacts",
76
+ "hypothesisDigest",
77
+ ];
78
+
79
+ function numericRecord(input, keys, label, validator) {
80
+ rrsiExact(input, keys, label);
81
+ return Object.fromEntries(
82
+ keys.map((key) => [key, validator(input[key], `${label}.${key}`)]),
83
+ );
84
+ }
85
+
86
+ function uniqueList(values, label, min, max, validator = rrsiId) {
87
+ if (!Array.isArray(values) || values.length < min || values.length > max)
88
+ rrsiFail(`${label} has an invalid entry count`);
89
+ const result = values.map((value) => validator(value, label));
90
+ if (new Set(result).size !== result.length)
91
+ rrsiFail(`${label} has duplicate entries`);
92
+ return result;
93
+ }
94
+
95
+ function kind(value) {
96
+ if (!["skill", "memory-policy"].includes(value))
97
+ rrsiFail("invalid candidate kind");
98
+ return value;
99
+ }
100
+
101
+ export function buildRrsiPolicy(input) {
102
+ const value = snapshotRrsiData(input);
103
+ rrsiExact(value, POLICY_KEYS, "RRSI policy");
104
+ const limits = numericRecord(
105
+ value.limits,
106
+ [
107
+ "maxRounds",
108
+ "maxCandidatesPerRound",
109
+ "maxCandidates",
110
+ "maxChangedFiles",
111
+ "maxArtifactBytes",
112
+ "maxLineageDepth",
113
+ "maxSelectionQueries",
114
+ "maxConsecutiveNoGainRounds",
115
+ ],
116
+ "limits",
117
+ (number, label) => rrsiInteger(number, label, 1, 1_000_000),
118
+ );
119
+ if (
120
+ limits.maxRounds > 32 ||
121
+ limits.maxCandidatesPerRound > 8 ||
122
+ limits.maxCandidates > limits.maxRounds * limits.maxCandidatesPerRound ||
123
+ limits.maxChangedFiles > 3 ||
124
+ limits.maxSelectionQueries > limits.maxCandidates ||
125
+ limits.maxConsecutiveNoGainRounds > limits.maxRounds ||
126
+ limits.maxLineageDepth > 32
127
+ )
128
+ rrsiFail("RRSI limits are inconsistent or exceed the bounded pilot");
129
+ const weights = numericRecord(
130
+ value.weights,
131
+ ["generalization", "cost", "noise", "history", "complexity"],
132
+ "weights",
133
+ (number, label) => rrsiFinite(number, label, 0, 100),
134
+ );
135
+ if (Object.values(weights).every((weight) => weight === 0))
136
+ rrsiFail("RRSI policy requires a nonzero regularizer");
137
+ rrsiExact(
138
+ value.cost,
139
+ ["costScaleMicrounits", "latencyScaleMs", "costWeight", "latencyWeight"],
140
+ "cost",
141
+ );
142
+ const cost = {
143
+ costScaleMicrounits: rrsiInteger(
144
+ value.cost.costScaleMicrounits,
145
+ "cost scale",
146
+ 1,
147
+ ),
148
+ latencyScaleMs: rrsiInteger(value.cost.latencyScaleMs, "latency scale", 1),
149
+ costWeight: rrsiFinite(value.cost.costWeight, "cost weight"),
150
+ latencyWeight: rrsiFinite(value.cost.latencyWeight, "latency weight"),
151
+ };
152
+ rrsiExact(
153
+ value.history,
154
+ [
155
+ "window",
156
+ "maxOscillations",
157
+ "maxRepeatedFailures",
158
+ "oscillationWeight",
159
+ "repeatedFailureWeight",
160
+ ],
161
+ "history",
162
+ );
163
+ const history = {
164
+ window: rrsiInteger(value.history.window, "history window", 1, 1000),
165
+ maxOscillations: rrsiInteger(
166
+ value.history.maxOscillations,
167
+ "oscillation maximum",
168
+ 1,
169
+ 1000,
170
+ ),
171
+ maxRepeatedFailures: rrsiInteger(
172
+ value.history.maxRepeatedFailures,
173
+ "failure maximum",
174
+ 1,
175
+ 1000,
176
+ ),
177
+ oscillationWeight: rrsiFinite(
178
+ value.history.oscillationWeight,
179
+ "oscillation weight",
180
+ ),
181
+ repeatedFailureWeight: rrsiFinite(
182
+ value.history.repeatedFailureWeight,
183
+ "failure weight",
184
+ ),
185
+ };
186
+ rrsiExact(
187
+ value.complexity,
188
+ [
189
+ "targetArtifactBytes",
190
+ "targetWorkflowNodes",
191
+ "targetChangedFiles",
192
+ "bytesWeight",
193
+ "nodesWeight",
194
+ "filesWeight",
195
+ ],
196
+ "complexity",
197
+ );
198
+ const complexity = {
199
+ targetArtifactBytes: rrsiInteger(
200
+ value.complexity.targetArtifactBytes,
201
+ "target bytes",
202
+ 1,
203
+ limits.maxArtifactBytes,
204
+ ),
205
+ targetWorkflowNodes: rrsiInteger(
206
+ value.complexity.targetWorkflowNodes,
207
+ "target nodes",
208
+ 1,
209
+ 1000,
210
+ ),
211
+ targetChangedFiles: rrsiInteger(
212
+ value.complexity.targetChangedFiles,
213
+ "target files",
214
+ 1,
215
+ limits.maxChangedFiles,
216
+ ),
217
+ bytesWeight: rrsiFinite(value.complexity.bytesWeight, "bytes weight"),
218
+ nodesWeight: rrsiFinite(value.complexity.nodesWeight, "nodes weight"),
219
+ filesWeight: rrsiFinite(value.complexity.filesWeight, "files weight"),
220
+ };
221
+ rrsiExact(
222
+ value.thresholds,
223
+ [
224
+ "minimumQualityDelta",
225
+ "minimumEfficiencyReduction",
226
+ "maxNoiseRegression",
227
+ "minIndependentGroups",
228
+ ],
229
+ "thresholds",
230
+ );
231
+ const thresholds = {
232
+ minimumQualityDelta: rrsiFinite(
233
+ value.thresholds.minimumQualityDelta,
234
+ "minimum quality delta",
235
+ 0.05,
236
+ 1,
237
+ ),
238
+ minimumEfficiencyReduction: rrsiFinite(
239
+ value.thresholds.minimumEfficiencyReduction,
240
+ "minimum efficiency reduction",
241
+ 0.1,
242
+ 1,
243
+ ),
244
+ maxNoiseRegression: rrsiFinite(
245
+ value.thresholds.maxNoiseRegression,
246
+ "noise limit",
247
+ ),
248
+ minIndependentGroups: rrsiInteger(
249
+ value.thresholds.minIndependentGroups,
250
+ "minimum groups",
251
+ 20,
252
+ 5000,
253
+ ),
254
+ };
255
+ return rrsiEnvelope(RRSI_POLICY_SCHEMA, "policyDigest", {
256
+ policyId: rrsiId(value.policyId, "policyId"),
257
+ limits,
258
+ weights,
259
+ cost,
260
+ history,
261
+ complexity,
262
+ thresholds,
263
+ calibrated: rrsiBoolean(value.calibrated, "calibrated"),
264
+ });
265
+ }
266
+
267
+ export function verifyRrsiPolicy(value) {
268
+ return verifyRrsiEnvelope(
269
+ value,
270
+ RRSI_POLICY_SCHEMA,
271
+ "policyDigest",
272
+ POLICY_KEYS,
273
+ buildRrsiPolicy,
274
+ );
275
+ }
276
+
277
+ export function buildRrsiDatasetManifest(input) {
278
+ const value = snapshotRrsiData(input);
279
+ rrsiExact(value, DATASET_KEYS, "RRSI dataset");
280
+ if (
281
+ !Array.isArray(value.tasks) ||
282
+ value.tasks.length < 5 ||
283
+ value.tasks.length > 5000
284
+ )
285
+ rrsiFail("RRSI dataset requires 5..5000 task references");
286
+ const seenIds = new Set();
287
+ const seenContent = new Set();
288
+ const owners = new Map();
289
+ const parents = new Map();
290
+ const find = (id) => {
291
+ let current = id;
292
+ while (parents.get(current) !== current) current = parents.get(current);
293
+ while (id !== current) {
294
+ const previous = parents.get(id);
295
+ parents.set(id, current);
296
+ id = previous;
297
+ }
298
+ return current;
299
+ };
300
+ const tasks = value.tasks
301
+ .map((task) => {
302
+ rrsiExact(
303
+ task,
304
+ ["id", "partition", "contentDigest", "groups"],
305
+ "task reference",
306
+ );
307
+ const id = rrsiId(task.id, "task ID");
308
+ const contentDigest = rrsiDigest(
309
+ task.contentDigest,
310
+ "task content digest",
311
+ );
312
+ if (!RRSI_PARTITIONS.includes(task.partition))
313
+ rrsiFail("invalid task partition");
314
+ if (seenIds.has(id) || seenContent.has(contentDigest))
315
+ rrsiFail("duplicate task ID or content", "CC_RRSI_DATA_LEAKAGE");
316
+ seenIds.add(id);
317
+ seenContent.add(contentDigest);
318
+ parents.set(id, id);
319
+ const groups = numericRecord(
320
+ task.groups,
321
+ RRSI_GROUP_DIMENSIONS,
322
+ "task groups",
323
+ rrsiDigest,
324
+ );
325
+ return { id, partition: task.partition, contentDigest, groups };
326
+ })
327
+ .sort((left, right) =>
328
+ left.id < right.id ? -1 : left.id > right.id ? 1 : 0,
329
+ );
330
+ for (const task of tasks) {
331
+ for (const dimension of RRSI_GROUP_DIMENSIONS) {
332
+ const key = `${dimension}:${task.groups[dimension]}`;
333
+ const owner = owners.get(key);
334
+ if (owner && owner.partition !== task.partition)
335
+ rrsiFail(
336
+ "declared source group crosses RRSI partitions",
337
+ "CC_RRSI_DATA_LEAKAGE",
338
+ );
339
+ if (owner) parents.set(find(task.id), find(owner.id));
340
+ else owners.set(key, task);
341
+ }
342
+ }
343
+ const pools = Object.fromEntries(
344
+ RRSI_PARTITIONS.map((partition) => {
345
+ const members = tasks.filter((task) => task.partition === partition);
346
+ if (!members.length)
347
+ rrsiFail("RRSI dataset must contain every partition");
348
+ return [
349
+ partition,
350
+ {
351
+ taskCount: members.length,
352
+ componentCount: new Set(members.map((task) => find(task.id))).size,
353
+ partitionDigest: rrsiHash("chainlesschain.rrsi-partition/v1", {
354
+ partition,
355
+ tasks: members,
356
+ }),
357
+ },
358
+ ];
359
+ }),
360
+ );
361
+ return rrsiEnvelope(RRSI_DATASET_SCHEMA, "datasetDigest", {
362
+ manifestId: rrsiId(value.manifestId, "manifestId"),
363
+ datasetVersion: rrsiId(value.datasetVersion, "datasetVersion"),
364
+ tasks,
365
+ pools,
366
+ sourceMetadataAuthenticated: false,
367
+ });
368
+ }
369
+
370
+ export function verifyRrsiDatasetManifest(value) {
371
+ return verifyRrsiEnvelope(
372
+ value,
373
+ RRSI_DATASET_SCHEMA,
374
+ "datasetDigest",
375
+ DATASET_KEYS,
376
+ buildRrsiDatasetManifest,
377
+ ["pools", "sourceMetadataAuthenticated"],
378
+ );
379
+ }
380
+
381
+ export function projectRrsiTrainingView(input) {
382
+ const dataset = verifyRrsiDatasetManifest(input);
383
+ return freezeRrsiData({
384
+ trainingPartitionDigest: dataset.pools.train.partitionDigest,
385
+ tasks: dataset.tasks
386
+ .filter((task) => task.partition === "train")
387
+ .map(({ id, contentDigest }) => ({ id, contentDigest })),
388
+ sourceMetadataAuthenticated: false,
389
+ });
390
+ }
391
+
392
+ function budgetRecord(input, label) {
393
+ return numericRecord(input, RRSI_BUDGET_FIELDS, label, (number, name) =>
394
+ rrsiInteger(number, name, 1),
395
+ );
396
+ }
397
+
398
+ export function buildRrsiCampaign(input) {
399
+ const value = snapshotRrsiData(input);
400
+ rrsiExact(value, CAMPAIGN_KEYS, "RRSI campaign");
401
+ if (
402
+ typeof value.goalId !== "string" ||
403
+ !/^[a-z][a-z0-9-]{0,127}$/u.test(value.goalId)
404
+ )
405
+ rrsiFail("campaign goalId must be a canonical artifact target");
406
+ const policy = verifyRrsiPolicy(value.policy);
407
+ const dataset = verifyRrsiDatasetManifest(value.dataset);
408
+ const minimumTasks = {
409
+ train: 60,
410
+ select: 40,
411
+ "gate-validation": 40,
412
+ "gate-test": 40,
413
+ audit: 40,
414
+ };
415
+ for (const partition of RRSI_PARTITIONS) {
416
+ if (
417
+ dataset.pools[partition].taskCount < minimumTasks[partition] ||
418
+ dataset.pools[partition].componentCount <
419
+ policy.thresholds.minIndependentGroups
420
+ )
421
+ rrsiFail(
422
+ "RRSI campaign needs sufficient tasks and independent declared source groups",
423
+ );
424
+ }
425
+ if (
426
+ typeof value.sourceCommitSha !== "string" ||
427
+ !/^[a-f0-9]{40}$/u.test(value.sourceCommitSha)
428
+ )
429
+ rrsiFail("campaign sourceCommitSha must be an exact Git commit");
430
+ const execution = numericRecord(
431
+ value.execution,
432
+ ["modelDigest", "pricingDigest", "environmentDigest", "graderDigest"],
433
+ "execution",
434
+ rrsiDigest,
435
+ );
436
+ rrsiExact(
437
+ value.experiment,
438
+ [
439
+ "arms",
440
+ "comparisons",
441
+ "seeds",
442
+ "perturbations",
443
+ "familyAlpha",
444
+ "power",
445
+ "bootstrapSamples",
446
+ "randomnessCommitment",
447
+ ],
448
+ "experiment",
449
+ );
450
+ const arms = uniqueList(
451
+ value.experiment.arms,
452
+ "experiment arms",
453
+ 3,
454
+ 3,
455
+ ).sort();
456
+ if (arms.join(",") !== "baseline,rrsi,rsi")
457
+ rrsiFail("experiment requires baseline, RSI and RRSI");
458
+ const comparisons = uniqueList(
459
+ value.experiment.comparisons,
460
+ "comparisons",
461
+ 2,
462
+ 32,
463
+ ).sort();
464
+ if (
465
+ !comparisons.includes("rrsi-vs-baseline") ||
466
+ !comparisons.includes("rrsi-vs-rsi")
467
+ )
468
+ rrsiFail("experiment must preregister both RRSI comparisons");
469
+ const seeds = uniqueList(
470
+ value.experiment.seeds,
471
+ "seeds",
472
+ 3,
473
+ 32,
474
+ (seed, label) => rrsiInteger(seed, label, 0, 0x7fffffff),
475
+ ).sort((a, b) => a - b);
476
+ const familyAlpha = rrsiFinite(
477
+ value.experiment.familyAlpha,
478
+ "family alpha",
479
+ 0.0001,
480
+ 0.05,
481
+ );
482
+ const bootstrapSamples = rrsiInteger(
483
+ value.experiment.bootstrapSamples,
484
+ "bootstrap samples",
485
+ 1000,
486
+ 2_000_000,
487
+ );
488
+ if ((bootstrapSamples * familyAlpha) / comparisons.length / 2 < 25)
489
+ rrsiFail(
490
+ "bootstrap plan has too few tail replicates for its comparison count",
491
+ );
492
+ const experiment = {
493
+ arms,
494
+ comparisons,
495
+ seeds,
496
+ perturbations: uniqueList(
497
+ value.experiment.perturbations,
498
+ "perturbations",
499
+ 1,
500
+ 8,
501
+ ).sort(),
502
+ familyAlpha,
503
+ power: rrsiFinite(value.experiment.power, "planned power", 0.8, 0.99),
504
+ bootstrapSamples,
505
+ randomnessCommitment: rrsiDigest(
506
+ value.experiment.randomnessCommitment,
507
+ "randomness commitment",
508
+ ),
509
+ };
510
+ rrsiExact(
511
+ value.budget,
512
+ [
513
+ "totalPerArm",
514
+ "proposalPerExploringArm",
515
+ "selectionPerExploringArm",
516
+ "finalEvaluationPerArm",
517
+ ],
518
+ "campaign budget",
519
+ );
520
+ const budget = Object.fromEntries(
521
+ Object.keys(value.budget).map((key) => [
522
+ key,
523
+ budgetRecord(value.budget[key], key),
524
+ ]),
525
+ );
526
+ for (const field of RRSI_BUDGET_FIELDS) {
527
+ const allocated =
528
+ budget.proposalPerExploringArm[field] +
529
+ budget.selectionPerExploringArm[field] +
530
+ budget.finalEvaluationPerArm[field];
531
+ if (
532
+ !Number.isSafeInteger(allocated) ||
533
+ allocated > budget.totalPerArm[field]
534
+ )
535
+ rrsiFail(`campaign stage budgets exceed per-arm ${field}`);
536
+ }
537
+ const plannedFinalExecutions =
538
+ seeds.length *
539
+ (dataset.pools["gate-validation"].taskCount +
540
+ dataset.pools["gate-test"].taskCount +
541
+ dataset.pools.audit.taskCount);
542
+ if (budget.finalEvaluationPerArm.maxExecutions < plannedFinalExecutions)
543
+ rrsiFail("final evaluation reserve cannot cover the frozen denominator");
544
+ const plannedSelectionExecutions =
545
+ 2 *
546
+ policy.limits.maxSelectionQueries *
547
+ dataset.pools.select.taskCount *
548
+ seeds.length *
549
+ (1 + experiment.perturbations.length);
550
+ if (
551
+ budget.selectionPerExploringArm.maxExecutions < plannedSelectionExecutions
552
+ )
553
+ rrsiFail("selection reserve cannot cover frozen baseline/candidate pairs");
554
+ return rrsiEnvelope(RRSI_CAMPAIGN_SCHEMA, "campaignDigest", {
555
+ campaignId: rrsiId(value.campaignId, "campaignId"),
556
+ tenantId: rrsiId(value.tenantId, "tenantId"),
557
+ goalId: rrsiId(value.goalId, "goalId"),
558
+ candidateKind: kind(value.candidateKind),
559
+ sourceCommitSha: value.sourceCommitSha,
560
+ parentReleaseDigest: rrsiDigest(
561
+ value.parentReleaseDigest,
562
+ "parent release",
563
+ ),
564
+ anchorReleaseDigest: rrsiDigest(
565
+ value.anchorReleaseDigest,
566
+ "anchor release",
567
+ ),
568
+ policy,
569
+ dataset,
570
+ execution,
571
+ experiment,
572
+ budget,
573
+ plannedFinalExecutionsPerArm: plannedFinalExecutions,
574
+ plannedSelectionExecutionsPerExploringArm: plannedSelectionExecutions,
575
+ alphaPerComparison: familyAlpha / comparisons.length,
576
+ statisticalProtocolValidated: false,
577
+ });
578
+ }
579
+
580
+ export function verifyRrsiCampaign(value) {
581
+ return verifyRrsiEnvelope(
582
+ value,
583
+ RRSI_CAMPAIGN_SCHEMA,
584
+ "campaignDigest",
585
+ CAMPAIGN_KEYS,
586
+ buildRrsiCampaign,
587
+ [
588
+ "plannedFinalExecutionsPerArm",
589
+ "plannedSelectionExecutionsPerExploringArm",
590
+ "alphaPerComparison",
591
+ "statisticalProtocolValidated",
592
+ ],
593
+ );
594
+ }
595
+
596
+ function artifactPath(path, candidateKind, targetId) {
597
+ if (
598
+ typeof path !== "string" ||
599
+ path.length > 512 ||
600
+ !/^[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(path)
601
+ )
602
+ rrsiFail("invalid artifact path");
603
+ const parts = path.split("/");
604
+ if (
605
+ parts.some(
606
+ (part) =>
607
+ !part ||
608
+ part === "." ||
609
+ part === ".." ||
610
+ part.endsWith(".") ||
611
+ /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/iu.test(part),
612
+ )
613
+ )
614
+ rrsiFail("artifact path contains traversal or reserved segments");
615
+ const root = candidateKind === "skill" ? "skills" : "memory-policies";
616
+ if (
617
+ parts.length < 3 ||
618
+ parts[0] !== root ||
619
+ parts[1] !== targetId ||
620
+ !(candidateKind === "skill" ? /\.(md|json)$/u : /\.json$/u).test(path)
621
+ )
622
+ rrsiFail("artifact path is outside the declared candidate target");
623
+ return path;
624
+ }
625
+
626
+ export function buildRrsiCandidate(campaignInput, input) {
627
+ const campaign = verifyRrsiCampaign(campaignInput);
628
+ const value = snapshotRrsiData(input);
629
+ rrsiExact(value, CANDIDATE_KEYS, "RRSI candidate");
630
+ if (
631
+ value.parentReleaseDigest !== campaign.parentReleaseDigest ||
632
+ value.kind !== campaign.candidateKind ||
633
+ value.targetId !== campaign.goalId
634
+ )
635
+ rrsiFail("candidate differs from its frozen campaign");
636
+ const sourceTaskIds = uniqueList(
637
+ value.sourceTaskIds,
638
+ "training source tasks",
639
+ 1,
640
+ 5000,
641
+ ).sort();
642
+ const allowed = new Set(
643
+ campaign.dataset.tasks
644
+ .filter((task) => task.partition === "train")
645
+ .map((task) => task.id),
646
+ );
647
+ if (sourceTaskIds.some((id) => !allowed.has(id)))
648
+ rrsiFail(
649
+ "candidate source is outside the training pool",
650
+ "CC_RRSI_DATA_LEAKAGE",
651
+ );
652
+ if (
653
+ !Array.isArray(value.artifacts) ||
654
+ value.artifacts.length < 1 ||
655
+ value.artifacts.length > campaign.policy.limits.maxChangedFiles
656
+ )
657
+ rrsiFail("candidate exceeds its file limit");
658
+ const paths = new Set();
659
+ const artifacts = value.artifacts
660
+ .map((artifact) => {
661
+ rrsiExact(
662
+ artifact,
663
+ ["path", "baseDigest", "contentDigest", "bytes", "workflowNodes"],
664
+ "candidate artifact",
665
+ );
666
+ const path = artifactPath(artifact.path, value.kind, value.targetId);
667
+ if (paths.has(path.toLowerCase()))
668
+ rrsiFail("artifact paths collide after case folding");
669
+ paths.add(path.toLowerCase());
670
+ return {
671
+ path,
672
+ baseDigest: rrsiDigest(artifact.baseDigest, "base artifact digest"),
673
+ contentDigest: rrsiDigest(
674
+ artifact.contentDigest,
675
+ "artifact content digest",
676
+ ),
677
+ bytes: rrsiInteger(
678
+ artifact.bytes,
679
+ "artifact bytes",
680
+ 1,
681
+ campaign.policy.limits.maxArtifactBytes,
682
+ ),
683
+ workflowNodes: rrsiInteger(
684
+ artifact.workflowNodes,
685
+ "workflow nodes",
686
+ 0,
687
+ 1000,
688
+ ),
689
+ };
690
+ })
691
+ .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
692
+ if (
693
+ artifacts.reduce((total, artifact) => total + artifact.bytes, 0) >
694
+ campaign.policy.limits.maxArtifactBytes
695
+ )
696
+ rrsiFail("candidate exceeds its artifact byte limit");
697
+ const contentDigest = rrsiHash("chainlesschain.rrsi-candidate-content/v1", {
698
+ kind: value.kind,
699
+ targetId: value.targetId,
700
+ artifacts: artifacts.map(({ path, contentDigest }) => ({
701
+ path,
702
+ contentDigest,
703
+ })),
704
+ });
705
+ return rrsiEnvelope(RRSI_CANDIDATE_SCHEMA, "candidateDigest", {
706
+ candidateId: rrsiId(value.candidateId, "candidateId"),
707
+ parentReleaseDigest: value.parentReleaseDigest,
708
+ kind: value.kind,
709
+ targetId: value.targetId,
710
+ lineageDepth: rrsiInteger(
711
+ value.lineageDepth,
712
+ "lineage depth",
713
+ 1,
714
+ campaign.policy.limits.maxLineageDepth,
715
+ ),
716
+ sourceTaskIds,
717
+ artifacts,
718
+ hypothesisDigest: rrsiDigest(value.hypothesisDigest, "hypothesis digest"),
719
+ campaignDigest: campaign.campaignDigest,
720
+ tenantId: campaign.tenantId,
721
+ policyDigest: campaign.policy.policyDigest,
722
+ datasetDigest: campaign.dataset.datasetDigest,
723
+ contentDigest,
724
+ });
725
+ }
726
+
727
+ export function verifyRrsiCandidate(campaign, candidate) {
728
+ return verifyRrsiEnvelope(
729
+ candidate,
730
+ RRSI_CANDIDATE_SCHEMA,
731
+ "candidateDigest",
732
+ CANDIDATE_KEYS,
733
+ (input) => buildRrsiCandidate(campaign, input),
734
+ [
735
+ "campaignDigest",
736
+ "tenantId",
737
+ "policyDigest",
738
+ "datasetDigest",
739
+ "contentDigest",
740
+ ],
741
+ );
742
+ }