@ixo/editor 6.33.0 → 6.35.0

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 (526) hide show
  1. package/dist/BidConfig-YLGSEIOS.js +154 -0
  2. package/dist/BidConfig-YLGSEIOS.js.map +1 -0
  3. package/dist/BidFlowDetail-U2SX5M7F.js +365 -0
  4. package/dist/BidFlowDetail-U2SX5M7F.js.map +1 -0
  5. package/dist/CalendarEventCreateConfig-J2LU6LJO.js +155 -0
  6. package/dist/CalendarEventCreateConfig-J2LU6LJO.js.map +1 -0
  7. package/dist/CalendarEventCreateFlowDetail-ZWHZWDOK.js +174 -0
  8. package/dist/CalendarEventCreateFlowDetail-ZWHZWDOK.js.map +1 -0
  9. package/dist/CalendarEventListConfig-GQNNF4ZB.js +116 -0
  10. package/dist/CalendarEventListConfig-GQNNF4ZB.js.map +1 -0
  11. package/dist/CalendarEventListFlowDetail-SSRTOXIX.js +58 -0
  12. package/dist/CalendarEventListFlowDetail-SSRTOXIX.js.map +1 -0
  13. package/dist/CalendarEventUpdateConfig-KACZA6GH.js +133 -0
  14. package/dist/CalendarEventUpdateConfig-KACZA6GH.js.map +1 -0
  15. package/dist/CalendarEventUpdateFlowDetail-CD6NHHOU.js +155 -0
  16. package/dist/CalendarEventUpdateFlowDetail-CD6NHHOU.js.map +1 -0
  17. package/dist/ClaimConfig-3HKPGK55.js +200 -0
  18. package/dist/ClaimConfig-3HKPGK55.js.map +1 -0
  19. package/dist/ClaimFlowDetail-I4OQSHAB.js +641 -0
  20. package/dist/ClaimFlowDetail-I4OQSHAB.js.map +1 -0
  21. package/dist/CollectionLifecycleConfig-LCCGZ3CJ.js +149 -0
  22. package/dist/CollectionLifecycleConfig-LCCGZ3CJ.js.map +1 -0
  23. package/dist/CollectionLifecycleFlowDetail-LQHKB227.js +647 -0
  24. package/dist/CollectionLifecycleFlowDetail-LQHKB227.js.map +1 -0
  25. package/dist/CollectionUsersConfig-RI2X3YY2.js +271 -0
  26. package/dist/CollectionUsersConfig-RI2X3YY2.js.map +1 -0
  27. package/dist/CollectionUsersFlowDetail-LHXVCCPQ.js +1276 -0
  28. package/dist/CollectionUsersFlowDetail-LHXVCCPQ.js.map +1 -0
  29. package/dist/CredentialStoreConfig-G66AQDGZ.js +75 -0
  30. package/dist/CredentialStoreConfig-G66AQDGZ.js.map +1 -0
  31. package/dist/CredentialStoreFlowDetail-FL7QAM3S.js +99 -0
  32. package/dist/CredentialStoreFlowDetail-FL7QAM3S.js.map +1 -0
  33. package/dist/DesignPodConfig-LJ7H2CZ6.js +8 -0
  34. package/dist/DesignPodConfig-LJ7H2CZ6.js.map +1 -0
  35. package/dist/DesignPodFlowDetail-JHJWGNVY.js +309 -0
  36. package/dist/DesignPodFlowDetail-JHJWGNVY.js.map +1 -0
  37. package/dist/DomainCardPreviewConfig-Q3X5M4WF.js +37 -0
  38. package/dist/DomainCardPreviewConfig-Q3X5M4WF.js.map +1 -0
  39. package/dist/DomainCardPreviewFlowDetail-Y2FE7O5Z.js +131 -0
  40. package/dist/DomainCardPreviewFlowDetail-Y2FE7O5Z.js.map +1 -0
  41. package/dist/DomainIndexerLookupConfig-N4VONQUY.js +41 -0
  42. package/dist/DomainIndexerLookupConfig-N4VONQUY.js.map +1 -0
  43. package/dist/DomainIndexerLookupFlowDetail-GJ7WWK7I.js +70 -0
  44. package/dist/DomainIndexerLookupFlowDetail-GJ7WWK7I.js.map +1 -0
  45. package/dist/DomainSignConfig-XFIXROVK.js +47 -0
  46. package/dist/DomainSignConfig-XFIXROVK.js.map +1 -0
  47. package/dist/DomainSignFlowDetail-BXZ6JBPR.js +206 -0
  48. package/dist/DomainSignFlowDetail-BXZ6JBPR.js.map +1 -0
  49. package/dist/DomainSingleSelectionConfig-ZNKIXB4P.js +101 -0
  50. package/dist/DomainSingleSelectionConfig-ZNKIXB4P.js.map +1 -0
  51. package/dist/DomainSingleSelectionFlowDetail-HWTQXSLA.js +147 -0
  52. package/dist/DomainSingleSelectionFlowDetail-HWTQXSLA.js.map +1 -0
  53. package/dist/EmailSendConfig-YEGZ5Q77.js +215 -0
  54. package/dist/EmailSendConfig-YEGZ5Q77.js.map +1 -0
  55. package/dist/EntityCreateOracleConfig-UZ6ZIMP5.js +150 -0
  56. package/dist/EntityCreateOracleConfig-UZ6ZIMP5.js.map +1 -0
  57. package/dist/EntityCreateOracleFlowDetail-H2X7CPYU.js +120 -0
  58. package/dist/EntityCreateOracleFlowDetail-H2X7CPYU.js.map +1 -0
  59. package/dist/EntitySingleSelectionConfig-DL57KNKM.js +30 -0
  60. package/dist/EntitySingleSelectionConfig-DL57KNKM.js.map +1 -0
  61. package/dist/EntitySingleSelectionFlowDetail-GFQGX3GA.js +118 -0
  62. package/dist/EntitySingleSelectionFlowDetail-GFQGX3GA.js.map +1 -0
  63. package/dist/EntityTransferConfig-JVZ3H35B.js +62 -0
  64. package/dist/EntityTransferConfig-JVZ3H35B.js.map +1 -0
  65. package/dist/EntityTransferFlowDetail-XEXM34XB.js +132 -0
  66. package/dist/EntityTransferFlowDetail-XEXM34XB.js.map +1 -0
  67. package/dist/EvalEngineConfig-CHC4IRN3.js +464 -0
  68. package/dist/EvalEngineConfig-CHC4IRN3.js.map +1 -0
  69. package/dist/EvalEngineFlowDetail-PUFRNO4U.js +4291 -0
  70. package/dist/EvalEngineFlowDetail-PUFRNO4U.js.map +1 -0
  71. package/dist/EvaluateBidConfig-OE4CM43G.js +151 -0
  72. package/dist/EvaluateBidConfig-OE4CM43G.js.map +1 -0
  73. package/dist/EvaluateBidFlowDetail-2EXGNBYC.js +564 -0
  74. package/dist/EvaluateBidFlowDetail-2EXGNBYC.js.map +1 -0
  75. package/dist/EvaluateClaimConfig-3D4F5LHU.js +297 -0
  76. package/dist/EvaluateClaimConfig-3D4F5LHU.js.map +1 -0
  77. package/dist/EvaluateClaimFlowDetail-QKHJVEDE.js +2237 -0
  78. package/dist/EvaluateClaimFlowDetail-QKHJVEDE.js.map +1 -0
  79. package/dist/FormSubmitConfig-UFZYMLUN.js +59 -0
  80. package/dist/FormSubmitConfig-UFZYMLUN.js.map +1 -0
  81. package/dist/FormSubmitFlowDetail-IAHDJS6P.js +169 -0
  82. package/dist/FormSubmitFlowDetail-IAHDJS6P.js.map +1 -0
  83. package/dist/GovernanceAuthzExecFlowDetail-SQBGU5BX.js +166 -0
  84. package/dist/GovernanceAuthzExecFlowDetail-SQBGU5BX.js.map +1 -0
  85. package/dist/GovernanceAuthzGrantFlowDetail-DZPNLANT.js +88 -0
  86. package/dist/GovernanceAuthzGrantFlowDetail-DZPNLANT.js.map +1 -0
  87. package/dist/GovernanceAuthzRevokeFlowDetail-3JZ4IUJG.js +88 -0
  88. package/dist/GovernanceAuthzRevokeFlowDetail-3JZ4IUJG.js.map +1 -0
  89. package/dist/GovernanceChainVoteFlowDetail-475UDNG6.js +83 -0
  90. package/dist/GovernanceChainVoteFlowDetail-475UDNG6.js.map +1 -0
  91. package/dist/GovernanceConfigConfig-V3WM4WBP.js +30 -0
  92. package/dist/GovernanceConfigConfig-V3WM4WBP.js.map +1 -0
  93. package/dist/GovernanceConfigFlowDetail-SQ5PPDRX.js +267 -0
  94. package/dist/GovernanceConfigFlowDetail-SQ5PPDRX.js.map +1 -0
  95. package/dist/GovernanceContractExecuteFlowDetail-H2ZV6W2E.js +113 -0
  96. package/dist/GovernanceContractExecuteFlowDetail-H2ZV6W2E.js.map +1 -0
  97. package/dist/GovernanceContractInstantiateFlowDetail-YJJMGM54.js +144 -0
  98. package/dist/GovernanceContractInstantiateFlowDetail-YJJMGM54.js.map +1 -0
  99. package/dist/GovernanceContractManageCw20FlowDetail-OCBMW3YJ.js +72 -0
  100. package/dist/GovernanceContractManageCw20FlowDetail-OCBMW3YJ.js.map +1 -0
  101. package/dist/GovernanceContractMigrateFlowDetail-JDNIKTT3.js +104 -0
  102. package/dist/GovernanceContractMigrateFlowDetail-JDNIKTT3.js.map +1 -0
  103. package/dist/GovernanceContractUpdateAdminFlowDetail-SZBOAOCC.js +68 -0
  104. package/dist/GovernanceContractUpdateAdminFlowDetail-SZBOAOCC.js.map +1 -0
  105. package/dist/GovernanceCustomMessageFlowDetail-CXD4ZATO.js +78 -0
  106. package/dist/GovernanceCustomMessageFlowDetail-CXD4ZATO.js.map +1 -0
  107. package/dist/GovernanceDaoAcceptToMarketplaceFlowDetail-Q6ZBNY7Z.js +98 -0
  108. package/dist/GovernanceDaoAcceptToMarketplaceFlowDetail-Q6ZBNY7Z.js.map +1 -0
  109. package/dist/GovernanceDaoAdminExecFlowDetail-JAEAY2US.js +94 -0
  110. package/dist/GovernanceDaoAdminExecFlowDetail-JAEAY2US.js.map +1 -0
  111. package/dist/GovernanceDaoCreateEntityFlowDetail-7RVNTVAB.js +96 -0
  112. package/dist/GovernanceDaoCreateEntityFlowDetail-7RVNTVAB.js.map +1 -0
  113. package/dist/GovernanceDaoJoinFlowDetail-XYCTCNHO.js +68 -0
  114. package/dist/GovernanceDaoJoinFlowDetail-XYCTCNHO.js.map +1 -0
  115. package/dist/GovernanceDaoManageStorageFlowDetail-LMLYLYYC.js +93 -0
  116. package/dist/GovernanceDaoManageStorageFlowDetail-LMLYLYYC.js.map +1 -0
  117. package/dist/GovernanceDaoManageSubDaosFlowDetail-YUFQ67JN.js +84 -0
  118. package/dist/GovernanceDaoManageSubDaosFlowDetail-YUFQ67JN.js.map +1 -0
  119. package/dist/GovernanceDaoUpdateInfoFlowDetail-G5FIBY4L.js +104 -0
  120. package/dist/GovernanceDaoUpdateInfoFlowDetail-G5FIBY4L.js.map +1 -0
  121. package/dist/GovernanceMemberProposalConfig-IGPXEFDB.js +42 -0
  122. package/dist/GovernanceMemberProposalConfig-IGPXEFDB.js.map +1 -0
  123. package/dist/GovernanceMemberProposalFlowDetail-T3VURONF.js +240 -0
  124. package/dist/GovernanceMemberProposalFlowDetail-T3VURONF.js.map +1 -0
  125. package/dist/GovernanceNftBurnFlowDetail-AG4I2O7H.js +69 -0
  126. package/dist/GovernanceNftBurnFlowDetail-AG4I2O7H.js.map +1 -0
  127. package/dist/GovernanceNftManageCollectionsFlowDetail-UAAGO3Q6.js +71 -0
  128. package/dist/GovernanceNftManageCollectionsFlowDetail-UAAGO3Q6.js.map +1 -0
  129. package/dist/GovernanceNftTransferFlowDetail-KXM7DTOV.js +130 -0
  130. package/dist/GovernanceNftTransferFlowDetail-KXM7DTOV.js.map +1 -0
  131. package/dist/GovernanceSettingsProposalConfig-4SLJTBLW.js +42 -0
  132. package/dist/GovernanceSettingsProposalConfig-4SLJTBLW.js.map +1 -0
  133. package/dist/GovernanceSettingsProposalFlowDetail-VFZPSCLR.js +165 -0
  134. package/dist/GovernanceSettingsProposalFlowDetail-VFZPSCLR.js.map +1 -0
  135. package/dist/GovernanceStakingStakeFlowDetail-ULLJ7FLM.js +123 -0
  136. package/dist/GovernanceStakingStakeFlowDetail-ULLJ7FLM.js.map +1 -0
  137. package/dist/GovernanceStakingStakeToGroupFlowDetail-CSPKJA3H.js +84 -0
  138. package/dist/GovernanceStakingStakeToGroupFlowDetail-CSPKJA3H.js.map +1 -0
  139. package/dist/GovernanceSubmissionConfigProposalFlowDetail-MZCPSZF2.js +111 -0
  140. package/dist/GovernanceSubmissionConfigProposalFlowDetail-MZCPSZF2.js.map +1 -0
  141. package/dist/GovernanceTransactionMintFlowDetail-Y2WRAODH.js +66 -0
  142. package/dist/GovernanceTransactionMintFlowDetail-Y2WRAODH.js.map +1 -0
  143. package/dist/GovernanceTransactionPerformTokenSwapFlowDetail-GEK6PMMI.js +133 -0
  144. package/dist/GovernanceTransactionPerformTokenSwapFlowDetail-GEK6PMMI.js.map +1 -0
  145. package/dist/GovernanceTransactionSendFundsConfig-VBKMLSF3.js +42 -0
  146. package/dist/GovernanceTransactionSendFundsConfig-VBKMLSF3.js.map +1 -0
  147. package/dist/GovernanceTransactionSendFundsFlowDetail-5TZB64VL.js +182 -0
  148. package/dist/GovernanceTransactionSendFundsFlowDetail-5TZB64VL.js.map +1 -0
  149. package/dist/GovernanceTransactionSendGroupTokenFlowDetail-EGOWVZM2.js +155 -0
  150. package/dist/GovernanceTransactionSendGroupTokenFlowDetail-EGOWVZM2.js.map +1 -0
  151. package/dist/GovernanceTransactionWithdrawTokenSwapFlowDetail-6XWVO5O6.js +56 -0
  152. package/dist/GovernanceTransactionWithdrawTokenSwapFlowDetail-6XWVO5O6.js.map +1 -0
  153. package/dist/GovernanceValidatorActionsFlowDetail-ZMLPAFUB.js +117 -0
  154. package/dist/GovernanceValidatorActionsFlowDetail-ZMLPAFUB.js.map +1 -0
  155. package/dist/HarvestConfig-AIGOGBFR.js +56 -0
  156. package/dist/HarvestConfig-AIGOGBFR.js.map +1 -0
  157. package/dist/HarvestFlowDetail-X3RUH3X3.js +131 -0
  158. package/dist/HarvestFlowDetail-X3RUH3X3.js.map +1 -0
  159. package/dist/HttpRequestConfig-OQEJIIJY.js +194 -0
  160. package/dist/HttpRequestConfig-OQEJIIJY.js.map +1 -0
  161. package/dist/HttpRequestFlowDetail-JVLV533Z.js +116 -0
  162. package/dist/HttpRequestFlowDetail-JVLV533Z.js.map +1 -0
  163. package/dist/IdentityCreateConfig-ZBUOJ6AL.js +94 -0
  164. package/dist/IdentityCreateConfig-ZBUOJ6AL.js.map +1 -0
  165. package/dist/IdentityCreateFlowDetail-4TE6UCEB.js +83 -0
  166. package/dist/IdentityCreateFlowDetail-4TE6UCEB.js.map +1 -0
  167. package/dist/IidCreateConfig-RRV2DYXI.js +75 -0
  168. package/dist/IidCreateConfig-RRV2DYXI.js.map +1 -0
  169. package/dist/IidCreateFlowDetail-HPVZAHVY.js +57 -0
  170. package/dist/IidCreateFlowDetail-HPVZAHVY.js.map +1 -0
  171. package/dist/KycVerifyConfig-VCG65K5K.js +65 -0
  172. package/dist/KycVerifyConfig-VCG65K5K.js.map +1 -0
  173. package/dist/KycVerifyFlowDetail-FEU43HML.js +421 -0
  174. package/dist/KycVerifyFlowDetail-FEU43HML.js.map +1 -0
  175. package/dist/ListDomainFlowsConfig-3JZEPTOJ.js +37 -0
  176. package/dist/ListDomainFlowsConfig-3JZEPTOJ.js.map +1 -0
  177. package/dist/ListDomainFlowsFlowDetail-XX5AXDZZ.js +257 -0
  178. package/dist/ListDomainFlowsFlowDetail-XX5AXDZZ.js.map +1 -0
  179. package/dist/LoadBatchesConfig-IMODIWRT.js +38 -0
  180. package/dist/LoadBatchesConfig-IMODIWRT.js.map +1 -0
  181. package/dist/LoadBatchesFlowDetail-GB24T76O.js +101 -0
  182. package/dist/LoadBatchesFlowDetail-GB24T76O.js.map +1 -0
  183. package/dist/MatrixDmConfig-NBII27CS.js +120 -0
  184. package/dist/MatrixDmConfig-NBII27CS.js.map +1 -0
  185. package/dist/MatrixRegisterConfig-N2U4FBYF.js +62 -0
  186. package/dist/MatrixRegisterConfig-N2U4FBYF.js.map +1 -0
  187. package/dist/MatrixRegisterFlowDetail-D5YNL5QX.js +86 -0
  188. package/dist/MatrixRegisterFlowDetail-D5YNL5QX.js.map +1 -0
  189. package/dist/MemberMultiSelectConfig-E7WUB2WD.js +30 -0
  190. package/dist/MemberMultiSelectConfig-E7WUB2WD.js.map +1 -0
  191. package/dist/MemberMultiSelectFlowDetail-6C4ZMSDR.js +392 -0
  192. package/dist/MemberMultiSelectFlowDetail-6C4ZMSDR.js.map +1 -0
  193. package/dist/OracleConfig-R7TDTTKN.js +56 -0
  194. package/dist/OracleConfig-R7TDTTKN.js.map +1 -0
  195. package/dist/OracleConfigureOracleConfig-QFF74X3N.js +198 -0
  196. package/dist/OracleConfigureOracleConfig-QFF74X3N.js.map +1 -0
  197. package/dist/OracleConfigureOracleFlowDetail-MIBXUEKC.js +255 -0
  198. package/dist/OracleConfigureOracleFlowDetail-MIBXUEKC.js.map +1 -0
  199. package/dist/OracleContractConfig-PHY5L7W2.js +38 -0
  200. package/dist/OracleContractConfig-PHY5L7W2.js.map +1 -0
  201. package/dist/OracleContractFlowDetail-M3PM4AU4.js +78 -0
  202. package/dist/OracleContractFlowDetail-M3PM4AU4.js.map +1 -0
  203. package/dist/OracleDeployConfig-QBG76ATZ.js +10 -0
  204. package/dist/OracleDeployConfig-QBG76ATZ.js.map +1 -0
  205. package/dist/OracleDeployFlowDetail-WKTMD2AD.js +231 -0
  206. package/dist/OracleDeployFlowDetail-WKTMD2AD.js.map +1 -0
  207. package/dist/OracleDeploySetupConfig-75XPGFJQ.js +10 -0
  208. package/dist/OracleDeploySetupConfig-75XPGFJQ.js.map +1 -0
  209. package/dist/OracleDeploySetupFlowDetail-R3BQ7EAU.js +165 -0
  210. package/dist/OracleDeploySetupFlowDetail-R3BQ7EAU.js.map +1 -0
  211. package/dist/OracleDeployStartConfig-NA6GZ4VQ.js +10 -0
  212. package/dist/OracleDeployStartConfig-NA6GZ4VQ.js.map +1 -0
  213. package/dist/OracleDeployStartFlowDetail-EL3CMDMG.js +89 -0
  214. package/dist/OracleDeployStartFlowDetail-EL3CMDMG.js.map +1 -0
  215. package/dist/OracleFlowDetail-5JCJK3GH.js +76 -0
  216. package/dist/OracleFlowDetail-5JCJK3GH.js.map +1 -0
  217. package/dist/OraclePromptConfig-YBRESISH.js +39 -0
  218. package/dist/OraclePromptConfig-YBRESISH.js.map +1 -0
  219. package/dist/OraclePromptFlowDetail-O3XNK7HY.js +112 -0
  220. package/dist/OraclePromptFlowDetail-O3XNK7HY.js.map +1 -0
  221. package/dist/OracleStoreConfigConfig-TUZWTJMA.js +134 -0
  222. package/dist/OracleStoreConfigConfig-TUZWTJMA.js.map +1 -0
  223. package/dist/OracleStoreConfigFlowDetail-Q6AUUSUL.js +99 -0
  224. package/dist/OracleStoreConfigFlowDetail-Q6AUUSUL.js.map +1 -0
  225. package/dist/OracleStoreSecretsAndConfigConfig-SZPYEK7U.js +198 -0
  226. package/dist/OracleStoreSecretsAndConfigConfig-SZPYEK7U.js.map +1 -0
  227. package/dist/OracleStoreSecretsAndConfigFlowDetail-HQU3UKEB.js +220 -0
  228. package/dist/OracleStoreSecretsAndConfigFlowDetail-HQU3UKEB.js.map +1 -0
  229. package/dist/OracleStoreSecretsConfig-PQMF7LFT.js +191 -0
  230. package/dist/OracleStoreSecretsConfig-PQMF7LFT.js.map +1 -0
  231. package/dist/OracleStoreSecretsFlowDetail-5RXWQ3KA.js +197 -0
  232. package/dist/OracleStoreSecretsFlowDetail-5RXWQ3KA.js.map +1 -0
  233. package/dist/ProposalCreateConfig-U5IHZNT7.js +161 -0
  234. package/dist/ProposalCreateConfig-U5IHZNT7.js.map +1 -0
  235. package/dist/ProposalCreateFlowDetail-2FCRCNYV.js +235 -0
  236. package/dist/ProposalCreateFlowDetail-2FCRCNYV.js.map +1 -0
  237. package/dist/ProposalVoteConfig-MH4MU7SL.js +150 -0
  238. package/dist/ProposalVoteConfig-MH4MU7SL.js.map +1 -0
  239. package/dist/ProposalVoteFlowDetail-IJJ3OHAB.js +280 -0
  240. package/dist/ProposalVoteFlowDetail-IJJ3OHAB.js.map +1 -0
  241. package/dist/ProtocolSelectConfig-S5U3P6K7.js +48 -0
  242. package/dist/ProtocolSelectConfig-S5U3P6K7.js.map +1 -0
  243. package/dist/ProtocolSelectFlowDetail-XBSJIEIH.js +116 -0
  244. package/dist/ProtocolSelectFlowDetail-XBSJIEIH.js.map +1 -0
  245. package/dist/RetireConfig-MV37WWZ6.js +59 -0
  246. package/dist/RetireConfig-MV37WWZ6.js.map +1 -0
  247. package/dist/RetireFlowDetail-VZ5O4SXI.js +147 -0
  248. package/dist/RetireFlowDetail-VZ5O4SXI.js.map +1 -0
  249. package/dist/SandboxProvisionConfig-ZGG4IRHM.js +46 -0
  250. package/dist/SandboxProvisionConfig-ZGG4IRHM.js.map +1 -0
  251. package/dist/SandboxProvisionFlowDetail-RUY64INV.js +79 -0
  252. package/dist/SandboxProvisionFlowDetail-RUY64INV.js.map +1 -0
  253. package/dist/WalletFundConfig-CMM3EP3B.js +117 -0
  254. package/dist/WalletFundConfig-CMM3EP3B.js.map +1 -0
  255. package/dist/WalletFundFlowDetail-TXWCZA4K.js +279 -0
  256. package/dist/WalletFundFlowDetail-TXWCZA4K.js.map +1 -0
  257. package/dist/WalletGenerateAndFundConfig-364RSEND.js +10 -0
  258. package/dist/WalletGenerateAndFundConfig-364RSEND.js.map +1 -0
  259. package/dist/WalletGenerateAndFundFlowDetail-C2LZW3NO.js +54 -0
  260. package/dist/WalletGenerateAndFundFlowDetail-C2LZW3NO.js.map +1 -0
  261. package/dist/WalletGenerateConfig-YYLCS65G.js +10 -0
  262. package/dist/WalletGenerateConfig-YYLCS65G.js.map +1 -0
  263. package/dist/WalletGenerateFlowDetail-CQCNDGJA.js +53 -0
  264. package/dist/WalletGenerateFlowDetail-CQCNDGJA.js.map +1 -0
  265. package/dist/XeroContactCreateConfig-OWG5PA3B.js +102 -0
  266. package/dist/XeroContactCreateConfig-OWG5PA3B.js.map +1 -0
  267. package/dist/XeroContactCreateFlowDetail-6MAINCF6.js +127 -0
  268. package/dist/XeroContactCreateFlowDetail-6MAINCF6.js.map +1 -0
  269. package/dist/XeroInvoiceCreateConfig-O74RUSZM.js +403 -0
  270. package/dist/XeroInvoiceCreateConfig-O74RUSZM.js.map +1 -0
  271. package/dist/XeroInvoiceCreateFlowDetail-UL7KS6CZ.js +631 -0
  272. package/dist/XeroInvoiceCreateFlowDetail-UL7KS6CZ.js.map +1 -0
  273. package/dist/XeroInvoiceListConfig-UR3GONBJ.js +113 -0
  274. package/dist/XeroInvoiceListConfig-UR3GONBJ.js.map +1 -0
  275. package/dist/XeroInvoiceListFlowDetail-LYHODWH6.js +58 -0
  276. package/dist/XeroInvoiceListFlowDetail-LYHODWH6.js.map +1 -0
  277. package/dist/XeroPaymentCreateConfig-RPMAIK6E.js +116 -0
  278. package/dist/XeroPaymentCreateConfig-RPMAIK6E.js.map +1 -0
  279. package/dist/XeroPaymentCreateFlowDetail-CF35MVIM.js +573 -0
  280. package/dist/XeroPaymentCreateFlowDetail-CF35MVIM.js.map +1 -0
  281. package/dist/action-manifest.json +2091 -393
  282. package/dist/chunk-2GAYKKTL.js +9 -0
  283. package/dist/chunk-2GAYKKTL.js.map +1 -0
  284. package/dist/chunk-3TUYY4HK.js +20 -0
  285. package/dist/chunk-3TUYY4HK.js.map +1 -0
  286. package/dist/chunk-4DGCCXD6.js +710 -0
  287. package/dist/chunk-4DGCCXD6.js.map +1 -0
  288. package/dist/chunk-4NAFQF6V.js +11 -0
  289. package/dist/chunk-4NAFQF6V.js.map +1 -0
  290. package/dist/chunk-4PONO4US.js +799 -0
  291. package/dist/chunk-4PONO4US.js.map +1 -0
  292. package/dist/chunk-4TMOIK5M.js +21 -0
  293. package/dist/chunk-4TMOIK5M.js.map +1 -0
  294. package/dist/chunk-5E6Z6JJN.js +4456 -0
  295. package/dist/chunk-5E6Z6JJN.js.map +1 -0
  296. package/dist/chunk-5IH3VC5I.js +102 -0
  297. package/dist/chunk-5IH3VC5I.js.map +1 -0
  298. package/dist/chunk-5NTKDOP6.js +89 -0
  299. package/dist/chunk-5NTKDOP6.js.map +1 -0
  300. package/dist/chunk-5O2SFRGU.js +18 -0
  301. package/dist/chunk-5O2SFRGU.js.map +1 -0
  302. package/dist/chunk-632JLECF.js +55 -0
  303. package/dist/chunk-632JLECF.js.map +1 -0
  304. package/dist/chunk-676HDB7K.js +95 -0
  305. package/dist/chunk-676HDB7K.js.map +1 -0
  306. package/dist/chunk-6ESTNTSH.js +223 -0
  307. package/dist/chunk-6ESTNTSH.js.map +1 -0
  308. package/dist/chunk-6GKJR52N.js +15 -0
  309. package/dist/chunk-6GKJR52N.js.map +1 -0
  310. package/dist/chunk-6L4ZIKYU.js +23 -0
  311. package/dist/chunk-6L4ZIKYU.js.map +1 -0
  312. package/dist/chunk-76YX5R4L.js +11 -0
  313. package/dist/chunk-76YX5R4L.js.map +1 -0
  314. package/dist/chunk-7J3GFMN3.js +32 -0
  315. package/dist/chunk-7J3GFMN3.js.map +1 -0
  316. package/dist/chunk-7LSARC2G.js +102 -0
  317. package/dist/chunk-7LSARC2G.js.map +1 -0
  318. package/dist/chunk-7W7UUUIE.js +609 -0
  319. package/dist/chunk-7W7UUUIE.js.map +1 -0
  320. package/dist/chunk-7ZLW7H37.js +21 -0
  321. package/dist/chunk-7ZLW7H37.js.map +1 -0
  322. package/dist/chunk-AAZHI22G.js +18 -0
  323. package/dist/chunk-AAZHI22G.js.map +1 -0
  324. package/dist/chunk-ACNE455I.js +76 -0
  325. package/dist/chunk-ACNE455I.js.map +1 -0
  326. package/dist/chunk-BKLSSLPZ.js +27 -0
  327. package/dist/chunk-BKLSSLPZ.js.map +1 -0
  328. package/dist/chunk-BZ7UPUTY.js +417 -0
  329. package/dist/chunk-BZ7UPUTY.js.map +1 -0
  330. package/dist/chunk-CGFAICUE.js +28 -0
  331. package/dist/chunk-CGFAICUE.js.map +1 -0
  332. package/dist/chunk-CMCEWQ3C.js +19 -0
  333. package/dist/chunk-CMCEWQ3C.js.map +1 -0
  334. package/dist/chunk-CP4UV436.js +41 -0
  335. package/dist/chunk-CP4UV436.js.map +1 -0
  336. package/dist/chunk-DIQRZP7Z.js +51 -0
  337. package/dist/chunk-DIQRZP7Z.js.map +1 -0
  338. package/dist/chunk-EBFFDDAS.js +13 -0
  339. package/dist/chunk-EBFFDDAS.js.map +1 -0
  340. package/dist/chunk-EGVS23DR.js +85 -0
  341. package/dist/chunk-EGVS23DR.js.map +1 -0
  342. package/dist/chunk-EKBQ7K4N.js +15 -0
  343. package/dist/chunk-EKBQ7K4N.js.map +1 -0
  344. package/dist/chunk-EKQCZRAN.js +24 -0
  345. package/dist/chunk-EKQCZRAN.js.map +1 -0
  346. package/dist/chunk-EYKZIZ5J.js +48 -0
  347. package/dist/chunk-EYKZIZ5J.js.map +1 -0
  348. package/dist/{chunk-NEOPTPDF.js → chunk-F4PTFXZH.js} +11554 -22046
  349. package/dist/chunk-F4PTFXZH.js.map +1 -0
  350. package/dist/chunk-F5GTFCYV.js +3333 -0
  351. package/dist/chunk-F5GTFCYV.js.map +1 -0
  352. package/dist/chunk-FFYZXA75.js +58 -0
  353. package/dist/chunk-FFYZXA75.js.map +1 -0
  354. package/dist/chunk-GFGDHPZ2.js +22 -0
  355. package/dist/chunk-GFGDHPZ2.js.map +1 -0
  356. package/dist/chunk-GR3CDFID.js +18 -0
  357. package/dist/chunk-GR3CDFID.js.map +1 -0
  358. package/dist/chunk-GR4SIU32.js +104 -0
  359. package/dist/chunk-GR4SIU32.js.map +1 -0
  360. package/dist/chunk-H5E46IIS.js +18 -0
  361. package/dist/chunk-H5E46IIS.js.map +1 -0
  362. package/dist/chunk-HFHVAMZL.js +22 -0
  363. package/dist/chunk-HFHVAMZL.js.map +1 -0
  364. package/dist/chunk-HT6L7A5M.js +12 -0
  365. package/dist/chunk-HT6L7A5M.js.map +1 -0
  366. package/dist/chunk-I2FPFISM.js +301 -0
  367. package/dist/chunk-I2FPFISM.js.map +1 -0
  368. package/dist/chunk-IADAQJDH.js +28 -0
  369. package/dist/chunk-IADAQJDH.js.map +1 -0
  370. package/dist/chunk-IBOBCMQQ.js +99 -0
  371. package/dist/chunk-IBOBCMQQ.js.map +1 -0
  372. package/dist/chunk-IFWKRCFF.js +56 -0
  373. package/dist/chunk-IFWKRCFF.js.map +1 -0
  374. package/dist/chunk-IH4T7V4C.js +40 -0
  375. package/dist/chunk-IH4T7V4C.js.map +1 -0
  376. package/dist/chunk-IIIZZ4E4.js +1679 -0
  377. package/dist/chunk-IIIZZ4E4.js.map +1 -0
  378. package/dist/chunk-ILSFU3WD.js +83 -0
  379. package/dist/chunk-ILSFU3WD.js.map +1 -0
  380. package/dist/chunk-IX3VBV3L.js +43 -0
  381. package/dist/chunk-IX3VBV3L.js.map +1 -0
  382. package/dist/chunk-JB6ASLUJ.js +315 -0
  383. package/dist/chunk-JB6ASLUJ.js.map +1 -0
  384. package/dist/chunk-JBBFSORW.js +846 -0
  385. package/dist/chunk-JBBFSORW.js.map +1 -0
  386. package/dist/chunk-JIDTNKKL.js +1183 -0
  387. package/dist/chunk-JIDTNKKL.js.map +1 -0
  388. package/dist/chunk-JSPE6NGZ.js +22 -0
  389. package/dist/chunk-JSPE6NGZ.js.map +1 -0
  390. package/dist/chunk-JVROGQ7Q.js +150 -0
  391. package/dist/chunk-JVROGQ7Q.js.map +1 -0
  392. package/dist/chunk-K4WUMWNJ.js +32 -0
  393. package/dist/chunk-K4WUMWNJ.js.map +1 -0
  394. package/dist/chunk-K74XQ4Q5.js +11 -0
  395. package/dist/chunk-K74XQ4Q5.js.map +1 -0
  396. package/dist/chunk-KLLMJ4U3.js +22 -0
  397. package/dist/chunk-KLLMJ4U3.js.map +1 -0
  398. package/dist/chunk-LTKVCJ2E.js +27 -0
  399. package/dist/chunk-LTKVCJ2E.js.map +1 -0
  400. package/dist/chunk-M36DJTFZ.js +34 -0
  401. package/dist/chunk-M36DJTFZ.js.map +1 -0
  402. package/dist/chunk-MHM52LCJ.js +154 -0
  403. package/dist/chunk-MHM52LCJ.js.map +1 -0
  404. package/dist/chunk-MQCDMHRZ.js +59 -0
  405. package/dist/chunk-MQCDMHRZ.js.map +1 -0
  406. package/dist/chunk-MZIBZ5FY.js +554 -0
  407. package/dist/chunk-MZIBZ5FY.js.map +1 -0
  408. package/dist/chunk-N3ORMGAI.js +348 -0
  409. package/dist/chunk-N3ORMGAI.js.map +1 -0
  410. package/dist/chunk-NCSGIRRQ.js +28 -0
  411. package/dist/chunk-NCSGIRRQ.js.map +1 -0
  412. package/dist/chunk-NIXT2SBH.js +1423 -0
  413. package/dist/chunk-NIXT2SBH.js.map +1 -0
  414. package/dist/chunk-NJAII6CO.js +148 -0
  415. package/dist/chunk-NJAII6CO.js.map +1 -0
  416. package/dist/chunk-NKE4TL43.js +92 -0
  417. package/dist/chunk-NKE4TL43.js.map +1 -0
  418. package/dist/chunk-NZ7AXA7B.js +1 -0
  419. package/dist/chunk-NZ7AXA7B.js.map +1 -0
  420. package/dist/chunk-OCAYEGI2.js +26 -0
  421. package/dist/chunk-OCAYEGI2.js.map +1 -0
  422. package/dist/chunk-OMLI45ER.js +90 -0
  423. package/dist/chunk-OMLI45ER.js.map +1 -0
  424. package/dist/chunk-P7OBLJAG.js +88 -0
  425. package/dist/chunk-P7OBLJAG.js.map +1 -0
  426. package/dist/chunk-PAY3CBWL.js +2321 -0
  427. package/dist/chunk-PAY3CBWL.js.map +1 -0
  428. package/dist/chunk-PFF6VY35.js +257 -0
  429. package/dist/chunk-PFF6VY35.js.map +1 -0
  430. package/dist/chunk-PYNDJDWZ.js +1758 -0
  431. package/dist/chunk-PYNDJDWZ.js.map +1 -0
  432. package/dist/chunk-QDQ6UMMN.js +53 -0
  433. package/dist/chunk-QDQ6UMMN.js.map +1 -0
  434. package/dist/chunk-QGT3G2XG.js +24 -0
  435. package/dist/chunk-QGT3G2XG.js.map +1 -0
  436. package/dist/chunk-QZYCJ2GZ.js +55 -0
  437. package/dist/chunk-QZYCJ2GZ.js.map +1 -0
  438. package/dist/chunk-REZ7RFSA.js +124 -0
  439. package/dist/chunk-REZ7RFSA.js.map +1 -0
  440. package/dist/chunk-RRYBAE6E.js +2449 -0
  441. package/dist/chunk-RRYBAE6E.js.map +1 -0
  442. package/dist/chunk-RWUZOB62.js +34 -0
  443. package/dist/chunk-RWUZOB62.js.map +1 -0
  444. package/dist/chunk-SB5UCPZH.js +116 -0
  445. package/dist/chunk-SB5UCPZH.js.map +1 -0
  446. package/dist/chunk-SEJJ7CRI.js +99 -0
  447. package/dist/chunk-SEJJ7CRI.js.map +1 -0
  448. package/dist/chunk-SHBFGRPV.js +45 -0
  449. package/dist/chunk-SHBFGRPV.js.map +1 -0
  450. package/dist/chunk-SOFJ4GC5.js +45 -0
  451. package/dist/chunk-SOFJ4GC5.js.map +1 -0
  452. package/dist/chunk-STH2HPZK.js +44 -0
  453. package/dist/chunk-STH2HPZK.js.map +1 -0
  454. package/dist/chunk-TK3JNKME.js +28 -0
  455. package/dist/chunk-TK3JNKME.js.map +1 -0
  456. package/dist/chunk-TMONHFE3.js +46 -0
  457. package/dist/chunk-TMONHFE3.js.map +1 -0
  458. package/dist/chunk-TR4KO3AG.js +44 -0
  459. package/dist/chunk-TR4KO3AG.js.map +1 -0
  460. package/dist/chunk-TS2LNBF2.js +68 -0
  461. package/dist/chunk-TS2LNBF2.js.map +1 -0
  462. package/dist/chunk-UZUMBFPP.js +26 -0
  463. package/dist/chunk-UZUMBFPP.js.map +1 -0
  464. package/dist/chunk-VRZ5LMOW.js +176 -0
  465. package/dist/chunk-VRZ5LMOW.js.map +1 -0
  466. package/dist/chunk-WLGGY6Z6.js +75 -0
  467. package/dist/chunk-WLGGY6Z6.js.map +1 -0
  468. package/dist/chunk-WO7V6ZNC.js +11 -0
  469. package/dist/chunk-WO7V6ZNC.js.map +1 -0
  470. package/dist/chunk-WXSENSRP.js +64 -0
  471. package/dist/chunk-WXSENSRP.js.map +1 -0
  472. package/dist/chunk-XEKBZ2SA.js +19 -0
  473. package/dist/chunk-XEKBZ2SA.js.map +1 -0
  474. package/dist/chunk-XPBKU3JX.js +61 -0
  475. package/dist/chunk-XPBKU3JX.js.map +1 -0
  476. package/dist/chunk-XRYXBXWH.js +24 -0
  477. package/dist/chunk-XRYXBXWH.js.map +1 -0
  478. package/dist/chunk-XVA7QRVH.js +22 -0
  479. package/dist/chunk-XVA7QRVH.js.map +1 -0
  480. package/dist/chunk-XYXDY72K.js +27508 -0
  481. package/dist/chunk-XYXDY72K.js.map +1 -0
  482. package/dist/chunk-YCTHHBSS.js +37 -0
  483. package/dist/chunk-YCTHHBSS.js.map +1 -0
  484. package/dist/chunk-YHPWD5NE.js +70 -0
  485. package/dist/chunk-YHPWD5NE.js.map +1 -0
  486. package/dist/chunk-YLNEKJQ5.js +126 -0
  487. package/dist/chunk-YLNEKJQ5.js.map +1 -0
  488. package/dist/chunk-YN4CEKCF.js +73 -0
  489. package/dist/chunk-YN4CEKCF.js.map +1 -0
  490. package/dist/chunk-YYNMESIF.js +17 -0
  491. package/dist/chunk-YYNMESIF.js.map +1 -0
  492. package/dist/chunk-Z6PRMCV6.js +1 -0
  493. package/dist/chunk-Z6PRMCV6.js.map +1 -0
  494. package/dist/chunk-ZDNW6VQG.js +11 -0
  495. package/dist/chunk-ZDNW6VQG.js.map +1 -0
  496. package/dist/chunk-ZP4D73DO.js +36 -0
  497. package/dist/chunk-ZP4D73DO.js.map +1 -0
  498. package/dist/chunk-ZUATADUV.js +26 -0
  499. package/dist/chunk-ZUATADUV.js.map +1 -0
  500. package/dist/{connections-1NtNQrsY.d.ts → connections-CEcurtWI.d.ts} +74 -9
  501. package/dist/core/index.cjs +14041 -6973
  502. package/dist/core/index.cjs.map +1 -1
  503. package/dist/core/index.d.ts +422 -138
  504. package/dist/core/index.js +425 -183
  505. package/dist/core/index.js.map +1 -1
  506. package/dist/flow-vnext/index.cjs +2842 -0
  507. package/dist/flow-vnext/index.cjs.map +1 -0
  508. package/dist/flow-vnext/index.d.ts +3 -0
  509. package/dist/flow-vnext/index.js +119 -0
  510. package/dist/flow-vnext/index.js.map +1 -0
  511. package/dist/{graphql-client-Bn0tN049.d.ts → graphql-client-B2tREsx6.d.ts} +3 -1
  512. package/dist/index-b9xxXGFs.d.ts +1230 -0
  513. package/dist/index.d.ts +5 -3
  514. package/dist/index.js +202 -37
  515. package/dist/index.js.map +1 -1
  516. package/dist/legacy-BpgIqaQ5.d.ts +14 -0
  517. package/dist/mantine/index.d.ts +7 -4
  518. package/dist/mantine/index.js +84 -30
  519. package/dist/mantine/index.js.map +1 -1
  520. package/dist/{runtime-BFwvCQDF.d.ts → types-Dqk5MTfW.d.ts} +6096 -5386
  521. package/package.json +12 -2
  522. package/dist/chunk-A4CWC4AG.js +0 -374
  523. package/dist/chunk-A4CWC4AG.js.map +0 -1
  524. package/dist/chunk-NEOPTPDF.js.map +0 -1
  525. package/dist/chunk-VRCRDKN5.js +0 -59694
  526. package/dist/chunk-VRCRDKN5.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mantine/blocks/action/actionTypes/evalEngine/EvalEngineFlowDetail.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/AdvancedPanel.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ApprovalPolicy.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/phrases.ts","../src/mantine/blocks/action/actionTypes/evalRubric/ruleModel.ts","../src/mantine/blocks/action/actionTypes/evalRubric/policyModel.ts","../src/mantine/blocks/action/actionTypes/evalRubric/rubricStyles.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/LinkedRuleEditor.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ValueInput.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ruleDraft.ts","../src/mantine/blocks/action/actionTypes/evalRubric/RuleCard.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/RuleEditor.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/AiCheckInline.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ConditionRow.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ExternalCheckInline.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/ReviewTaskEditor.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/templates.ts","../src/mantine/blocks/action/actionTypes/evalRubric/FrequencyRule.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/frequencyModel.ts","../src/mantine/blocks/action/actionTypes/evalRubric/UniqueRule.tsx","../src/mantine/blocks/action/actionTypes/evalRubric/uniqueModel.ts","../src/mantine/blocks/action/actionTypes/evalRubric/useRubricDraft.ts"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ActionIcon, Alert, Badge, Box, Button, Group, Loader, Paper, Stack, Text } from '@mantine/core';\nimport { IconAlertCircle, IconAlertTriangle, IconArrowRight, IconCheck, IconInfoCircle, IconTrash } from '@tabler/icons-react';\nimport { SCHEMA_UNKNOWN_KEY_PREFIX } from '@/core/lib/actionRegistry/actions/evalRubric/schemaGate';\nimport type { RubricField } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport type { RubricProblem } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport BaseAlert from '@/mantine/components/Base/BaseAlert';\nimport { useBlocknoteHandlers } from '@/mantine/context/BlocknoteContext';\nimport { resolveReferences } from '@/mantine/utils/referenceResolver';\nimport type { ActionTypeFlowProps } from '../../actionTypeUI';\nimport { actionAlertStyles } from '../../alertStyles';\nimport { formatCapCoins } from '../evalRegister/grantCaps';\nimport { billingNote, ownerPaysLine, useEnginePricing, usdLabel } from '../evalRegister/pricing';\nimport { AdvancedPanel } from '../evalRubric/AdvancedPanel';\nimport { ApprovalPolicy } from '../evalRubric/ApprovalPolicy';\nimport { LinkedRuleEditor } from '../evalRubric/LinkedRuleEditor';\nimport { RuleCard } from '../evalRubric/RuleCard';\nimport { RuleEditor } from '../evalRubric/RuleEditor';\nimport { CONSEQUENCES, consequenceIcon, describeLinked, describeRule, describeTally, linkedSentenceOf, problemText, schemaProblemText } from '../evalRubric/phrases';\nimport { applyDraft, applyLinkedDraft, type LinkedDraft, type RuleDraft } from '../evalRubric/ruleDraft';\nimport {\n cardForDiagnosticPath,\n policyShapeOf,\n pruneDanglingSources,\n removeGatesAt,\n removeRule,\n rootPath,\n rulesByCard,\n type LinkedRule,\n type UiRule,\n} from '../evalRubric/ruleModel';\nimport { cardStyle, consequencePillStyle, quietButton, RuleSentence, SLATE } from '../evalRubric/rubricStyles';\nimport { FrequencyRule } from '../evalRubric/FrequencyRule';\nimport { UniqueRule } from '../evalRubric/UniqueRule';\nimport { useRubricDraft } from '../evalRubric/useRubricDraft';\nimport { parseEvalEngineInputs, type EvalEngineRuntimeInputs } from './types';\n\nconst LOG = '[eval.engine]';\n\nfunction truncate(value: string): string {\n if (!value) return '';\n return value.length <= 16 ? value : `${value.slice(0, 10)}…${value.slice(-4)}`;\n}\n\n/**\n * The real message inside ANY throw shape. This run anchors a chain transaction,\n * and the host handlers on that path don't only throw `Error`s — the portal's\n * `awaitTransaction` rejects with a plain STRING, SignX with a raw event OBJECT —\n * so an `instanceof Error` check alone would bury the actual failure behind a\n * generic line. The fallback is the true last resort only.\n */\nfunction failureMessageOf(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string' && error) return error;\n if (error && typeof error === 'object' && 'message' in error && (error as { message?: unknown }).message) {\n return String((error as { message: unknown }).message);\n }\n try {\n const serialized = JSON.stringify(error);\n if (serialized && serialized !== '{}' && serialized !== 'null' && serialized !== 'undefined') return serialized;\n } catch {\n // circular / unserializable — fall through\n }\n return 'Failed to enable the Evaluation Engine';\n}\n\n/**\n * Flow-mode UI for the merged \"Evaluation Engine\" block: the rules DESIGNER (the\n * same card grid as the rules block this one replaces, whose parts still live in `../evalRubric`),\n * the §B.3 pricing disclosure, and ONE slide-to-sign that enrols the collection\n * and publishes the rules in a single run.\n *\n * Three things make this different from the two blocks it replaces:\n *\n * - **The designer runs in FLOW mode**, so its writes go into `block.props.inputs`\n * through `editor.updateBlock` (the proven `CollectionLifecycleFlowDetail`\n * pattern) — and always as a MERGE, because `useRubricDraft` serializes only the\n * rubric-shaped subset of the blob and must never drop the register-side keys\n * (collection binding, billing email, the three settings, the payout cap).\n * - **No rules, no signature.** An engine enrolled with an empty rule set records\n * \"no rules\" against every claim and judges nothing, so an empty (or broken)\n * rule set keeps the slider locked rather than producing a useless enrolment.\n * - **The proof is composite**: enrolment id + published rules id + the anchor tx.\n * A run that reports success without all three did not fully land, and is\n * treated as a failure rather than shown as done.\n *\n * Author-facing vocabulary is the rules block's (§B.5 rule 1): rules, reject,\n * points, ask a person. The words rubric/gate/criterion/basis points never render.\n */\nexport const EvalEngineFlowDetail: React.FC<ActionTypeFlowProps<EvalEngineRuntimeInputs>> = ({\n inputs,\n editor,\n block,\n runtime,\n updateRuntime,\n isDisabled,\n provideSigningHandler,\n unlockSigning,\n registerRuntimeInputs,\n executeAction,\n activePendingInvocation,\n onPendingInvocationCompleted,\n}) => {\n const handlers = useBlocknoteHandlers();\n const handlersRef = useRef(handlers);\n useEffect(() => {\n handlersRef.current = handlers;\n }, [handlers]);\n\n const parsed = useMemo(() => parseEvalEngineInputs(inputs), [inputs]);\n const editorDocument = editor?.document || [];\n const resolveOpts = useMemo(() => ({ yRuntime: editor?._yRuntime }), [editor?._yRuntime]);\n\n // Template-configured context (manual mode). May be empty when this block is\n // an event listener — see `pendingPayload` below.\n const templateDeedDid = useMemo(() => resolveReferences(parsed.deedDid || '', editorDocument, resolveOpts).trim(), [parsed.deedDid, editorDocument, resolveOpts]);\n const templateCollectionId = useMemo(() => resolveReferences(parsed.collectionId || '', editorDocument, resolveOpts).trim(), [parsed.collectionId, editorDocument, resolveOpts]);\n\n // Listener mode: the collection + owning entity arrive in the frozen event\n // payload and take precedence over the template config, so the block enrols\n // exactly the collection that was just created.\n const pendingPayload = useMemo(() => {\n if (!activePendingInvocation) return undefined;\n return {\n ...(activePendingInvocation.payload || {}),\n ...(activePendingInvocation.refSnapshots || {}),\n } as Record<string, unknown>;\n }, [activePendingInvocation]);\n\n const deedDid = useMemo(() => String(pendingPayload?.entity || '').trim() || templateDeedDid, [pendingPayload, templateDeedDid]);\n const collectionId = useMemo(() => String(pendingPayload?.collectionId || '').trim() || templateCollectionId, [pendingPayload, templateCollectionId]);\n\n // Entity admin account — the granter of the evaluate-authz grant (§C). Signing\n // stays locked until it resolves; a failed lookup keeps the slider locked with\n // the waiting hint below rather than a doomed run.\n const [adminAddress, setAdminAddress] = useState('');\n useEffect(() => {\n let mounted = true;\n if (!deedDid) {\n setAdminAddress('');\n return;\n }\n (async () => {\n try {\n const addr = await handlersRef.current.getAdminAccountAddress(deedDid);\n if (mounted) setAdminAddress(String(addr || '').trim());\n } catch {\n if (mounted) setAdminAddress('');\n }\n })();\n return () => {\n mounted = false;\n };\n }, [deedDid]);\n\n // -------------------------------------------------------------------------\n // The designer, writing into the SAME blob as the template config.\n // -------------------------------------------------------------------------\n // `useRubricDraft.update()` serializes ONLY the rubric-shaped keys, so this\n // writer merges that subset over the block's current FULL blob. Replacing it\n // would wipe the register-side settings the moment the author edits a rule.\n // The base is re-read from the editor's own document rather than the `inputs`\n // prop: `updateBlock` lands in editor state synchronously, while the prop only\n // catches up on the next render, so two saves in quick succession would\n // otherwise merge over a blob that is one write stale.\n const writeInputs = useCallback(\n (rubricSubsetJson: string) => {\n const blockId = String(block?.id || '');\n if (!editor || !blockId) return;\n const current = (editor.document || []).find((candidate: { id?: string }) => candidate?.id === blockId) || block;\n let subset: Record<string, unknown> = {};\n try {\n subset = JSON.parse(rubricSubsetJson);\n } catch {\n return; // unparseable write — never clobber a good blob with it\n }\n let full: Record<string, unknown> = {};\n try {\n full = JSON.parse(String(current?.props?.inputs || '{}'));\n } catch {\n // Unreadable blob: the subset alone is still better than dropping the edit.\n }\n // Reading is not editing. Several things call `update()` with values that are\n // already there — the hook re-writes the trimmed DID every time it fetches the\n // collection list, and its serializer always emits all five of its keys — and\n // each would otherwise dirty the document just because someone opened the\n // panel. So compare CONTENT over the keys the subset actually carries, and\n // write only on a real change. A blank and an absent optional are the same\n // statement (the register serializer drops blanks), so one is not a change\n // into the other. Anything this comparison cannot settle falls through to a\n // write, which is the safe direction.\n const changed = Object.keys(subset).some((key) => {\n const before = full[key];\n const after = subset[key];\n if (before === after) return false;\n if ((before ?? '') === '' && (after ?? '') === '') return false;\n return JSON.stringify(before ?? null) !== JSON.stringify(after ?? null);\n });\n if (!changed) return;\n // ONLY `inputs`: `updateBlock` merges the props it is given, so echoing the\n // whole object back would republish every sibling prop — including one read\n // from the `block` fallback, which can be a render stale.\n editor.updateBlock(blockId, { props: { inputs: JSON.stringify({ ...full, ...subset }) } });\n },\n [editor, block]\n );\n\n // The settings the author intends to enrol with, forwarded to the engine's\n // pre-publish check so AI rules are judged truthfully BEFORE enrolment. This\n // sits in a debounced effect's dependency array inside the hook, so the\n // reference has to be stable — a fresh literal would re-fire the engine check\n // on every render instead of every edit.\n const intendedSettings = useMemo(\n () => ({ allowAiChecks: parsed.allowAiChecks, allowImageChecks: parsed.allowImageChecks, allowChainEvaluation: parsed.allowChainEvaluation }),\n [parsed.allowAiChecks, parsed.allowImageChecks, parsed.allowChainEvaluation]\n );\n\n const draft = useRubricDraft(inputs, writeInputs, { settings: intendedSettings });\n\n // The draft as it stands RIGHT NOW. `execute` below is a callback that can\n // have been built on an older render, and what it sends must be what the gate\n // armed on — not what the draft held when its closure was created.\n const draftLocalRef = useRef(draft.local);\n draftLocalRef.current = draft.local;\n\n // Listener mode: once the event payload names the collection, persist it into\n // the blob so the draft's form loader (which reads `local.deedDid`/\n // `local.collectionId`) targets the right claim form. Writes only on a real\n // difference, so it settles after one pass instead of looping.\n useEffect(() => {\n if (!pendingPayload) return;\n if (!collectionId && !deedDid) return;\n if (draft.local.collectionId === collectionId && draft.local.deedDid === deedDid) return;\n console.log(`${LOG} listener mode — pinning the event's collection into the block`, { collectionId });\n draft.update({ collectionId, deedDid });\n }, [pendingPayload, collectionId, deedDid]);\n\n // The prices this collection is actually on (billing guide §11) — cards differ\n // per relayer node, so what is signed for has to be read live rather than\n // recited from a local list. Falls back to that list if the engine is unreachable.\n const { card, live } = useEnginePricing({ collectionId, evalEngineUrl: parsed.evalEngineUrl });\n const payLine = ownerPaysLine(live);\n\n // -------------------------------------------------------------------------\n // Derived runtime state — read straight from the Y.Map each render.\n // -------------------------------------------------------------------------\n const output = (runtime.output as Record<string, any> | undefined) || undefined;\n const registrationId = String(output?.registrationId || '').trim();\n const rubricId = String(output?.rubricId || '').trim();\n const resourceTxHash = String(output?.resourceTxHash || '').trim();\n const isRunning = runtime.state === 'running';\n const isFailed = runtime.state === 'failed';\n const errorMessage = runtime.error?.message || null;\n // Proof is COMPOSITE: enrolled, rules published, and anchored. Any one missing\n // means this block did not do its job, whatever the state says.\n const isCompletedWithProof = runtime.state === 'completed' && !!registrationId && !!rubricId && !!resourceTxHash;\n const isStale = runtime.state === 'completed' && !isCompletedWithProof;\n\n const catalog = draft.local.claimSchemaSnapshot;\n const body = draft.local.rubric;\n\n // ONE problem surface: what the rules say against the form they were written\n // against (`draft.diagnostics`, incl. the engine's verdict) plus what they say\n // against the form as it is NOW (`draft.driftProblems`). The two overlap by\n // design — every duplicate collapses in `problemList`'s dedupe and `RuleCard`'s\n // — and only the drift run can produce `RUB_SCHEMA_DRIFT`, the one problem that\n // means \"your form moved\", not \"your rule is wrong\".\n const allDiagnostics = useMemo(() => (draft.driftProblems ? [...draft.diagnostics, ...draft.driftProblems] : draft.diagnostics), [draft.diagnostics, draft.driftProblems]);\n const allErrors = useMemo(() => allDiagnostics.filter((diagnostic) => diagnostic.severity === 'error'), [allDiagnostics]);\n\n const configMissing = !collectionId || !deedDid;\n // Only the evaluate-authz grant needs the admin account, so only a chain-writing\n // enrolment waits for it.\n const adminMissing = !configMissing && !adminAddress && parsed.allowChainEvaluation;\n // `runEvalRegister` refuses to enrol without a valid billing email (evalRegister.ts\n // §76-83) — after the PIN and the signature. Same rule, checked here, so nobody\n // spends either to learn it. Same shape as the run's own test.\n const emailMissing = !configMissing && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(String(parsed.notifyEmail || '').trim());\n // Locked decision: no rules, no signature. An engine enrolled with nothing to\n // judge by records \"no rules\" on every claim, forever. A grown rule is ONE\n // rule (owner 2026-08-03) and already counts in `rules`; a linked rule IS\n // rules — its gates are what the plain list never shows; and a rule folded\n // into the approval policy (proposal v3) is a member of the policy gate,\n // which `rules` excludes — a rulebook that is one policy gate still judges.\n const policyMemberCount = useMemo(() => {\n const shape = policyShapeOf(body ?? null);\n return shape.kind === 'policy' ? shape.members.length : 0;\n }, [body]);\n const checkCount = draft.rules.length + draft.linked.length + policyMemberCount;\n const rulesMissing = !body || checkCount === 0;\n // The form the rules are written against has to be readable here, or the rules\n // cannot be checked at all — and unchecked rules are exactly what `draft.errors`\n // would be empty for.\n const formBroken = !configMissing && !draft.formLoading && (!!draft.formError || !catalog);\n // The check that produced `draft.errors` fails SOFT in the hook — the designer\n // has to stay usable while the rules service is down. The GATE must not: an empty\n // problem list from a check that never ran reads exactly like a clean one. The run\n // now checks the rules in its own preflight before anything irreversible\n // (`evalEngine.ts` stage 1), so arming here could not publish bad rules — it would\n // spend the owner a PIN prompt and a failed run to be told what this already\n // knows. So \"could not check\" and \"not checked yet\" both hold the slider.\n const rulesUnchecked = !configMissing && !rulesMissing && (draft.checking || !!draft.checkError);\n // Same fail-closed rule for the live-form comparison: in flight, unreadable, or\n // never run all mean \"not checked\" — never \"no drift\". `null` is the never-run\n // state, which is why it is a distinct value and not an empty array.\n const driftUnchecked = !configMissing && !rulesMissing && (draft.driftChecking || !!draft.driftError || draft.driftProblems === null);\n // Every error-severity problem holds the slider: local, engine, and drift.\n const blocked = configMissing || adminMissing || emailMissing || draft.formLoading || formBroken || rulesMissing || rulesUnchecked || driftUnchecked || allErrors.length > 0;\n\n // The stored catalog is a SNAPSHOT of the form as it was when the rules were\n // written, and the hook only re-reads the form when there is no snapshot at all —\n // so a question deleted or retyped since then still agrees with everything stored,\n // and nothing local would object. `checkFormDrift` re-reads the live form ONCE per\n // mount and compares it WITH the snapshot kept as the baseline, which is what\n // makes the problem read \"the form changed\" rather than \"this rule points at\n // nothing\" — and it persists nothing, so opening this panel never writes the\n // block. The run's preflight re-checks the same thing; doing it here is what stops\n // the author starting a run that is already doomed.\n const driftCheckedRef = useRef(false);\n useEffect(() => {\n if (driftCheckedRef.current) return;\n if (configMissing || isCompletedWithProof) return;\n if (draft.formLoading || !catalog || !body) return; // nothing authored yet ⇒ nothing to compare\n driftCheckedRef.current = true;\n console.log(`${LOG} checking the rules against the claim form as it is NOW`);\n void draft.checkFormDrift();\n }, [configMissing, isCompletedWithProof, catalog, body, draft.formLoading, draft.checkFormDrift]);\n\n // Push runtime inputs upward so the executor merges the resolved context over\n // the persisted blob.\n useEffect(() => {\n if (!registerRuntimeInputs) return;\n registerRuntimeInputs({ collectionId, deedDid, adminAddress: adminAddress || undefined });\n }, [registerRuntimeInputs, collectionId, deedDid, adminAddress]);\n\n useEffect(() => {\n unlockSigning?.(!isDisabled && !isRunning && !isCompletedWithProof && !blocked);\n }, [unlockSigning, isDisabled, isRunning, isCompletedWithProof, blocked]);\n\n // -------------------------------------------------------------------------\n // Signing handler the generic SlideToSign control invokes. One-shot: consumes\n // the pending invocation (if event-triggered) on success.\n // -------------------------------------------------------------------------\n const execute = useCallback(async () => {\n if (isDisabled || isRunning || isCompletedWithProof) return;\n if (!executeAction) {\n updateRuntime({ state: 'failed', error: { message: 'Shared action executor is unavailable', at: Date.now() } });\n return;\n }\n if (configMissing) {\n updateRuntime({ state: 'failed', error: { message: 'No collection configured. Set one in template mode or wire a Claim Collection trigger.', at: Date.now() } });\n return;\n }\n if (blocked) {\n updateRuntime({ state: 'failed', error: { message: 'Finish the rules and fix the problems above before signing.', at: Date.now() } });\n return;\n }\n\n const runtimeInputs: EvalEngineRuntimeInputs = {\n collectionId,\n deedDid,\n adminAddress: adminAddress || undefined,\n // The rules ride ALONG WITH the run, not only in the block's saved blob.\n // Runtime inputs are merged LAST over `block.props.inputs`\n // (`actionExecutor.ts`'s `buildActionRunInputs`), and the block object that\n // blob is read from is the caller's own copy — `findBlock` returns it as\n // given, without re-resolving the id against `editor.document`, so it can\n // be one write behind the edit that was just made. The blob itself is\n // written correctly (`runInputs.test.tsx` pins that); this is what\n // guarantees the run is judged on the SAME rules the signing gate armed\n // on. Read through the ref so the freshest edit wins over whatever this\n // callback closed over; `blocked` above already refuses to run without\n // rules, so past the gate these are never absent.\n rubric: draftLocalRef.current.rubric ?? undefined,\n claimSchemaSnapshot: draftLocalRef.current.claimSchemaSnapshot ?? undefined,\n };\n const pendingInvocationId = activePendingInvocation?.id;\n console.log(`${LOG} execute →`, { collectionId, rules: draft.rules.length, listener: !!pendingInvocationId });\n try {\n const outcome = await executeAction(pendingInvocationId ? { runtimeInputs, pendingInvocationId } : { runtimeInputs });\n if (!outcome.success) throw new Error(outcome.error || 'Enabling the Evaluation Engine failed');\n const payload = outcome.output as { registrationId?: string; rubricId?: string; resourceTxHash?: string } | undefined;\n // Composite proof guard: enrolled AND published AND anchored, or this run\n // half-landed — which is a failure, not a partial success.\n if (!String(payload?.registrationId || '').trim() || !String(payload?.rubricId || '').trim() || !String(payload?.resourceTxHash || '').trim()) {\n throw new Error('The run reported success without full proof (enrolment, published rules, and the transaction that anchors them). Check the [eval.engine] handler logs.');\n }\n console.log(`${LOG} execute success`, { registrationId: payload!.registrationId, rubricId: payload!.rubricId });\n if (pendingInvocationId) onPendingInvocationCompleted?.(pendingInvocationId);\n } catch (error) {\n // The RAW throw first — a SignX event object or chain rawLog must land in\n // the console whole, even when the extracted message is lossy.\n console.error(`${LOG} execute failed`, error);\n updateRuntime({ state: 'failed', error: { message: failureMessageOf(error), at: Date.now() } });\n }\n }, [\n isDisabled,\n isRunning,\n isCompletedWithProof,\n executeAction,\n configMissing,\n blocked,\n collectionId,\n deedDid,\n adminAddress,\n draft.rules.length,\n activePendingInvocation,\n updateRuntime,\n onPendingInvocationCompleted,\n ]);\n\n useEffect(() => {\n if (!provideSigningHandler) return;\n provideSigningHandler(execute);\n }, [provideSigningHandler, execute]);\n\n const handleReset = useCallback(() => {\n updateRuntime({ state: 'idle', error: undefined, output: {} });\n }, [updateRuntime]);\n\n // -------------------------------------------------------------------------\n // The designer's own view of the draft (§B.5) — carried over from the rules\n // block's builder, reading everything off `draft`. The pickers are NOT: the\n // collection is bound in template mode or by the trigger, never re-chosen here.\n // -------------------------------------------------------------------------\n const [editorState, setEditorState] = useState<{ field: RubricField; editing?: UiRule } | null>(null);\n const [linkedEditorState, setLinkedEditorState] = useState<{ checkedField: string; editing?: LinkedRule } | null>(null);\n\n // Card resolution needs the card set (dotted question names are whole cards), so it comes first.\n const cardPaths = useMemo(() => new Set((catalog?.fields ?? []).map((field) => field.path)), [catalog]);\n const byCard = useMemo(() => rulesByCard(body, cardPaths), [body, cardPaths]);\n\n // A linked rule lists on its CHECKED question's card (Part 3 placement).\n const linkedByCard = useMemo(() => {\n const grouped = new Map<string, LinkedRule[]>();\n for (const entry of draft.linked) {\n const key = rootPath(entry.checkedField, cardPaths);\n const bucket = grouped.get(key);\n if (bucket) bucket.push(entry);\n else grouped.set(key, [entry]);\n }\n return grouped;\n }, [draft.linked, cardPaths]);\n\n // The questions that can serve as a linked rule's guard — where \"is exactly\n // this value\" makes sense. No guard beyond the card's own question ⇒ the\n // affordance hides on that card.\n const guardPaths = useMemo(\n () =>\n [...draft.index.values()]\n .filter((entry) => (entry.kind === 'text' || entry.kind === 'number' || entry.kind === 'choice') && !entry.path.includes('[*]'))\n .map((entry) => entry.path),\n [draft.index]\n );\n\n // Every problem, filed under the card whose rule caused it (§A.11 pointers).\n const problemsByCard = useMemo(() => {\n const grouped = new Map<string, RubricProblem[]>();\n const loose: RubricProblem[] = [];\n for (const diagnostic of allDiagnostics) {\n const cardPath = cardForDiagnosticPath(body, diagnostic.path, cardPaths);\n if (!cardPath) {\n loose.push(diagnostic);\n continue;\n }\n const bucket = grouped.get(cardPath);\n if (bucket) bucket.push(diagnostic);\n else grouped.set(cardPath, [diagnostic]);\n }\n return { grouped, loose };\n }, [body, allDiagnostics, cardPaths]);\n\n // Rules about something that is no longer a question on the form — they still\n // have to be reachable, or the author could never delete what blocks them.\n const orphanRules = useMemo(() => draft.rules.filter((rule) => !rule.fieldPath || !cardPaths.has(rootPath(rule.fieldPath, cardPaths))), [draft.rules, cardPaths]);\n // …and linked rules whose checked question left the form, for the same reason.\n const orphanLinked = useMemo(() => draft.linked.filter((entry) => !cardPaths.has(rootPath(entry.checkedField, cardPaths))), [draft.linked, cardPaths]);\n\n // A card can be scrolled to when a problem points at it (§B.5 \"take me there\").\n const cardRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const scrollToCard = useCallback((cardPath: string) => {\n cardRefs.current.get(cardPath)?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, []);\n\n // The real problems, in the author's words — never a bare count, never a raw\n // code (§B.5). A shape error is named by WHERE it is (`schemaProblemText`) so it\n // says what is actually wrong, except when it carries its OWN words (an unknown\n // key names the key + the stale-service fix), which show verbatim.\n const problemList = useMemo(() => {\n const seen = new Set<string>();\n const out: { text: string; card?: string }[] = [];\n for (const diagnostic of allErrors) {\n const cardPath = cardForDiagnosticPath(body, diagnostic.path, cardPaths);\n const text =\n diagnostic.code === 'RUB_SCHEMA' && diagnostic.message.startsWith(SCHEMA_UNKNOWN_KEY_PREFIX)\n ? diagnostic.message\n : diagnostic.code === 'RUB_SCHEMA'\n ? schemaProblemText(diagnostic.path, !!cardPath)\n : problemText(diagnostic);\n const target = cardPath && cardPaths.has(cardPath) ? cardPath : undefined;\n const key = `${text}@@${target ?? ''}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push({ text, card: target });\n }\n return out;\n }, [allErrors, body, cardPaths]);\n\n const saveRule = (rule: RuleDraft) => {\n if (!body) return;\n // The subject's readable name for the receipt wording — the question's title\n // (a check's question is the answer it sends).\n const subjectTitle = draft.index.get(rule.ext?.sendField ?? rule.ai?.sendField ?? rule.field)?.title;\n // Prune AFTER the rule (and its check, if any) lands: a source loses its last\n // reader when a rule is rewritten off it, and must not linger (§A.14).\n draft.setRubric(pruneDanglingSources(applyDraft(body, rule, editorState?.editing, subjectTitle)));\n setEditorState(null);\n };\n\n const deleteRule = (rule: UiRule) => {\n if (!body) return;\n // Deleting the last rule on an outside check deletes the check with it.\n draft.setRubric(pruneDanglingSources(removeRule(body, rule)));\n };\n\n const saveLinked = (linkedDraft: LinkedDraft) => {\n if (!body) return;\n draft.setRubric(pruneDanglingSources(applyLinkedDraft(body, linkedDraft, draft.index)));\n setLinkedEditorState(null);\n };\n\n /** Delete = removes ALL of the table's gates, the \"anyone else\" one included. */\n const deleteLinked = (entry: LinkedRule) => {\n if (!body) return;\n draft.setRubric(pruneDanglingSources(removeGatesAt(body, entry.indices)));\n };\n\n // Editing is locked while the run is in flight or the block is off — the blob\n // being signed must not move underneath the signature.\n const editingLocked = isDisabled || isRunning;\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n const title = (block?.props?.title as string) || 'Evaluation Engine';\n const description = (block?.props?.description as string) || '';\n\n return (\n <Stack gap=\"md\">\n <Stack gap={2}>\n <Text fw={600}>{title}</Text>\n {description && (\n <Text size=\"sm\" c=\"dimmed\">\n {description}\n </Text>\n )}\n </Stack>\n\n {configMissing && (\n <Alert color=\"yellow\" styles={actionAlertStyles}>\n Configure the DID and claim collection in template mode (or wire a Claim Collection trigger) before running this action.\n </Alert>\n )}\n\n {/* ── The designer: the claim form, and the rules on it ──\n Hidden once the run has landed: the rules are published and enrolment is\n one-shot, so further edits here would change a blob nothing reads. */}\n {!configMissing && !isCompletedWithProof && (\n <>\n {draft.formLoading && (\n <Group gap=\"xs\">\n <Loader size=\"xs\" />\n <Text size=\"sm\" c=\"dimmed\">\n Loading the claim form…\n </Text>\n </Group>\n )}\n\n {/* This claim form already had rules published against it, and they are what\n is on screen. Said plainly, because it changes what signing MEANS here:\n this run replaces a live rulebook rather than establishing a first one. */}\n {draft.prefilledFromChain && (\n <Alert color=\"neutralColor\" variant=\"light\" icon={<IconInfoCircle size={16} />} styles={actionAlertStyles}>\n <Text size=\"xs\">These are the rules already published for this claim form, loaded from chain. Edit them and sign to replace what is live.</Text>\n </Alert>\n )}\n\n {/* The collection list is how the form is found at all, and its failure is\n otherwise SILENT: the hook clears a collection that is no longer on the\n DID without a word, leaving a screen with no rules and no reason. */}\n {draft.collectionsError && (\n <Alert color=\"red\" icon={<IconAlertCircle size={16} />} styles={actionAlertStyles}>\n <Text size=\"sm\">{draft.collectionsError}</Text>\n </Alert>\n )}\n\n {!draft.formLoading && draft.formError && <BaseAlert errMsg={draft.formError} onRetry={draft.reloadForm} />}\n\n {!draft.formLoading && !draft.formError && catalog && body && (\n <>\n <Group justify=\"space-between\" align=\"center\">\n <Text size=\"sm\" fw={600}>\n {body.title ? `Form: “${body.title}”` : 'The claim form'} · {catalog.fields.length} question{catalog.fields.length === 1 ? '' : 's'}\n </Text>\n </Group>\n\n <Stack gap={14}>\n {catalog.fields.map((field) => (\n <div\n key={field.path}\n ref={(el) => {\n if (el) cardRefs.current.set(field.path, el);\n else cardRefs.current.delete(field.path);\n }}\n >\n <RuleCard\n field={field}\n rules={byCard.get(field.path) ?? []}\n linked={linkedByCard.get(field.path) ?? []}\n problems={problemsByCard.grouped.get(field.path) ?? []}\n index={draft.index}\n aiChecks={body.aiChecks}\n onAdd={() => setEditorState({ field })}\n onEdit={(rule) => setEditorState({ field, editing: rule })}\n onDelete={deleteRule}\n onAddLinked={guardPaths.some((path) => path !== field.path) ? () => setLinkedEditorState({ checkedField: field.path }) : undefined}\n onEditLinked={(entry) => setLinkedEditorState({ checkedField: entry.checkedField, editing: entry })}\n onDeleteLinked={deleteLinked}\n disabled={editingLocked}\n />\n </div>\n ))}\n </Stack>\n\n {(orphanRules.length > 0 || orphanLinked.length > 0) && (\n <Paper p={18} style={{ ...cardStyle, borderColor: 'var(--mantine-color-red-6)' }}>\n <Stack gap=\"sm\">\n <Text size=\"sm\" fw={600}>\n Rules with no question\n </Text>\n <Text size=\"xs\" c=\"dimmed\">\n These are about answers the form no longer asks for. Delete them, or put the questions back on the form.\n </Text>\n {orphanRules.map((rule) => (\n <Group key={rule.code} gap=\"sm\" align=\"flex-start\" wrap=\"nowrap\">\n <Box mt={2} style={consequencePillStyle(CONSEQUENCES.find((entry) => entry.value === rule.consequence)?.color ?? SLATE)}>\n {consequenceIcon(rule.consequence, 15)}\n </Box>\n <Box style={{ flex: 1 }}>\n <RuleSentence text={describeRule(rule, { fields: draft.index, aiChecks: body.aiChecks })} />\n </Box>\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => deleteRule(rule)} disabled={editingLocked} aria-label=\"Delete this rule\">\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n ))}\n {orphanLinked.map((entry) => (\n <Group key={entry.elseCase.code} gap=\"sm\" align=\"flex-start\" wrap=\"nowrap\">\n <Box mt={2} style={consequencePillStyle(entry.onFail === 'review' ? 'var(--mantine-color-grape-6)' : 'var(--mantine-color-red-6)')}>\n {consequenceIcon(entry.onFail === 'review' ? 'human' : 'reject', 15)}\n </Box>\n <Box style={{ flex: 1 }}>\n <RuleSentence text={describeLinked(linkedSentenceOf(entry), { fields: draft.index })} />\n </Box>\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => deleteLinked(entry)} disabled={editingLocked} aria-label=\"Delete this rule\">\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n ))}\n </Stack>\n </Paper>\n )}\n\n {/* This collection's settings contradict these rules — the ONE problem the editor\n cannot work out for itself (it comes back from the engine's pre-publish check).\n It belongs to no single question, and on THIS block the setting it names is one\n panel away in template mode, so it is said here in full rather than buried in\n the summary bar. */}\n {allErrors\n .filter((problem) => problem.code === 'RUB_AI_CHECKS_DISABLED')\n .map((problem) => (\n <Alert key={problem.code} color=\"red\" icon={<IconAlertTriangle size={16} />} title=\"AI checks are turned off for this collection\" styles={actionAlertStyles}>\n <Text size=\"xs\">{problem.message}</Text>\n </Alert>\n ))}\n\n {/* ── When is a claim approved? ──\n The rulebook-level APPROVAL POLICY (proposal v3): tabs over\n the author's reject rules. \"All of them\" states today's one\n rule; the other tabs fold the ticked rules into ONE any/\n at-least gate — shapes the engine already evaluates. */}\n <ApprovalPolicy body={body} index={draft.index} checkCount={checkCount} onChange={draft.setRubric} disabled={editingLocked} />\n\n {/* ── This claim must be unique ──\n The duplicate rule (dup-detection spec §6) — a document-level\n card like the approval policy: keyed on picked answers (file\n fields match by fingerprint), with the default-on AI judge\n (opting out is explicit — weak matches then pass with only a\n recorded score) and the two bps thresholds behind percent\n sliders. */}\n <UniqueRule body={body} catalog={catalog} onChange={draft.setRubric} disabled={editingLocked} />\n\n {/* ── Limit how often each person can claim ──\n The frequency rule (dup-detection spec §13) — composes with the\n unique rule: uniqueness catches same content, this catches too\n much content, however varied. One sentence of controls (\"At\n most 2 claims per month\") plus the breach consequence — a\n person checks (the engine default), or reject. */}\n <FrequencyRule body={body} onChange={draft.setRubric} disabled={editingLocked} />\n\n {/* Document-level WARNINGS that belong to no single question (errors are\n listed, in plain words, in the summary bar below). RUB_WEIGHT_IGNORED\n stays silent: nothing on screen sets a weight any more. */}\n {problemsByCard.loose\n .filter((problem) => problem.severity === 'warning' && problem.code !== 'RUB_WEIGHT_IGNORED')\n .map((problem) => (\n <Alert key={`${problem.code}${problem.path}`} color=\"yellow\" icon={<IconInfoCircle size={16} />} styles={actionAlertStyles}>\n <Text size=\"xs\">{problemText(problem)}</Text>\n </Alert>\n ))}\n\n {/* ── The summary bar: the real problems, in plain words, each with a\n \"take me there\" when it belongs to a question (§B.5). ── */}\n <Paper p=\"md\" style={cardStyle}>\n <Stack gap=\"xs\">\n <Group justify=\"space-between\">\n <Group gap=\"xs\">\n {allErrors.length === 0 ? <IconCheck size={16} color=\"var(--mantine-color-green-6)\" /> : <IconAlertTriangle size={16} color=\"var(--mantine-color-red-6)\" />}\n <Text size=\"sm\">{describeTally(draft.rules, { linked: draft.linked.length, policyMembers: policyMemberCount })}</Text>\n </Group>\n <Text size=\"sm\" fw={600} c={allErrors.length > 0 ? 'red' : 'dimmed'}>\n {allErrors.length > 0 ? `${allErrors.length} problem${allErrors.length === 1 ? '' : 's'} left to fix` : 'Ready to sign'}\n </Text>\n </Group>\n {problemList.length > 0 && (\n <Stack gap={6}>\n {problemList.map((problem, at) => (\n <Group key={`${problem.text}${at}`} gap=\"xs\" wrap=\"nowrap\" align=\"flex-start\">\n <Box mt={3} style={{ flexShrink: 0 }}>\n <IconAlertTriangle size={14} color=\"var(--mantine-color-red-6)\" />\n </Box>\n <Text size=\"xs\" style={{ flex: 1 }}>\n {problem.text}\n </Text>\n {problem.card && (\n <Button size=\"compact-xs\" variant=\"subtle\" styles={quietButton} rightSection={<IconArrowRight size={12} />} onClick={() => scrollToCard(problem.card!)}>\n Take me there\n </Button>\n )}\n </Group>\n ))}\n </Stack>\n )}\n </Stack>\n </Paper>\n\n {/* The machine view, collapsed and read-only — same placement and props the rules\n block's builder gave it. It takes `body` and no setter, so it cannot reach the\n merge-writer: nothing here can write the block or move the signing gate. */}\n <AdvancedPanel body={body} />\n\n {editorState && (\n <RuleEditor\n opened\n onClose={() => setEditorState(null)}\n body={body}\n catalog={catalog}\n index={draft.index}\n field={editorState.field}\n editing={editorState.editing}\n onSave={saveRule}\n />\n )}\n\n {linkedEditorState && (\n <LinkedRuleEditor\n opened\n onClose={() => setLinkedEditorState(null)}\n body={body}\n catalog={catalog}\n index={draft.index}\n initialChecked={linkedEditorState.checkedField}\n editing={linkedEditorState.editing}\n onSave={saveLinked}\n />\n )}\n </>\n )}\n </>\n )}\n\n {/* The rules service's verdict is part of the signing gate, so its state is\n shown rather than left to a locked slider nobody can explain. */}\n {!configMissing && !isCompletedWithProof && !rulesMissing && (draft.checking || draft.driftChecking) && (\n <Group gap=\"xs\">\n <Loader size=\"xs\" />\n <Text size=\"sm\" c=\"dimmed\">\n {draft.driftChecking ? 'Checking your rules against the claim form…' : 'Checking your rules…'}\n </Text>\n </Group>\n )}\n\n {!configMissing && !isCompletedWithProof && !rulesMissing && !draft.checking && !draft.driftChecking && (draft.checkError || draft.driftError) && (\n <Alert color=\"red\" icon={<IconAlertCircle size={16} />} styles={actionAlertStyles}>\n <Stack gap=\"xs\">\n {draft.driftError && <Text size=\"sm\">{draft.driftError}</Text>}\n {draft.checkError && <Text size=\"sm\">{draft.checkError}</Text>}\n <Text size=\"xs\" c=\"dimmed\">\n Your rules can&apos;t be signed off until they have been checked — enrolling is not something that can be taken back.\n </Text>\n </Stack>\n </Alert>\n )}\n\n {!configMissing && !isCompletedWithProof && (\n <Alert color=\"neutralColor\" variant=\"light\" icon={<IconInfoCircle size={16} />} styles={actionAlertStyles}>\n <Stack gap={6}>\n <Text size=\"xs\">\n Slide to sign to turn the Evaluation Engine on for this collection. One signature does both: it authorizes the engine to read this collection&apos;s claims on your\n behalf, and publishes the rules above so every new claim is judged by them.\n </Text>\n {/* The §B.3 pricing disclosure repeats at the moment of signing —\n exactly the checks being enabled, one USD price per line.\n What you sign is what you saw. */}\n <Stack gap={2}>\n <Text size=\"xs\">Checking a claim — {usdLabel(card.baseUsd)} / claim</Text>\n {parsed.allowAiChecks && <Text size=\"xs\">AI checks — {usdLabel(card.aiRuleUsd)} per AI rule / claim</Text>}\n {parsed.allowAiChecks && parsed.allowImageChecks && <Text size=\"xs\">Fake-photo detection — {usdLabel(card.photoUsd)} / photo</Text>}\n {/* The bottom line for this collection: the card minus what its own\n evaluation payment credits back. Only shown once the engine has\n resolved it — a signature never carries a guessed number. */}\n {payLine && (\n <Text size=\"xs\" fw={500}>\n {payLine}\n </Text>\n )}\n {/* Costs nothing, but it is the setting that moves money — say so before the signature. */}\n <Text size=\"xs\">\n {parsed.allowChainEvaluation ? 'Decisions are submitted on chain — this releases payment' : 'Decisions are recorded only — nothing is submitted on chain'}\n </Text>\n {/* The grant is what the signature actually authorizes. Name it and\n its ceiling here: quiet, never hidden. */}\n {parsed.allowChainEvaluation && <Text size=\"xs\">Engine may approve payouts up to {formatCapCoins(parsed.evaluateMaxAmount, 'no custom amount')} / claim</Text>}\n {/* What is being published alongside the enrolment, in one line. */}\n <Text size=\"xs\">{describeTally(draft.rules, { policyMembers: policyMemberCount })}</Text>\n {/* `billingNote` is the single credits mention on this surface in every\n state, resolved or not — never render a standalone credits note\n alongside it (fix round 1: the two used to double up while\n unresolved, since the unresolved note already ends \"…paid from your\n subscription credits\"). Said once per surface, owner 2026-07-18. */}\n <Text size=\"xs\" c=\"dimmed\">\n {billingNote(card, live)}\n </Text>\n </Stack>\n <Group gap=\"xs\">\n <Badge size=\"xs\" variant=\"light\" color=\"neutralColor\">\n Collection {truncate(collectionId)}\n </Badge>\n </Group>\n </Stack>\n </Alert>\n )}\n\n {/* Why the slider is locked, when the reason is not already a problem on a\n card: an engine with no rules would send every claim to a person. */}\n {!configMissing && !isCompletedWithProof && rulesMissing && !draft.formLoading && !draft.formError && (\n <Text size=\"xs\" c=\"dimmed\">\n Add at least one rule before signing — until then this engine would have nothing to judge by, and every claim would wait for a person.\n </Text>\n )}\n\n {emailMissing && !isCompletedWithProof && (\n <Text size=\"xs\" c=\"dimmed\">\n Add a billing email in template mode before signing — failed payments and paused evaluations are announced there.\n </Text>\n )}\n\n {adminMissing && !isCompletedWithProof && (\n <Text size=\"xs\" c=\"dimmed\">\n Waiting for the entity&apos;s admin account… (it signs the grant that lets the engine submit decisions on chain)\n </Text>\n )}\n\n {isStale && (\n <Alert icon={<IconAlertCircle size={16} />} color=\"yellow\" title=\"Inconsistent State\" styles={actionAlertStyles}>\n <Stack gap=\"xs\">\n <Text size=\"sm\">\n This block was marked completed but did not record all of the enrolment, the published rules, and the transaction that anchors them. Reset and re-run.\n </Text>\n <Button variant=\"outline\" size=\"xs\" onClick={handleReset}>\n Reset\n </Button>\n </Stack>\n </Alert>\n )}\n\n {isFailed && (\n <Alert icon={<IconAlertCircle size={16} />} color=\"red\" title=\"The Evaluation Engine was not enabled\" styles={actionAlertStyles}>\n <Stack gap=\"xs\">\n {errorMessage && <Text size=\"sm\">{errorMessage}</Text>}\n <Button variant=\"outline\" size=\"xs\" onClick={handleReset}>\n Reset\n </Button>\n </Stack>\n </Alert>\n )}\n\n {isCompletedWithProof && (\n <Alert icon={<IconCheck size={16} />} color=\"green\" styles={actionAlertStyles}>\n Evaluation Engine enabled — this collection is enrolled and your rules are published (rules {truncate(rubricId)}). Every new claim is judged by them.\n </Alert>\n )}\n\n {isDisabled && (\n <Text size=\"xs\" c=\"dimmed\">\n This block is currently disabled.\n </Text>\n )}\n </Stack>\n );\n};\n\nexport default EvalEngineFlowDetail;\n","import React from 'react';\nimport { Button, Code, CopyButton, Group, ScrollArea, Stack } from '@mantine/core';\nimport { buildRubricEnvelope, type RubricBody } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { CollapsibleSection } from '@/mantine/components/CollapsibleSection';\n\n/**\n * The machine view — the ONE thing left under the fold, collapsed by default.\n *\n * The named-values and reviewer sections that used to live here are gone: the\n * reviewer moved into the 👤 outcome of the rule editor, calculated values are\n * authored inline where a 📊 rule picks its subject (§A.7), and `constants`\n * left the format entirely (v1.1, §A.0).\n */\n\ninterface AdvancedPanelProps {\n body: RubricBody;\n}\n\nexport const AdvancedPanel: React.FC<AdvancedPanelProps> = ({ body }) => (\n <CollapsibleSection title=\"Your rules, as the machine reads them\">\n <MachineView body={body} />\n </CollapsibleSection>\n);\n\nconst MachineView: React.FC<{ body: RubricBody }> = ({ body }) => {\n const text = JSON.stringify(buildRubricEnvelope(body), null, 2);\n return (\n <Stack gap=\"xs\">\n <Group justify=\"flex-end\">\n <CopyButton value={text}>\n {({ copied, copy }) => (\n <Button size=\"compact-xs\" variant=\"subtle\" onClick={copy}>\n {copied ? 'Copied' : 'Copy'}\n </Button>\n )}\n </CopyButton>\n </Group>\n <ScrollArea.Autosize mah={280}>\n <Code block style={{ fontSize: 11 }}>\n {text}\n </Code>\n </ScrollArea.Autosize>\n </Stack>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Box, Button, Checkbox, Group, Paper, SegmentedControl, Stack, Text } from '@mantine/core';\nimport { IconPin } from '@tabler/icons-react';\nimport type { RubricBody } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport BaseNumberInput from '@/mantine/components/Base/BaseNumberInput';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport {\n describeApproval,\n describePolicy,\n describePolicyMember,\n describeRule,\n fieldTitle,\n GROUP_OUTSIDE_BUILDER_TEXT,\n POLICY_DEFAULT_REASON,\n POLICY_EMPTY_TALLY_TEXT,\n POLICY_NO_RULES_TEXT,\n POLICY_OUTSIDE_BUILDER_TEXT,\n POLICY_PIN_LABEL,\n POLICY_TAB_LABEL,\n policyStepperText,\n type PhraseContext,\n} from './phrases';\nimport { clampPolicyN, compilePolicy, derivePolicy, type PolicyRow, type PolicyState, type PolicyTab } from './policyModel';\nimport { primaryFieldOf, type FieldIndex } from './ruleModel';\nimport { ACCENT, ACCENT_SOFT, cardStyle, chipInput, INK, quietButton, RuleSentence, segmentedPill } from './rubricStyles';\n\n/**\n * \"When is a claim approved?\" — the rulebook-level APPROVAL POLICY (owner\n * 2026-08-03, proposal v3): three tabs over the author's existing ⛔ rules.\n *\n * - **All of them** (default): nothing to set — today's one-sentence answer.\n * - **Any of them / At least…**: the rule list appears. A ticked, unpinned\n * rule folds into the tally; a pinned rule must always pass regardless; an\n * unticked rule stays exactly as it was. The stepper counts over every\n * selected rule, pins included, and the sentence below does the honest\n * arithmetic.\n *\n * The whole state is DERIVED from the document (`derivePolicy`) and every\n * change compiles straight back (`compilePolicy`) — no stored builder state,\n * no new shapes. The one local mirror here is the in-progress edit itself\n * (which rows the author unchecked, the original bytes of a folded gate),\n * ephemeral by doctrine: it re-derives whenever the document changes under us\n * (a rule added or deleted on a card), and skips only the echo of its own\n * write, which would otherwise flip every unchecked row to pinned mid-edit.\n */\n\ninterface ApprovalPolicyProps {\n body: RubricBody;\n index: FieldIndex;\n /** Standalone rules + linked tables + folded members — the default tab's sentence counts what the author can see. */\n checkCount: number;\n onChange: (next: RubricBody) => void;\n disabled?: boolean;\n}\n\nconst TABS: PolicyTab[] = ['all', 'any', 'atLeast'];\n\n/** The question a row is about, for the sentence's pin list. */\nfunction rowTitle(row: PolicyRow, ctx: PhraseContext): string {\n return fieldTitle(row.rule ? row.rule.fieldPath : primaryFieldOf(row.member), ctx);\n}\n\n/** The row's sentence — a standalone rule reads as its card does, a folded member by its conditions. */\nfunction rowSentence(row: PolicyRow, ctx: PhraseContext): string {\n if (row.rule) return describeRule(row.rule, ctx);\n return row.member ? describePolicyMember(row.member, ctx) : '';\n}\n\n/** The pin chip — quiet until active, then the accent tint (never a solid fill). */\nfunction pinChipStyles(active: boolean): { root: React.CSSProperties } {\n return { root: { ...quietButton.root, ...(active ? { '--button-bg': ACCENT_SOFT, '--button-color': INK } : {}) } as React.CSSProperties };\n}\n\nexport const ApprovalPolicy: React.FC<ApprovalPolicyProps> = ({ body, index, checkCount, onChange, disabled }) => {\n const [state, setState] = useState<PolicyState>(() => derivePolicy(body));\n const lastWrittenRef = useRef<string | null>(null);\n const bodyJson = JSON.stringify(body);\n useEffect(() => {\n // Re-derive on an EXTERNAL document change only — our own write echoes back\n // through the block's inputs and must not clobber the in-progress edit.\n if (bodyJson === lastWrittenRef.current) return;\n setState(derivePolicy(body));\n // `bodyJson` (content) is the real dependency — `body`'s identity churns on every write.\n }, [bodyJson]);\n\n const commit = (next: PolicyState) => {\n setState(next);\n const compiled = compilePolicy(next);\n const json = JSON.stringify(compiled);\n lastWrittenRef.current = json;\n if (json !== bodyJson) onChange(compiled);\n };\n\n const selectedCount = state.rows.filter((row) => row.selected).length;\n const pinnedSelected = state.rows.filter((row) => row.selected && row.pinned).length;\n const restCount = state.rows.filter((row) => row.selected && !row.pinned && !row.locked).length;\n\n const patchRow = (key: string, patch: Partial<Pick<PolicyRow, 'selected' | 'pinned'>>) => {\n const rows = state.rows.map((row) => (row.key === key ? { ...row, ...patch } : row));\n const pinned = rows.filter((row) => row.selected && row.pinned).length;\n const selected = rows.filter((row) => row.selected).length;\n commit({ ...state, rows, n: clampPolicyN(state.n, pinned, selected) });\n };\n\n const pickTab = (tab: PolicyTab) => commit({ ...state, tab, n: clampPolicyN(state.n, pinnedSelected, selectedCount) });\n const setN = (n: number) => commit({ ...state, n: clampPolicyN(n, pinnedSelected, selectedCount) });\n const setReason = (reason: string) => commit({ ...state, reason });\n\n const ctx: PhraseContext = { fields: index, aiChecks: body.aiChecks };\n const pinnedTitles = state.rows.filter((row) => row.selected && row.pinned).map((row) => rowTitle(row, ctx));\n const sentence =\n state.tab === 'all'\n ? describeApproval(checkCount)\n : restCount === 0\n ? ''\n : describePolicy({ tab: state.tab, pinned: pinnedTitles, restCount, n: state.n, reason: state.reason.trim() || POLICY_DEFAULT_REASON });\n\n return (\n <Paper p={18} style={cardStyle}>\n <Stack gap=\"sm\">\n <Group gap=\"sm\" justify=\"space-between\" align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\" fw={600}>\n When is a claim approved?\n </Text>\n <SegmentedControl\n styles={segmentedPill}\n value={state.foreign ? '' : state.tab}\n onChange={(tab) => pickTab(tab as PolicyTab)}\n disabled={disabled || state.foreign}\n data={TABS.map((tab) => ({ value: tab, label: POLICY_TAB_LABEL[tab] }))}\n />\n </Group>\n\n {state.foreign ? (\n // Hand-authored territory the tabs cannot edit — applied as written,\n // shown read-only; the stray gates stay deletable on their cards.\n <Text size=\"xs\" c=\"dimmed\">\n {POLICY_OUTSIDE_BUILDER_TEXT}\n </Text>\n ) : state.tab === 'all' ? (\n <RuleSentence text={sentence} />\n ) : (\n <Stack gap=\"xs\">\n {state.rows.length === 0 ? (\n <Text size=\"xs\" c=\"dimmed\">\n {POLICY_NO_RULES_TEXT}\n </Text>\n ) : (\n state.rows.map((row) => (\n <Group key={row.key} gap=\"sm\" align=\"flex-start\" wrap=\"nowrap\">\n <Checkbox\n size=\"xs\"\n mt={8}\n checked={row.selected}\n disabled={disabled || row.locked}\n onChange={(event) => patchRow(row.key, { selected: event.currentTarget.checked })}\n aria-label={`Count the rule on ${rowTitle(row, ctx)} towards approval`}\n />\n <Box style={{ flex: 1 }}>\n {row.rule?.grown && !row.rule.grown.editable ? (\n <Text size=\"xs\" c=\"dimmed\">\n {GROUP_OUTSIDE_BUILDER_TEXT}\n </Text>\n ) : (\n <RuleSentence text={rowSentence(row, ctx)} />\n )}\n </Box>\n {row.selected && (\n <Button\n size=\"compact-xs\"\n variant=\"subtle\"\n styles={pinChipStyles(row.pinned)}\n leftSection={icon(IconPin, 12, row.pinned ? ACCENT : undefined)}\n onClick={() => patchRow(row.key, { pinned: !row.pinned })}\n disabled={disabled || row.locked}\n >\n {POLICY_PIN_LABEL}\n </Button>\n )}\n </Group>\n ))\n )}\n\n {state.tab === 'atLeast' && state.rows.length > 0 && (\n <Group gap={8} align=\"center\" wrap=\"nowrap\">\n <BaseNumberInput\n w={80}\n styles={chipInput}\n min={pinnedSelected + 1}\n max={Math.max(selectedCount, pinnedSelected + 1)}\n value={state.n}\n onChange={(next) => setN(typeof next === 'number' ? next : pinnedSelected + 1)}\n disabled={disabled}\n />\n <Text size=\"sm\" c=\"dimmed\">\n {policyStepperText(selectedCount)}\n </Text>\n </Group>\n )}\n\n {state.rows.length > 0 && (\n <BaseTextInput\n label=\"What should the claimant be told?\"\n styles={chipInput}\n placeholder={POLICY_DEFAULT_REASON}\n description=\"They will read this when too few of the rules pass.\"\n value={state.reason}\n onChange={(event) => setReason(event.currentTarget.value)}\n disabled={disabled}\n />\n )}\n\n {sentence ? (\n <RuleSentence text={sentence} />\n ) : (\n state.rows.length > 0 && (\n <Text size=\"xs\" c=\"dimmed\">\n {POLICY_EMPTY_TALLY_TEXT}\n </Text>\n )\n )}\n </Stack>\n )}\n </Stack>\n </Paper>\n );\n};\n","import type { ReactNode } from 'react';\nimport { IconBan, IconUserSearch } from '@tabler/icons-react';\nimport type { RubricAiCheck, RubricCondition, RubricCtxToken, RubricField, RubricFieldKind, RubricOperator } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport type { RubricDiagnosticCode } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { aiMemberName, FAILED, toCondition, toSimpleRule, type FieldIndex, type LinkedRule, type SimpleRule, type UiRule } from './ruleModel';\n\n/**\n * All of the builder's language, in one file — rubric-spec §B.5 rules 1 and 3.\n *\n * Rule 1, \"never show a concept\": the words rubric, gate, criterion, basis\n * points, aggregation, JSON-LD and LinkedResource do not appear in any string\n * here, and must not appear in any other file's JSX either. The author sees\n * two consequences (Reject · Ask a person) and \"your rules\". Points are gone\n * from the surface entirely in v1 — no score, no weights, no thresholds.\n *\n * Rule 3, \"every rule reads back as an English sentence\": `describeRule` is the\n * ONLY sentence writer. Operator wording is a `Record<RubricOperator, …>`, so\n * adding an operator to the format fails the type-check here until it has words\n * — the language can never silently fall behind the vocabulary, and no\n * component may hand-write an operator's phrasing a second time.\n */\n\n/** Extra context a sentence may need — the field titles a path reads back through, and (for a grown rule's AI members) the document's AI checks. */\nexport interface PhraseContext {\n fields: FieldIndex;\n aiChecks?: RubricAiCheck[];\n}\n\n// ---------------------------------------------------------------------------\n// The two consequences — the whole conceptual surface the author ever meets\n// ---------------------------------------------------------------------------\n\nexport const CONSEQUENCES = [\n { value: 'reject', Icon: IconBan, color: 'var(--mantine-color-red-6)', label: 'Reject the claim', hint: 'The claim is turned down straight away.' },\n { value: 'human', Icon: IconUserSearch, color: 'var(--mantine-color-grape-6)', label: 'A person checks', hint: 'Someone looks at it and answers a question.' },\n] as const;\n\n/** The colour-coded icon for a consequence — a ban for Reject, a person for a human check (§B.5 rule 4). */\nexport function consequenceIcon(consequence: UiRule['consequence'], size = 18): ReactNode {\n const found = CONSEQUENCES.find((c) => c.value === consequence);\n return found ? icon(found.Icon, size, found.color) : null;\n}\n\n// ---------------------------------------------------------------------------\n// What kind of answer a question takes (the small grey word on each card)\n// ---------------------------------------------------------------------------\n\nexport const KIND_LABEL: Record<RubricFieldKind, string> = {\n text: 'writing',\n number: 'number',\n date: 'date',\n choice: 'choice',\n multichoice: 'tick list',\n boolean: 'yes / no',\n file: 'file',\n signature: 'signature',\n keyed_choice: 'grid',\n cells: 'table',\n rows: 'table',\n keyed_text: 'group of answers',\n geo: 'place',\n};\n\n// ---------------------------------------------------------------------------\n// Operators (§A.4's phrase column) — the middle of every sentence\n// ---------------------------------------------------------------------------\n\n/**\n * `label` is what the author picks in the operator box and reads in the\n * sentence; `suffix` is the word that trails the value (\"within the last 30\n * **days**\"), so no component has to glue units on by hand.\n */\nexport const OPERATOR_PHRASE: Record<RubricOperator, { label: string; suffix?: string }> = {\n present: { label: 'must be filled in' },\n empty: { label: 'must be empty' },\n '==': { label: 'must be exactly' },\n '!=': { label: 'must not be' },\n '>': { label: 'must be more than' },\n '>=': { label: 'must be at least' },\n '<': { label: 'must be less than' },\n '<=': { label: 'must be at most' },\n between: { label: 'must be between' },\n approx: { label: 'must be about' },\n in: { label: 'must be one of' },\n notIn: { label: 'must not be one of' },\n matches: { label: 'must look like' },\n startsWith: { label: 'must start with' },\n endsWith: { label: 'must end with' },\n lengthBetween: { label: 'must be between', suffix: 'characters long' },\n contains: { label: 'must include' },\n containsAll: { label: 'must include all of' },\n containsAny: { label: 'must include any of' },\n subsetOf: { label: 'may only include' },\n countBetween: { label: 'must have between', suffix: 'entries' },\n isTrue: { label: 'must be ticked' },\n isFalse: { label: 'must be left unticked' },\n before: { label: 'must be before' },\n after: { label: 'must be after' },\n withinWindow: { label: 'must be during the collection period' },\n withinDays: { label: 'must be within the last', suffix: 'days' },\n notInFuture: { label: 'cannot be in the future' },\n mediaTypeIn: { label: 'must be' },\n maxSizeMB: { label: 'must be smaller than', suffix: 'MB' },\n withinBoundary: { label: 'must be inside the project area' },\n withinRadius: { label: 'must be near' },\n};\n\n/** Operators that read as a whole sentence on their own — their value box stays hidden. */\nexport function takesNoValue(op: RubricOperator): boolean {\n return op === 'present' || op === 'empty' || op === 'isTrue' || op === 'isFalse' || op === 'withinWindow' || op === 'notInFuture' || op === 'withinBoundary';\n}\n\n/** Values the engine fills in for you — offered wherever a date is asked for. */\nexport const CTX_LABEL: Record<RubricCtxToken, string> = {\n 'ctx.now': 'the moment it is judged',\n 'ctx.collection.startDate': 'the day the collection opened',\n 'ctx.collection.endDate': 'the day the collection closes',\n 'ctx.claim.submitter': 'the person who sent the claim',\n 'ctx.claim.submitterAddress': 'the wallet address of the person who sent the claim',\n 'ctx.claim.submissionDate': 'the day the claim was sent',\n 'ctx.submitter.priorClaimCount': 'how many claims this person sent before',\n 'ctx.submitter.priorApprovedCount': 'how many of their claims were approved',\n 'ctx.collection.projectBoundary': 'the project area',\n};\n\n/** The common file types, in the author's words → the MIME globs the rule stores. */\nexport const MEDIA_TYPES = [\n { value: 'application/pdf', label: 'a PDF' },\n { value: 'image/*', label: 'a picture' },\n { value: 'video/*', label: 'a video' },\n { value: 'audio/*', label: 'a sound recording' },\n { value: 'text/csv', label: 'a spreadsheet (CSV)' },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Problems — the author reads the problem, never the code (§B.5 guardrails)\n// ---------------------------------------------------------------------------\n\n/**\n * Stable diagnostic code → what actually went wrong, in the author's words.\n * A `Record` over the union: a new code cannot ship without words for it.\n */\nexport const DIAGNOSTIC_TEXT: Record<RubricDiagnosticCode, string> = {\n RUB_SCHEMA: 'This rule has a setting the rules service will not accept — open it and check its options.',\n RUB_FIELD_NOT_IN_SCHEMA: 'This rule is about a question that is not on the form.',\n RUB_FIELD_PATH: 'This rule points at something the form does not have.',\n RUB_OPERATOR_TYPE_MISMATCH: 'This check does not work on this kind of answer.',\n RUB_VALUE_TYPE: 'The value here does not suit the check — fix it and the rule will work.',\n RUB_UNKNOWN_REF: 'This rule uses a value that no longer exists.',\n RUB_EXPR_SYNTAX: 'This calculated value could not be worked out.',\n RUB_EXPR_UNKNOWN_FUNC: 'This calculated value uses a way of counting we do not support.',\n RUB_REGEX_UNSAFE: 'This pattern is too complicated to be safe — please simplify it.',\n RUB_THRESHOLD_ORDER: 'The approve, part-pay and person-checks scores are in the wrong order.',\n RUB_WEIGHT_INVALID: 'How much this question counts must be between one and five stars.',\n RUB_QUORUM_INVALID: 'You are asking for more checks to pass than there are checks to pass.',\n RUB_DUPLICATE_CODE: 'Two rules are using the same name.',\n RUB_REVIEW_TASK_UNMAPPED: 'A person is meant to check this, but there is no question to ask them.',\n RUB_REVIEW_ANSWER_UNMAPPED: 'One of the answers a person can give does not decide anything yet.',\n RUB_UNREACHABLE_BAND: 'A step below can never be reached, because an earlier one always wins.',\n RUB_WEIGHT_IGNORED: 'The stars on your scored rules are being ignored — the way this rubric adds up scores does not use them.',\n RUB_NO_RULES: 'No rules yet — as it stands, every claim would be approved and paid without any checking. Add at least one rule before publishing.',\n RUB_SCHEMA_DRIFT: 'The form changed: this rule is about a question that was removed or altered.',\n RUB_UNIQUE_KEY_DERIVED: 'Calculated values cannot be part of the unique key — pick answers from the form instead.',\n RUB_EXT_SOURCE_UNKNOWN: 'This rule uses an external check that is not set up — add it under External checks, or fix the name.',\n RUB_EXT_FIELD_INVALID: 'This rule reads the wrong kind of answer from an external check — a yes/no check has no score, and a score has no yes/no.',\n RUB_AI_CHECK_UNKNOWN: 'This rule uses an AI check that is not set up — re-open the rule and pick “AI checks it” again.',\n RUB_AI_FIELD_INVALID: 'This rule reads the wrong kind of answer from an AI check — it gives a yes/no and a reason, nothing else.',\n};\n\nexport function diagnosticText(code: RubricDiagnosticCode): string {\n return DIAGNOSTIC_TEXT[code];\n}\n\n/**\n * The author-facing words for ONE problem, whatever produced it.\n *\n * The editor phrases its own diagnostics by CODE (§B.5 rule 1 — raw validator text never reaches\n * the screen). The engine's pre-publish preview returns codes this table has no entry for\n * (`BIND_*`, `RUB_AI_CHECKS_DISABLED`), and those already carry a message written for the author —\n * e.g. naming the AI checks a collection has switched off. Use it rather than render a blank line,\n * which is what a bare `DIAGNOSTIC_TEXT[code]` lookup does for an unknown key.\n */\nexport function problemText(problem: { code: string; message: string }): string {\n return DIAGNOSTIC_TEXT[problem.code as RubricDiagnosticCode] ?? problem.message;\n}\n\n/**\n * A SHAPE (Ajv `RUB_SCHEMA`) problem, in plain words chosen by WHERE in the\n * document it is (§A.11) — the fix for a message that used to lie.\n *\n * `RUB_SCHEMA` is a catch-all: any shape the engine's strict schema rejects. The\n * generic \"open the rule and check its options\" line is only honest when the\n * problem maps to a RULE the author can open on its card (`hasCard`). A shape\n * error that maps to no card must say what it actually is — the form binding, the\n * reviewer, the thresholds — instead of blaming the form link for everything. The\n * `path` is the section key from `schemaGate`'s `sectionPath`.\n *\n * \"The form link needs refreshing\" is reserved for a genuine BINDING failure\n * (`/claimSchema` — empty `protocol`, wrong `resource`); an empty `proof` is its\n * own, more specific case.\n */\nexport function schemaProblemText(path: string, hasCard: boolean): string {\n if (hasCard) return DIAGNOSTIC_TEXT.RUB_SCHEMA;\n if (path === '/claimSchema/proof') return 'This form has no fingerprint yet — reopen the collection so its form is pinned to these rules before publishing.';\n if (path.startsWith('/claimSchema')) return 'The form link needs refreshing — reopen the collection to reconnect these rules to its questions.';\n if (path.startsWith('/review/assignTo')) return 'This review’s assigned person uses an old setting — re-pick the reviewer.';\n if (path.startsWith('/review')) return 'The “a person checks” settings have something the rules service will not accept — re-open that rule and re-pick its options.';\n if (path.startsWith('/scoring')) return 'The approval scoring has a setting the rules service will not accept — check the approve score and how the rules add up.';\n if (path.startsWith('/settlement')) return 'The payout settings have a value the rules service will not accept.';\n if (path.startsWith('/derived')) return 'One of your calculated values has a setting the rules service will not accept.';\n if (path.startsWith('/sources')) return 'One of your external checks has a setting that isn’t valid — check its web address, its audience, and that it sends at least one value.';\n if (path.startsWith('/aiChecks')) return 'One of your AI checks has a setting that isn’t valid — re-open its rule and make sure it has at least one written rule to check.';\n if (path.startsWith('/unique')) return 'The “must be unique” rule has a setting the rules service will not accept — re-pick its answers and thresholds.';\n if (path.startsWith('/frequency')) return 'The “how often” limit has a setting the rules service will not accept — re-pick its number and period.';\n // Truly document-level (e.g. no reject rules and no scored questions at all).\n return 'These rules are missing something the rules service needs — add at least one reject rule or scored question.';\n}\n\n// ---------------------------------------------------------------------------\n// Sentences\n// ---------------------------------------------------------------------------\n\n/** An external-check answer (§A.14) in the author's words — never the raw `ext.` path (§B.5 rule 1). */\nconst EXT_REF = /^ext\\.([A-Za-z0-9_-]+)\\.(valid|score|reason)$/;\nfunction describeExtRef(ref: string, quoted: boolean): string {\n const match = EXT_REF.exec(ref);\n if (!match) return ref;\n const [, name, fieldName] = match;\n const label = quoted ? `the “${name}” check` : `${name} check`;\n if (fieldName === 'score') return `${label} score`;\n if (fieldName === 'reason') return `${label} reason`;\n return label;\n}\n\n/** An AI-check answer (§A.15) in the author's words — `ai.batchNumber_ai.valid` → \"batchNumber AI check\". */\nconst AI_REF = /^ai\\.([A-Za-z0-9_-]+)\\.(valid|reason)$/;\nfunction describeAiRef(ref: string): string {\n const match = AI_REF.exec(ref);\n if (!match) return ref;\n const [, name, fieldName] = match;\n const label = `${name.replace(/_ai(_\\d+)?$/, '')} AI check`;\n return fieldName === 'reason' ? `${label} reason` : label;\n}\n\n/** A question's title, as the author named it on the form — or an external/AI check's answer. */\nexport function fieldTitle(path: string, ctx: PhraseContext): string {\n if (path.startsWith('ai.')) return describeAiRef(path);\n if (path.startsWith('ext.')) return describeExtRef(path, false);\n // Calculated values (§A.7) went with scoring — nothing in the builder writes a\n // `~ref` any more, so one honest phrase covers a document that still has one.\n if (path.startsWith('~')) return 'a calculated value';\n const field = ctx.fields.get(path);\n if (field) return field.title;\n const rowPath = path.replace('[*]', '');\n return ctx.fields.get(rowPath)?.title ?? path.replace(/^\\$/, '');\n}\n\n/** A choice question stores `value` and displays `text` (§A.3) — always read back the text. */\nexport function choiceText(value: unknown, field: RubricField | undefined): string {\n const match = field?.choices?.find((choice) => choice.value === value);\n return match ? match.text : String(value);\n}\n\n/** One value, in the author's words: a choice's text, a date, a named value, or another answer. */\nfunction valueText(value: unknown, field: RubricField | undefined, ctx: PhraseContext): string {\n if (value === undefined || value === null) return '…';\n if (Array.isArray(value)) return value.map((entry) => valueText(entry, field, ctx)).join(', ') || '…';\n if (typeof value === 'object' && '@value' in (value as Record<string, unknown>)) return String((value as Record<string, unknown>)['@value']);\n if (typeof value === 'object') return JSON.stringify(value);\n if (typeof value === 'string') {\n if (value.startsWith('$')) return `the answer to “${fieldTitle(value, ctx)}”`;\n if (value.startsWith('ext.')) return describeExtRef(value, true);\n if (value in CTX_LABEL) return CTX_LABEL[value as RubricCtxToken];\n // A ~calculated value reads back as the sentence that built it.\n if (value.startsWith('~')) return fieldTitle(value, ctx);\n }\n return choiceText(value, field);\n}\n\n/** The value half of a sentence: \"500\", \"BRA_1, BRA_2\", \"2 and 8\", \"a PDF\". */\nexport function describeValue(op: RubricOperator, value: unknown, field: RubricField | undefined, ctx: PhraseContext): string {\n if (takesNoValue(op)) return '';\n if (op === 'mediaTypeIn') {\n const globs = Array.isArray(value) ? value : [];\n return globs.map((glob) => MEDIA_TYPES.find((m) => m.value === glob)?.label ?? String(glob)).join(' or ') || '…';\n }\n if (op === 'between' || op === 'lengthBetween' || op === 'countBetween') {\n const pair = Array.isArray(value) ? value : [];\n return `${valueText(pair[0], field, ctx)} and ${valueText(pair[1], field, ctx)}`;\n }\n if (op === 'withinRadius') {\n const spec = (value ?? {}) as { center?: unknown; meters?: unknown };\n return `${valueText(spec.center, field, ctx)}, within ${String(spec.meters ?? '…')} m`;\n }\n return valueText(value, field, ctx);\n}\n\n/** \"Delivery date must be during the collection period\" — the sentence, for any condition shape. */\nexport function describeCondition(cond: RubricCondition | undefined, ctx: PhraseContext, rowOf?: string): string {\n if (!cond) return 'nothing to check';\n if ('forEach' in cond && typeof cond.forEach === 'string') {\n const inner = cond.every ?? cond.some;\n const lead = cond.every ? 'every row' : 'at least one row';\n return `${lead} of “${fieldTitle(cond.forEach, ctx)}”: ${describeCondition(inner, ctx, cond.forEach)}`;\n }\n // Compound shapes (linked-rules design Part 1). The builder writes these only\n // as a grown rule's `when` (which has its own sentence, `describeGrown`), so\n // this prose is the honest fallback for a hand-authored compound anywhere else.\n if ('all' in cond && Array.isArray(cond.all)) return cond.all.map((member) => describeCondition(member, ctx, rowOf)).join(', and ');\n if ('any' in cond && Array.isArray(cond.any)) return cond.any.map((member) => describeCondition(member, ctx, rowOf)).join(', or ');\n if ('not' in cond) return `it is not the case that ${describeCondition(cond.not, ctx, rowOf)}`;\n if ('atLeast' in cond && Array.isArray(cond.of)) return `at least ${cond.atLeast} of: ${cond.of.map((member) => describeCondition(member, ctx, rowOf)).join('; ')}`;\n if (!('field' in cond)) return 'nothing to check';\n\n // Inside a forEach the ref is row-relative (`.col`) — read it against the column.\n const path = cond.field.startsWith('.') && rowOf ? `${rowOf}[*]${cond.field}` : cond.field;\n const field = ctx.fields.get(path);\n const phrase = OPERATOR_PHRASE[cond.op];\n if (!phrase) return `“${fieldTitle(path, ctx)}” has a check we no longer recognise`;\n const value = describeValue(cond.op, cond.value, field, ctx);\n const tolerance = cond.op === 'approx' && typeof cond.tolerance === 'number' ? `(give or take ${cond.tolerance})` : '';\n return [`“${fieldTitle(path, ctx)}”`, phrase.label, value, phrase.suffix, tolerance].filter(Boolean).join(' ');\n}\n\n/** What a person is asked, and what their answer does. */\nfunction describeReviewTask(rule: Extract<UiRule, { consequence: 'human' }>, ctx: PhraseContext): string {\n const task = rule.task;\n if (!task) return `a person checks “${fieldTitle(rule.fieldPath, ctx)}” — but there is no question to ask them yet`;\n const outcomes = Object.entries(task.map ?? {}).map(([answer, verdict]) => `${answerLabel(answer)} → ${VERDICT_LABEL[verdict]}`);\n // A machine can tell a photo is absent; it cannot tell what is in one. So a\n // missing answer is decided without anybody (§A.9) — say which way it goes.\n const score = rule.criterion.score;\n const missing = score?.['@type'] === 'ManualScore' ? ` If nothing was attached, nobody is asked and the check ${score.whenMissing === FAILED ? 'fails' : 'passes'}.` : '';\n return `A person answers: “${task.prompt}” ${outcomes.join(' · ')}${missing}`;\n}\n\nconst VERDICT_LABEL: Record<'approve' | 'partial' | 'reject', string> = {\n approve: 'approve',\n partial: 'part-approve',\n reject: 'reject',\n};\n\n/** A review answer key as the reviewer will see it (`\"true\"` is a Yes button, not a word). */\nexport function answerLabel(answer: string): string {\n if (answer === 'true') return 'Yes';\n if (answer === 'false') return 'No';\n return answer;\n}\n\n/** The \"Only check this if…\" lead-in (`appliesWhen`, §A.6/§A.8) — \"If X — …\". */\nfunction appliesWhenLead(cond: RubricCondition | undefined, ctx: PhraseContext): string {\n return cond ? `If ${describeCondition(cond, ctx)} — ` : '';\n}\n\n/** THE sentence: how a rule reads back on its card. */\nexport function describeRule(rule: UiRule, ctx: PhraseContext): string {\n switch (rule.consequence) {\n case 'reject': {\n // A score check's bands (§A.14 score) restate all three zones — the floor\n // gate is this card's too, so its meaning must be in this one sentence.\n if (rule.bands) {\n return `${appliesWhenLead(rule.gate.appliesWhen, ctx)}${describeScoreBands(rule.fieldPath, rule.bands, ctx)}`;\n }\n // A rule that GREW (owner 2026-08-03) restates its WHOLE meaning on every\n // change — every check, the knob, the ending — not the raw compound prose.\n if (rule.grown?.editable) {\n return describeGrown({ members: rule.grown.members, onFail: rule.gate.onFail, reason: rule.gate.reason, appliesWhen: rule.gate.appliesWhen }, ctx);\n }\n const check = describeCondition(rule.gate.when, ctx);\n const outcome = rule.gate.onFail === 'review' ? 'else a person checks it' : `else reject: “${rule.gate.reason}”`;\n return `${appliesWhenLead(rule.gate.appliesWhen, ctx)}${check} — ${outcome}`;\n }\n case 'human':\n return `${appliesWhenLead(rule.criterion.appliesWhen, ctx)}${describeReviewTask(rule, ctx)}`;\n default:\n return '';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Score checks (§A.14 `expect: 'score'`) — the bands' language\n// ---------------------------------------------------------------------------\n\n/** The answer-type choice on an outside check — yes/no, or a score out of 100. */\nexport const EXT_ANSWER_TYPE_LABEL = 'What does it answer?';\nexport const EXT_ANSWERS_BOOLEAN_LABEL = 'Yes or no';\nexport const EXT_ANSWERS_SCORE_LABEL = 'A score out of 100';\n\n/** The HOLD gate's stored reason — generated, never typed (the author's own words go on the floor gate). */\nexport const SCORE_HOLD_REASON = 'The check’s score is in the middle band — a person decides';\n\n/** The FLOOR gate's fallback rejection when the author writes none. */\nexport const SCORE_FLOOR_REASON = 'The check’s score is too low';\n\n/** The message box's label when a score check has a reject band. */\nexport const SCORE_MESSAGE_LABEL = 'What should the claimant be told when the score is too low?';\n\n/** THE score-bands sentence: all three zones, reject band first when there is one. */\nexport function describeScoreBands(fieldPath: string, bands: { approveAt: number; rejectBelow: number }, ctx: PhraseContext): string {\n const question = `“${fieldTitle(fieldPath, ctx)}”`;\n const approveAt = Math.round(bands.approveAt / 100);\n const rejectBelow = Math.round(bands.rejectBelow / 100);\n if (rejectBelow <= 0) {\n return `The outside service scores ${question} out of 100 — below ${approveAt} a person checks it; at ${approveAt} or more it passes`;\n }\n return `The outside service scores ${question} out of 100 — below ${rejectBelow} the claim is turned down; from ${rejectBelow} to ${approveAt - 1} a person checks it; at ${approveAt} or more it passes`;\n}\n\n// ---------------------------------------------------------------------------\n// Grown rules and linked rules (owner 2026-08-03)\n// ---------------------------------------------------------------------------\n\n/** The single-rule editor's one quiet growth affordance — the ONLY way a rule gains checks (owner 2026-08-03). */\nexport const GROW_RULE_LABEL = 'Add another check to this rule';\n\n/** The grown checks box's header label. All the checks must pass — the knob is retired (proposal v3). */\nexport const GROWN_CHECKS_LABEL = 'The checks';\n\nexport const LINKED_ADD_LABEL = 'Depends on another answer';\n\n// ---------------------------------------------------------------------------\n// The AI lane (§A.15) — the same wording family everywhere the lane appears\n// ---------------------------------------------------------------------------\n\n/** The one name of the lane — the check dropdown's entry in every editor that offers it. */\nexport const AI_CHECK_LANE_LABEL = 'AI checks it';\n\n/** The lead word of an AI member row in a grown rule (\"The AI checks [question]\"). */\nexport const GROUP_AI_MEMBER_LEAD = 'The AI checks';\n\n/** The middle of an AI-mode case row (\"If it is [x], the AI checks: [...]\"). */\nexport const LINKED_AI_ROW_LEAD = 'the AI checks:';\nexport const LINKED_AI_ELSE_LEAD = 'For anyone else, the AI checks:';\nexport const LINKED_AI_PLACEHOLDER = 'e.g. The invoice must show a salary of 3000';\nexport const LINKED_MISSING_AI_TEXT = 'Every case needs what the AI should check, written in plain words.';\n\n/** The \"what the AI can see\" picker — extra answers sent alongside the checked one. */\nexport const AI_SEES_LABEL = 'What can the AI see?';\nexport const AI_SEES_PLACEHOLDER = 'Add other answers the AI should see';\nexport function aiSeesHint(questionTitle: string): string {\n return `The answer it checks — “${questionTitle}” — is always sent. Add any other answers the AI should read; photos and files are sent as the files themselves.`;\n}\n\n/**\n * AI checks are a per-collection paid opt-in on the Evaluation Engine block, and\n * the rule editors cannot see that setting. With it off the check never runs and\n * every claim reading it is held for review — so it is said up front rather than\n * at publish. The engine's pre-publish check (§C.7, `RUB_AI_CHECKS_DISABLED`) is\n * the hard stop; this is the hint that avoids reaching it.\n */\nexport const AI_SETTING_HINT = 'Needs “AI checks” switched on for this collection in the Evaluation Engine block — without it these rules can’t run and claims wait for a person.';\n\n/** The quiet read-only row for a compound the builder cannot represent (nested by hand, `not`, an unrepresentable member…). */\nexport const GROUP_OUTSIDE_BUILDER_TEXT = 'This rule was written outside the builder. It is applied exactly as written — the advanced view below shows it in full.';\n\n/** Two case rows about the same value would overlap — the hole the table exists to prevent. */\nexport const LINKED_DUPLICATE_CASE_TEXT = 'Two of your cases are about the same value — every case must be different.';\nexport const LINKED_MISSING_CASE_TEXT = 'Every case needs a value to check against.';\n\n/** What `describeGrown` needs to say its sentence — a rule that holds several checks. */\nexport interface GrownSentence {\n members: SimpleRule[];\n onFail?: 'reject' | 'review';\n reason: string;\n appliesWhen?: RubricCondition;\n}\n\n/**\n * THE grown-rule sentence — restates the rule's whole meaning on every change.\n * Several checks in one rule always mean ALL of them (proposal v3), so the\n * sentence names every check: \"“Invoice” must be filled in, and “Receipt”\n * must be filled in — otherwise…\".\n */\nexport function describeGrown(rule: GrownSentence, ctx: PhraseContext): string {\n const lead = rule.members.map((member) => describeGroupMember(member, ctx)).join(', and ');\n const outcome = rule.onFail === 'review' ? 'otherwise a person checks it' : `otherwise reject: “${rule.reason}”`;\n return `${appliesWhenLead(rule.appliesWhen, ctx)}${lead} — ${outcome}`;\n}\n\n/**\n * One case of a linked rule, as it reads inside a gate's generated reason:\n * \"when “Employee name” is “Youssef”\". Shared by the sentence below and the\n * reason writer in `ruleDraft`, so the two can never drift apart.\n */\nexport function linkedCaseText(guardField: string, guardValue: unknown, ctx: PhraseContext): string {\n return `when “${fieldTitle(guardField, ctx)}” is “${describeValue('==', guardValue, ctx.fields.get(guardField), ctx)}”`;\n}\n\n/** The permanent last row's case text. */\nexport function linkedElseText(): string {\n return 'for anyone else';\n}\n\n/** What `describeLinked` needs to say its sentence — the draft and the model both produce it. */\nexport interface LinkedSentence {\n checkedField: string;\n op: RubricOperator;\n guardField: string;\n cases: { guardValue?: unknown; value?: unknown; instructions?: string }[];\n elseValue?: unknown;\n /** AI mode: every case's \"it must be\" is what the AI checks, in the author's words. */\n ai?: boolean;\n elseInstructions?: string;\n}\n\n/** The linked model, as the one sentence writer wants it — value and AI tables alike. */\nexport function linkedSentenceOf(entry: LinkedRule): LinkedSentence {\n return {\n checkedField: entry.checkedField,\n op: entry.op,\n guardField: entry.guardField,\n cases: entry.cases.map((c) => ({ guardValue: c.guardValue, value: c.when.value, instructions: c.instructions })),\n elseValue: entry.elseCase.when.value,\n ...(entry.ai ? { ai: true, elseInstructions: entry.elseCase.instructions } : {}),\n };\n}\n\n/** THE linked sentence: \"If “Employee name” is “Youssef”, “Salary” must be exactly 3000. For anyone else it must be exactly 4000.\" */\nexport function describeLinked(linked: LinkedSentence, ctx: PhraseContext): string {\n const guard = ctx.fields.get(linked.guardField);\n // AI mode: \"If “Name” is “yousef”, the AI checks “Invoice”: “…”. For anyone else: “…”.\"\n if (linked.ai) {\n const rules = (instructions: string | undefined) => `“${(instructions ?? '').trim() || '…'}”`;\n const parts = linked.cases.map((entry, at) => {\n const guardText = `“${describeValue('==', entry.guardValue, guard, ctx)}”`;\n return at === 0\n ? `If “${fieldTitle(linked.guardField, ctx)}” is ${guardText}, the AI checks “${fieldTitle(linked.checkedField, ctx)}”: ${rules(entry.instructions)}.`\n : `If it is ${guardText}: ${rules(entry.instructions)}.`;\n });\n parts.push(`For anyone else: ${rules(linked.elseInstructions)}.`);\n return parts.join(' ');\n }\n const phrase = OPERATOR_PHRASE[linked.op];\n const checked = ctx.fields.get(linked.checkedField);\n const check = (value: unknown) => [phrase.label, describeValue(linked.op, value, checked, ctx), phrase.suffix].filter(Boolean).join(' ');\n const parts = linked.cases.map((entry, at) => {\n const guardText = `“${describeValue('==', entry.guardValue, guard, ctx)}”`;\n return at === 0\n ? `If “${fieldTitle(linked.guardField, ctx)}” is ${guardText}, “${fieldTitle(linked.checkedField, ctx)}” ${check(entry.value)}.`\n : `If it is ${guardText}, it ${check(entry.value)}.`;\n });\n parts.push(`For anyone else it ${check(linked.elseValue)}.`);\n return parts.join(' ');\n}\n\n/** One check of a grown rule, as its own phrase — the same sentence a single-check rule reads back as. */\nexport function describeGroupMember(member: SimpleRule, ctx: PhraseContext): string {\n // An AI member reads as what it IS — never the raw `ai.` ref (§B.5 rule 1).\n const name = aiMemberName(member);\n const check = name ? ctx.aiChecks?.find((entry) => entry.name === name) : undefined;\n if (check) {\n const anchor = Object.values(check.send).find((value): value is string => typeof value === 'string' && value.startsWith('$'));\n const rules = check.instructions.filter((rule) => rule.trim().length > 0).join('; ');\n return anchor ? `the AI checks “${fieldTitle(anchor, ctx)}”: “${rules}”` : `the AI checks it: “${rules}”`;\n }\n return describeCondition(toCondition(member), ctx);\n}\n\n// ---------------------------------------------------------------------------\n// The approval policy (owner 2026-08-03, proposal v3) — the tabs' language\n// ---------------------------------------------------------------------------\n\n/** The three tabs of \"When is a claim approved?\" — never the words AND, OR or quorum. */\nexport const POLICY_TAB_LABEL: Record<'all' | 'any' | 'atLeast', string> = {\n all: 'All of them',\n any: 'Any of them',\n atLeast: 'At least…',\n};\n\n/** The pin chip on a policy row — a rule the tally never excuses. */\nexport const POLICY_PIN_LABEL = 'Must always pass';\n\n/** The policy gate's rejection wording when the author writes none. */\nexport const POLICY_DEFAULT_REASON = 'Not enough of the checks passed';\n\n/** A non-default tab with an empty tally — nothing is folded until a rule is ticked in. */\nexport const POLICY_EMPTY_TALLY_TEXT = 'Tick the rules that should count — until then, every check must still pass.';\n\n/** A non-default tab before any rule exists at all. */\nexport const POLICY_NO_RULES_TEXT = 'No rules yet — add a rule to a question above, then choose how many must pass.';\n\n/** The approval rule was hand-authored in a shape the tabs cannot edit (two policy gates, nesting, …). */\nexport const POLICY_OUTSIDE_BUILDER_TEXT = 'The approval rule was written outside the builder. It is applied exactly as written — the advanced view below shows it in full.';\n\n/** The stepper's trailing words — the displayed count runs over every SELECTED rule, pins included. */\nexport function policyStepperText(selectedCount: number): string {\n return `of the ${plural(selectedCount, 'selected rule')} must pass`;\n}\n\n/** \"“A”, “B” and “C”\" — the pinned rules, named by their questions. */\nfunction listOf(parts: string[]): string {\n if (parts.length <= 1) return parts[0] ?? '';\n return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;\n}\n\n/**\n * One policy row's sentence for a rule that lives INSIDE the policy gate (a\n * folded member, no gate of its own): the member's whole `when` — one builder\n * sentence, or an `all` compound of them, named check by check.\n */\nexport function describePolicyMember(member: RubricCondition, ctx: PhraseContext): string {\n const simple = toSimpleRule(member);\n if (simple) return describeGroupMember(simple, ctx);\n if ('all' in member && Array.isArray(member.all)) {\n const parts = member.all.map((inner) => {\n const innerSimple = toSimpleRule(inner);\n return innerSimple ? describeGroupMember(innerSimple, ctx) : describeCondition(inner, ctx);\n });\n return parts.join(', and ');\n }\n return describeCondition(member, ctx);\n}\n\n/**\n * THE approval-policy sentence — the honest arithmetic over what is actually\n * enforced: the pinned rules by name, then how many of the rest must also\n * pass. `n` is the DISPLAYED count (pins included), exactly what the stepper\n * shows; the sentence subtracts the pins itself.\n */\nexport function describePolicy(input: { tab: 'any' | 'atLeast'; pinned: string[]; restCount: number; n: number; reason: string }): string {\n const { tab, pinned, restCount, n, reason } = input;\n const outcome = `— otherwise reject: “${reason}”`;\n const rules = plural(restCount, 'rule');\n if (pinned.length === 0) {\n return tab === 'any' ? `Any one of the ${rules} must pass ${outcome}` : `At least ${n} of the ${rules} must pass ${outcome}`;\n }\n const names = listOf(pinned.map((title) => `“${title}”`));\n const beyond = pinned.length === 1 ? 'Beyond that' : 'Beyond those';\n const rest = tab === 'any' ? `any one of the other ${rules} must also pass` : `at least ${n - pinned.length} of the other ${rules} must also pass`;\n return `${names} must always pass. ${beyond}, ${rest} ${outcome}`;\n}\n\n// ---------------------------------------------------------------------------\n// The duplicate rule (dup-detection spec §6) — \"This claim must be unique\"\n// ---------------------------------------------------------------------------\n\n/** The section's title — the toggle beside it turns the whole rule on and off. */\nexport const UNIQUE_TITLE = 'This claim must be unique';\n\n/** What the rule does, in the author's words — names the honest-fix path (rejected priors never block). */\nexport const UNIQUE_EXPLAINER =\n 'Claims already in this collection are compared with each new one — exact copies, re-saved files and near-identical wording are caught. A claim that was rejected never blocks a fixed resubmission.';\n\n/** The key picker. Empty = the whole claim is the key. */\nexport const UNIQUE_BY_LABEL = 'Unique by…';\nexport const UNIQUE_BY_PLACEHOLDER = 'Pick the answers that identify a claim';\nexport const UNIQUE_BY_HINT = 'Two claims matching on ALL of these count as the same claim. Leave empty to compare whole claims.';\n\n/** The badge on a file-kind option: copies are caught by fingerprint, not bytes. */\nexport const UNIQUE_FILE_BADGE = 'matched by file fingerprint';\n\n/**\n * The per-date-field coarseness select (engine `UniqueBy.granularity`) — the row\n * reads as one sentence: \"Dates in “Pay period” match … in the same month\".\n * \"exactly\" is the default and emits nothing: the exact value is the engine's\n * own meaning for a plain ref.\n */\nexport const UNIQUE_GRANULARITY_OPTIONS: { value: 'exact' | 'day' | 'month' | 'year'; label: string }[] = [\n { value: 'exact', label: 'exactly' },\n { value: 'day', label: 'on the same day' },\n { value: 'month', label: 'in the same month' },\n { value: 'year', label: 'in the same year' },\n];\n\n/** The lead of a granularity row — the sentence the select finishes. */\nexport function uniqueGranularityLead(title: string): string {\n return `Dates in “${title}” match`;\n}\n\n/** The gray-zone AI judge — no billing suffix: screening is priced into the per-claim fee. On by default, like the engine (T18). */\nexport const UNIQUE_AI_LABEL = 'Use AI to catch reworded duplicates';\n\n/** What the judge does with a similar-but-not-identical claim — the switch's own hint while it is on. */\nexport const UNIQUE_AI_ON_HINT = 'Similar-looking claims are checked by AI; matches go to human review.';\n\n/** The honest consequence of switching the judge off (owner 2026-08-05) — said where the author decides, not at publish. */\nexport const UNIQUE_AI_OFF_WARNING = 'Without AI checking, similar-looking claims pass with only a recorded score.';\n\n/** Names the pricing honestly (§B.3 disclosure discipline): screening costs nothing extra. */\nexport const UNIQUE_PRICING_NOTE = 'Duplicate screening — fingerprints, similarity and AI checks — is included in this collection’s per-claim price.';\n\n/** The two threshold sliders — percent on screen, bps in the document. */\nexport const UNIQUE_REJECT_LABEL = 'Auto-reject at';\nexport const UNIQUE_REVIEW_LABEL = 'Send to review at';\n\n// ---------------------------------------------------------------------------\n// The frequency rule (dup-detection spec §13) — \"Limit how often each person can claim\"\n// ---------------------------------------------------------------------------\n\n/** The section's title — the toggle beside it turns the whole limit on and off. */\nexport const FREQUENCY_TITLE = 'Limit how often each person can claim';\n\n/** What the limit does, in the author's words — names the honest-fix path (rejected claims never use up a turn). */\nexport const FREQUENCY_EXPLAINER =\n 'Counts how many claims each person has already sent this calendar period — however different their content. A claim that was rejected never uses up a turn, so a fixed resubmission always fits.';\n\n/** The max stepper's trailing words — with the period select it reads as one sentence: \"At most [2] claims [per month]\". */\nexport const FREQUENCY_MAX_LEAD = 'At most';\nexport function frequencyMaxNoun(max: number): string {\n return max === 1 ? 'claim' : 'claims';\n}\n\n/** The period select's screen-reader name — its visible face is the sentence it finishes. */\nexport const FREQUENCY_PERIOD_ARIA = 'The period the limit counts over';\n\n/** The calendar periods, in plain words — the select the stepper's sentence ends with. */\nexport const FREQUENCY_PERIOD_OPTIONS: { value: 'day' | 'week' | 'month' | 'year'; label: string }[] = [\n { value: 'day', label: 'per day' },\n { value: 'week', label: 'per week' },\n { value: 'month', label: 'per month' },\n { value: 'year', label: 'per year' },\n];\n\n/** What happens to a claim over the limit — a person checks (default), or it is turned down. */\nexport const FREQUENCY_BREACH_LABEL = 'When someone goes over the limit';\nexport const FREQUENCY_BREACH_OPTIONS: { value: 'review' | 'reject'; label: string }[] = [\n { value: 'review', label: 'A person checks' },\n { value: 'reject', label: 'Reject the claim' },\n];\n\n/** The one-line hint under the default: review means a human sees it before anything is decided. */\nexport const FREQUENCY_BREACH_REVIEW_HINT = 'A claim over the limit is sent to a person to look at — nothing is turned down automatically.';\n\n// ---------------------------------------------------------------------------\n// The summary bar\n// ---------------------------------------------------------------------------\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? '' : 's'}`;\n}\n\n/**\n * \"4 reject rules · 1 human check · 1 linked rule\" (§B.5's summary bar). A\n * grown rule is ONE rule, counted with the rest; a rule folded into the\n * approval policy is still a reject rule (`policyMembers`), just not a\n * standalone gate any more.\n */\nexport function describeTally(rules: UiRule[], extra?: { linked?: number; policyMembers?: number }): string {\n const parts = [\n plural(rules.filter((r) => r.consequence === 'reject').length + (extra?.policyMembers ?? 0), 'reject rule'),\n plural(rules.filter((r) => r.consequence === 'human').length, 'human check'),\n ];\n if (extra?.linked) parts.push(plural(extra.linked, 'linked rule'));\n return parts.join(' · ');\n}\n\n/**\n * The approval rule, in the author's words. v1 has one: every check must pass\n * (`all_pass`), so this counts what the author can see on the cards rather than\n * reading a threshold nobody sets.\n */\nexport function describeApproval(checkCount: number): string {\n if (checkCount === 0) return 'When every check passes. No checks yet — add a rule to a question above.';\n if (checkCount === 1) return 'When the one check passes.';\n return `When all ${checkCount} checks pass.`;\n}\n","import { FORM_SEGMENT } from '@/core/lib/actionRegistry/actions/evalRubric/pathGrammar';\nimport type {\n RubricAiCheck,\n RubricAtLeastCondition,\n RubricBody,\n RubricCondition,\n RubricCriterion,\n RubricExternalSource,\n RubricField,\n RubricFieldCatalog,\n RubricFieldKind,\n RubricGate,\n RubricGateClass,\n RubricOperator,\n RubricReviewTask,\n RubricScoreNode,\n RubricScoringMethod,\n RubricSimpleCondition,\n} from '@/core/lib/actionRegistry/actions/evalRubric/types';\n\n/**\n * The UI's view OF the rubric document — rubric-spec §B.5 rule 2 (\"one card per\n * form question\"). Pure structure, no language (that's `./phrases`) and no\n * React: the document is a flat rulebook (`gates[]`, `scoring.criteria[]`,\n * `review.tasks[]`), while the author sees rules grouped under the question\n * they are about. This module is the mapping between the two, in both\n * directions, and the only place that mutates the body.\n *\n * The grouping is DERIVED, never stored: a rule belongs to the card of the\n * question its condition/score points at (`primaryFieldOf`). The format has no\n * \"which card\" key and must not grow one — the document is the engine's input,\n * not the builder's state.\n */\n\n// ---------------------------------------------------------------------------\n// The catalog index — every addressable path, containers' inner fields included\n// ---------------------------------------------------------------------------\n\nexport type FieldIndex = Map<string, RubricField>;\n\n/** Index every addressable path (`$q`, `$q.row.col`, `$q[*].col`) → its field. */\nexport function indexCatalog(catalog: RubricFieldCatalog | null | undefined): FieldIndex {\n const index: FieldIndex = new Map();\n const add = (field: RubricField) => {\n index.set(field.path, field);\n field.columns?.forEach(add);\n };\n for (const field of catalog?.fields ?? []) add(field);\n return index;\n}\n\n/**\n * The card a path belongs to: `$items.SKU_1.Quantity` → `$items`. With the card\n * set in hand, the longest known card that prefixes the path wins — a dotted\n * QUESTION name (cellnode-era path manifests, where `claim.type` is itself a\n * whole question) is its own card, while container sub-paths still land on\n * their container's. Without the set (ext refs, tests), the first segment\n * stands, which is only correct for single-segment question names.\n */\nexport function rootPath(path: string, cards?: ReadonlySet<string>): string {\n if (cards) {\n for (let prefix = path; ; ) {\n if (cards.has(prefix)) return prefix;\n const cut = Math.max(prefix.lastIndexOf('.'), prefix.lastIndexOf('['));\n if (cut <= 0) break;\n prefix = prefix.slice(0, cut);\n }\n }\n return FIELD_ROOT.exec(path)?.[0] ?? path;\n}\n\n/** The whole first segment of a `$field` ref, namespace prefix included (`$ixo:hiveId`). */\nconst FIELD_ROOT = new RegExp(`^\\\\$${FORM_SEGMENT}`);\n\n/** A container question's own path plus each inner field it can be asked about. */\nexport function targetableFields(field: RubricField): RubricField[] {\n return [field, ...(field.columns ?? [])];\n}\n\n// ---------------------------------------------------------------------------\n// External checks (§A.14) — an ext-subject rule is a rule ON a question\n// ---------------------------------------------------------------------------\n\nconst EXT_REF = /^ext\\.([A-Za-z0-9_-]+)\\.(valid|score|reason)$/;\ntype ExtField = 'valid' | 'score' | 'reason';\n\n/** The kind an external-check answer field carries: a yes/no, a number, or writing. */\nfunction extFieldKind(fieldName: ExtField): RubricFieldKind {\n return fieldName === 'score' ? 'number' : fieldName === 'valid' ? 'boolean' : 'text';\n}\n\n/**\n * Resolve an `ext.<name>.<field>` ref to a synthetic field so the sentence\n * builder can type it like any other answer — but ONLY when the source exists\n * and the field fits its `expect` (so the pickers can never offer a broken ref).\n */\nexport function extRefField(ref: string, sources: RubricExternalSource[] | undefined): RubricField | undefined {\n const match = EXT_REF.exec(ref);\n if (!match) return undefined;\n const source = sources?.find((entry) => entry.name === match[1]);\n if (!source) return undefined;\n const fieldName = match[2] as ExtField;\n if (fieldName === 'valid' && source.expect !== 'boolean') return undefined;\n if (fieldName === 'score' && source.expect !== 'score') return undefined;\n const noun = fieldName === 'valid' ? 'passed?' : fieldName;\n return { path: ref, kind: extFieldKind(fieldName), title: `${source.name} check — ${noun}`, isRequired: false };\n}\n\n/**\n * The question an `ext.<name>.*` ref is ABOUT: the `$field` the source sends\n * (§A.14). An external check is a kind of rule on that question — its rules\n * list on that card, not on a card of their own. `undefined` when the source\n * is unknown or sends no form answer (the rare no-question fallback).\n */\nexport function extRefQuestion(ref: string, body: RubricBody | null | undefined): string | undefined {\n const name = EXT_REF.exec(ref)?.[1];\n const source = name ? body?.sources?.find((entry) => entry.name === name) : undefined;\n if (!source) return undefined;\n return Object.values(source.send).find((value): value is string => typeof value === 'string' && value.startsWith('$'));\n}\n\n// ---------------------------------------------------------------------------\n// AI checks (§A.15) — an ai-subject rule is a rule ON a question, like ext\n// ---------------------------------------------------------------------------\n\nconst AI_REF = /^ai\\.([A-Za-z0-9_-]+)\\.(valid|reason)$/;\n\n/**\n * Resolve an `ai.<name>.<field>` ref to a synthetic field — the AI-check twin\n * of `extRefField`. Only two answers exist: the yes/no (`valid`) and the AI's\n * written `reason`.\n */\nexport function aiRefField(ref: string, aiChecks: RubricAiCheck[] | undefined): RubricField | undefined {\n const match = AI_REF.exec(ref);\n if (!match) return undefined;\n const check = aiChecks?.find((entry) => entry.name === match[1]);\n if (!check) return undefined;\n const fieldName = match[2] as 'valid' | 'reason';\n return { path: ref, kind: fieldName === 'valid' ? 'boolean' : 'text', title: `${check.name} AI check — ${fieldName === 'valid' ? 'passed?' : 'reason'}`, isRequired: false };\n}\n\n/** The question an `ai.<name>.*` ref is ABOUT — the `$field` the check sends (mirrors `extRefQuestion`). */\nexport function aiRefQuestion(ref: string, body: RubricBody | null | undefined): string | undefined {\n const name = AI_REF.exec(ref)?.[1];\n const check = name ? body?.aiChecks?.find((entry) => entry.name === name) : undefined;\n if (!check) return undefined;\n return Object.values(check.send).find((value): value is string => typeof value === 'string' && value.startsWith('$'));\n}\n\n/** EXACTLY what the builder compiles an AI member/case to: `ai.<name>.valid` must be ticked. */\nconst AI_VALID_REF = /^ai\\.([A-Za-z0-9_-]+)\\.valid$/;\n\n/**\n * The check name a simple rule reads as the builder's own \"the AI checks it\"\n * shape — `undefined` for every other rule, including hand-authored oddities on\n * ai refs (`.reason`, another operator), which stay plain sentence rows.\n */\nexport function aiMemberName(member: SimpleRule): string | undefined {\n return member.op === 'isTrue' ? AI_VALID_REF.exec(member.field)?.[1] : undefined;\n}\n\n/**\n * The `$answer` list a check sends, anchor first — or `undefined` when any\n * entry is NOT a plain `$answer` (ctx/derived/literal payloads are hand-authored\n * territory the pickers cannot re-save without silently dropping them).\n */\nexport function aiSendFields(check: RubricAiCheck): string[] | undefined {\n const values = Object.values(check.send ?? {});\n if (values.length === 0) return undefined;\n return values.every((value): value is string => typeof value === 'string' && value.startsWith('$')) ? values : undefined;\n}\n\n/** `~name` in a value position; the global twin scans an expression for every `~ref` it carries. */\nconst DERIVED_VALUE_REF = /^~([A-Za-z0-9_-]+)$/;\nconst DERIVED_EXPR_REFS = /~([A-Za-z0-9_-]+)/g;\n\n/**\n * Drop every source, AI check AND calculated value no remaining rule reads\n * (§A.14/§A.15/§A.7) — run after any rule change, so deleting the last rule on\n * a check (or the last rule scoring a calculated value) removes it, while one\n * several rules share survives until the last reference goes. References are\n * found by walking every condition (fields AND values), every score node\n * (values AND anchors), the part-pay `prorateBy`, and — for calculated values —\n * the payloads of kept checks and the expressions of other kept calculations.\n */\nexport function pruneDanglingSources(body: RubricBody): RubricBody {\n const sources = body.sources ?? [];\n const aiChecks = body.aiChecks ?? [];\n const derived = body.derived ?? [];\n if (sources.length === 0 && aiChecks.length === 0 && derived.length === 0) return body;\n\n const used = new Set<string>();\n const usedAi = new Set<string>();\n const usedDerived = new Set<string>();\n const note = (value: unknown) => {\n if (typeof value === 'string') {\n const name = EXT_REF.exec(value)?.[1];\n if (name) used.add(name);\n const aiName = AI_REF.exec(value)?.[1];\n if (aiName) usedAi.add(aiName);\n const derivedName = DERIVED_VALUE_REF.exec(value)?.[1];\n if (derivedName) usedDerived.add(derivedName);\n } else if (Array.isArray(value)) {\n value.forEach(note);\n }\n };\n const walkCondition = (cond: RubricCondition | undefined) => {\n if (!cond || typeof cond !== 'object') return;\n if ('forEach' in cond) {\n walkCondition(cond.every);\n walkCondition(cond.some);\n return;\n }\n // Compound shapes (restored 2026-08-03, the linked-rules design Part 1) — a\n // member may read an ext/ai/~ ref, and missing it here would prune a check\n // that is still very much in use.\n if ('all' in cond) {\n cond.all.forEach(walkCondition);\n return;\n }\n if ('any' in cond) {\n cond.any.forEach(walkCondition);\n return;\n }\n if ('not' in cond) {\n walkCondition(cond.not);\n return;\n }\n if ('atLeast' in cond) {\n cond.of.forEach(walkCondition);\n return;\n }\n if ('field' in cond) {\n note(cond.field);\n note(cond.value);\n }\n };\n const walkScore = (score: RubricScoreNode | undefined) => {\n if (!score) return;\n switch (score['@type']) {\n case 'BooleanScore':\n walkCondition(score.when);\n break;\n case 'BandsScore':\n note(score.value);\n // A step's threshold may be a ~calculated anchor (§A.8).\n (score.bands ?? []).forEach((band) => 'op' in band && note(band.value));\n break;\n case 'LinearScore':\n note(score.value);\n note(score.zeroAt);\n note(score.fullAt);\n break;\n case 'MapScore':\n note(score.value);\n break;\n case 'LevelsScore':\n (score.levels ?? []).forEach((level) => 'when' in level && walkCondition(level.when));\n break;\n case 'DeductionsScore':\n (score.deduct ?? []).forEach((deduction) => walkCondition(deduction.when));\n break;\n default:\n break;\n }\n };\n for (const gate of body.gates ?? []) {\n walkCondition(gate.when);\n walkCondition(gate.appliesWhen);\n }\n for (const criterion of body.scoring?.criteria ?? []) {\n walkCondition(criterion.appliesWhen);\n walkScore(criterion.score);\n }\n note(body.settlement?.onPartial?.prorateBy);\n\n const kept = sources.filter((source) => used.has(source.name));\n const keptAi = aiChecks.filter((check) => usedAi.has(check.name));\n\n // A kept check's payload may send a calculated value — those stay alive.\n for (const source of kept) Object.values(source.send ?? {}).forEach(note);\n for (const check of keptAi) Object.values(check.send ?? {}).forEach(note);\n\n // Calculated values may reference one another (a % is built ON a total), so a\n // deletion can orphan a chain — iterate to a fixpoint: keep an entry only\n // while something LIVE still reads it.\n let keptDerived = derived;\n for (;;) {\n const live = new Set(usedDerived);\n for (const entry of keptDerived) {\n for (const match of entry.expr.matchAll(DERIVED_EXPR_REFS)) live.add(match[1]);\n }\n const next = keptDerived.filter((entry) => live.has(entry.name));\n if (next.length === keptDerived.length) break;\n keptDerived = next;\n }\n\n if (kept.length === sources.length && keptAi.length === aiChecks.length && keptDerived.length === derived.length) return body;\n return {\n ...body,\n sources: kept.length > 0 ? kept : undefined,\n aiChecks: keptAi.length > 0 ? keptAi : undefined,\n derived: keptDerived.length > 0 ? keptDerived : undefined,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Simple rules ↔ conditions\n// ---------------------------------------------------------------------------\n\n/**\n * The one shape the sentence builder edits: `[field] [operator] [value]`.\n *\n * A `[*]` path (a repeating table's column) is stored as the document's\n * `forEach`/`every` condition — \"Every row must …\" (§A.5) — and read back into\n * the same flat shape, so the author only ever meets one sentence.\n */\nexport interface SimpleRule {\n field: string;\n op: RubricOperator;\n value?: unknown;\n tolerance?: number;\n}\n\nexport function toCondition(rule: SimpleRule): RubricCondition {\n const inner: RubricSimpleCondition = {\n '@type': 'Condition',\n field: rule.field,\n op: rule.op,\n ...(rule.value !== undefined ? { value: rule.value } : {}),\n ...(rule.tolerance !== undefined ? { tolerance: rule.tolerance } : {}),\n };\n const rowIndex = rule.field.indexOf('[*]');\n if (rowIndex < 0) return inner;\n // `$rows[*].col` ⇒ every row's `.col` (§A.5 row-relative refs).\n return { '@type': 'Condition', forEach: rule.field.slice(0, rowIndex), every: { ...inner, field: rule.field.slice(rowIndex + 3) } };\n}\n\n/** The inverse of `toCondition`, or `undefined` for a condition the builder cannot render as one sentence. */\nexport function toSimpleRule(cond: RubricCondition | undefined): SimpleRule | undefined {\n if (!cond) return undefined;\n if ('forEach' in cond && typeof cond.forEach === 'string') {\n const every = cond.every;\n if (!every || !('field' in every) || typeof every.field !== 'string' || !every.field.startsWith('.')) return undefined;\n return { field: `${cond.forEach}[*]${every.field}`, op: every.op, value: every.value, tolerance: every.tolerance };\n }\n if ('field' in cond && typeof cond.field === 'string') return { field: cond.field, op: cond.op, value: cond.value, tolerance: cond.tolerance };\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Grown rules (owner 2026-08-03, v3) — one gate, an `all` compound, still ONE rule\n// ---------------------------------------------------------------------------\n\n/**\n * What a compound `when` reads back as. Several checks in one rule always mean\n * ALL of them (proposal v3 retired the per-rule knob — any/at-least live in the\n * rulebook-level approval policy now, `policyShapeOf`). `editable: false` is the\n * territory the rule editor cannot represent — an `any`/`atLeast` (the policy\n * family), a `not`, hand-authored nesting, an AI member whose check is missing\n * or whose send the pickers can't re-save — and renders as a quiet read-only\n * row rather than being flattened or hidden (never destroy what the UI can't\n * author).\n */\nexport type GroupShape = { editable: true; members: SimpleRule[] } | { editable: false };\n\n/**\n * The DERIVED grown-rule recognition — no stored keys, exactly like the card\n * grouping: a gate whose `when` is `{all: […]}` IS a rule that grew more\n * checks. Returns `undefined` for a non-compound `when` (an ordinary\n * single-check rule), and the shape otherwise: editable when every member\n * reads back as one builder sentence (`toSimpleRule`).\n *\n * `aiChecks` (pass the document's, `[]` when it has none) additionally demands\n * that every AI member's check EXISTS and is picker-representable (an\n * all-`$answer` send) — a member reading a missing check, or one whose\n * hand-authored ctx/derived send re-saving would silently drop, renders the\n * whole rule read-only (never crash, never silently drop). Callers that only\n * need \"is this compound?\" may omit it.\n */\nexport function groupShapeOf(when: RubricCondition | undefined, aiChecks?: RubricAiCheck[]): GroupShape | undefined {\n if (!when || typeof when !== 'object') return undefined;\n if ('not' in when) return { editable: false };\n // `any`/`atLeast` are the approval policy's shapes (proposal v3): a gate\n // carrying one is either THE policy (claimed by `policyShapeOf`, never a card\n // rule) or — more than one, malformed — a read-only leftover on its card.\n if ('any' in when || 'atLeast' in when || 'of' in when) return { editable: false };\n if (!('all' in when)) return undefined;\n const raw = when.all;\n if (!Array.isArray(raw) || raw.length === 0) return { editable: false };\n const members: SimpleRule[] = [];\n for (const member of raw) {\n const simple = toSimpleRule(member);\n if (!simple) return { editable: false };\n const aiName = aiMemberName(simple);\n if (aiName && aiChecks !== undefined) {\n const check = aiChecks.find((entry) => entry.name === aiName);\n if (!check || !aiSendFields(check)) return { editable: false };\n }\n members.push(simple);\n }\n return { editable: true, members };\n}\n\n// ---------------------------------------------------------------------------\n// The approval policy (owner 2026-08-03, proposal v3) — ONE any/atLeast gate\n// ---------------------------------------------------------------------------\n\n/**\n * A condition the policy's rule list can carry as one row: one builder\n * sentence (`toSimpleRule`), or an `all` compound of such sentences — exactly\n * what a folded rule's whole `when` can be. Nested `any`/`atLeast`, a `not`,\n * or a member no sentence fits make the policy gate unrepresentable.\n */\nexport function policyMemberRenderable(cond: RubricCondition | undefined): boolean {\n if (!cond || typeof cond !== 'object') return false;\n if (toSimpleRule(cond)) return true;\n if ('all' in cond && Array.isArray(cond.all) && cond.all.length > 0) return cond.all.every((member) => toSimpleRule(member) !== undefined);\n return false;\n}\n\n/**\n * The DERIVED approval-policy recognition — document doctrine, no stored\n * builder state:\n * - zero `any`/`atLeast` gates → `none` (the \"All of them\" tab);\n * - exactly ONE, with representable members, an in-bounds `atLeast`\n * (`1 ≤ n ≤ members` — n = members is legal, \"all spelled with a number\"),\n * and at most a simple `appliesWhen` → it IS the policy: claimed by the\n * approval section, never a card rule;\n * - anything else (two policy-family gates, nested compounds inside, a\n * compound guard) → `foreign`: the section renders read-only and the gates\n * stay read-only rules on their cards — deletable, never rewritten.\n */\nexport type PolicyShape =\n | { kind: 'none' }\n | { kind: 'foreign' }\n | { kind: 'policy'; index: number; gate: RubricGate; tab: 'any' | 'atLeast'; nRest?: number; members: RubricCondition[] };\n\nexport function policyShapeOf(body: RubricBody | null): PolicyShape {\n const gates = body?.gates ?? [];\n const candidates: number[] = [];\n gates.forEach((gate, index) => {\n const when = gate.when;\n if (when && typeof when === 'object' && ('any' in when || 'atLeast' in when || 'of' in when)) candidates.push(index);\n });\n if (candidates.length === 0) return { kind: 'none' };\n if (candidates.length > 1) return { kind: 'foreign' };\n const index = candidates[0];\n const gate = gates[index];\n const when = gate.when as Partial<RubricAtLeastCondition> & { any?: RubricCondition[] };\n const members = Array.isArray(when.any) ? when.any : Array.isArray(when.of) ? when.of : undefined;\n if (!members || members.length === 0) return { kind: 'foreign' };\n if (!members.every(policyMemberRenderable)) return { kind: 'foreign' };\n if (gate.appliesWhen && !toSimpleRule(gate.appliesWhen)) return { kind: 'foreign' };\n if (Array.isArray(when.any)) return { kind: 'policy', index, gate, tab: 'any', members };\n const n = when.atLeast;\n if (!Number.isInteger(n) || (n as number) < 1 || (n as number) > members.length) return { kind: 'foreign' };\n return { kind: 'policy', index, gate, tab: 'atLeast', nRest: n, members };\n}\n\n// ---------------------------------------------------------------------------\n// Linked rules (linked-rules design Part 3) — a case table over guarded gates\n// ---------------------------------------------------------------------------\n\n/** One named row of the case table, and the gate it compiled to. */\nexport interface LinkedCase {\n code: string;\n index: number;\n gate: RubricGate;\n guardValue: unknown;\n when: SimpleRule;\n /** AI mode only: the per-case check's name and its one instruction. */\n aiName?: string;\n instructions?: string;\n}\n\n/**\n * The case-table card, recognised from the document — never stored. The\n * permanent \"anyone else\" row is `elseCase`: its `appliesWhen` is the `notIn`\n * complement of every named case, which is what makes the table exhaustive and\n * non-overlapping by construction.\n */\nexport interface LinkedRule {\n checkedField: string;\n op: RubricOperator;\n guardField: string;\n cases: LinkedCase[];\n elseCase: { code: string; index: number; gate: RubricGate; when: SimpleRule; aiName?: string; instructions?: string };\n onFail: 'reject' | 'review';\n gateClass: RubricGateClass;\n /** Every gate index this card owns, ascending — delete removes them all. */\n indices: number[];\n /**\n * AI mode (the linked AI lane): every case's gate reads its OWN per-case\n * AiCheck, and `checkedField` is the answer those checks look at (the shared\n * send anchor). `alsoSend` is the rest of the shared send list.\n */\n ai?: { alsoSend: string[] };\n}\n\n/** Values compare structurally — `in`/`notIn` entries are plain literals. */\nfunction valueKey(value: unknown): string {\n return JSON.stringify(value) ?? 'undefined';\n}\n\n/**\n * The DERIVED linked-rule recognition, pinned by tests: a set of gates is one\n * card iff they share the same `when.field` + `when.op`, every `appliesWhen`\n * tests the SAME other question with `in` (exactly one value each), exactly one\n * tests it with `notIn`, and that `notIn` list is precisely the union of the\n * named cases' values (no overlaps). Anything else stays individual cards.\n *\n * AI mode is a second, disjoint bucket family: every gate's `when` is the\n * builder's own AI shape (`ai.<name>.valid` must be ticked), each case reading\n * its OWN well-formed check (exactly one instruction, an all-`$answer` send)\n * and all checks sending the SAME list — the anchor is the table's checked\n * answer, so the bucket keys on it. The guard predicate is EXACTLY the value\n * table's, untouched. Any deviation — a missing or shared check, a mixed send,\n * extra instructions — keeps those gates individual cards.\n */\nexport function listLinkedRules(body: RubricBody | null): LinkedRule[] {\n const gates = body?.gates ?? [];\n const aiChecksByName = new Map((body?.aiChecks ?? []).map((check) => [check.name, check]));\n interface Candidate {\n index: number;\n gate: RubricGate;\n when: SimpleRule;\n guard: SimpleRule;\n /** AI mode: the well-formed per-case check this gate reads. */\n ai?: { name: string; instructions: string; sendFields: string[] };\n }\n const byKey = new Map<string, Candidate[]>();\n const push = (key: string, candidate: Candidate) => {\n const bucket = byKey.get(key);\n if (bucket) bucket.push(candidate);\n else byKey.set(key, [candidate]);\n };\n gates.forEach((gate, index) => {\n if (groupShapeOf(gate.when)) return; // a grown rule's compound gate is never a case row\n const when = toSimpleRule(gate.when);\n const guard = toSimpleRule(gate.appliesWhen);\n if (!when || !guard) return;\n if (guard.op !== 'in' && guard.op !== 'notIn') return;\n if (!Array.isArray(guard.value) || guard.value.length === 0) return;\n if (guard.op === 'in' && guard.value.length !== 1) return;\n if (guard.field.includes('[*]')) return;\n // The AI shape never enters a value bucket — its `when.field` is a\n // different check per case, so the table keys on what the checks look AT.\n const aiName = aiMemberName(when);\n if (aiName) {\n const check = aiChecksByName.get(aiName);\n if (!check) return;\n const sendFields = aiSendFields(check);\n if (!sendFields) return;\n if (check.instructions.length !== 1 || typeof check.instructions[0] !== 'string') return;\n if (guard.field === sendFields[0]) return;\n // The send list rides the key: rows sending different views can never\n // share a bucket — the uniformity rule with no second check needed.\n push(JSON.stringify(['ai', guard.field, sendFields]), { index, gate, when, guard, ai: { name: aiName, instructions: check.instructions[0], sendFields } });\n return;\n }\n if (guard.field === when.field) return;\n push(JSON.stringify([when.field, when.op, guard.field]), { index, gate, when, guard });\n });\n\n const out: LinkedRule[] = [];\n for (const bucket of byKey.values()) {\n const named = bucket.filter((entry) => entry.guard.op === 'in');\n const others = bucket.filter((entry) => entry.guard.op === 'notIn');\n if (named.length < 1 || others.length !== 1) continue;\n const elseEntry = others[0];\n const unionKeys = named.map((entry) => valueKey((entry.guard.value as unknown[])[0]));\n if (new Set(unionKeys).size !== unionKeys.length) continue; // overlapping cases — ambiguous\n const elseKeys = (elseEntry.guard.value as unknown[]).map(valueKey);\n if (elseKeys.length !== unionKeys.length) continue;\n if ([...unionKeys].sort().join('\u0000') !== [...elseKeys].sort().join('\u0000')) continue;\n const onFail = bucket[0].gate.onFail ?? 'reject';\n const gateClass = bucket[0].gate.class;\n if (!bucket.every((entry) => (entry.gate.onFail ?? 'reject') === onFail && entry.gate.class === gateClass)) continue;\n const ai = bucket[0].ai;\n // AI mode: one check per row — rows sharing a check could not recompile\n // into the per-case instructions the card edits, so they stay individual.\n if (ai && new Set(bucket.map((entry) => entry.ai?.name)).size !== bucket.length) continue;\n const caseExtras = (entry: Candidate) => (entry.ai ? { aiName: entry.ai.name, instructions: entry.ai.instructions } : {});\n out.push({\n checkedField: ai ? ai.sendFields[0] : bucket[0].when.field,\n op: bucket[0].when.op,\n guardField: bucket[0].guard.field,\n cases: named.map((entry) => ({\n code: entry.gate.code,\n index: entry.index,\n gate: entry.gate,\n guardValue: (entry.guard.value as unknown[])[0],\n when: entry.when,\n ...caseExtras(entry),\n })),\n elseCase: { code: elseEntry.gate.code, index: elseEntry.index, gate: elseEntry.gate, when: elseEntry.when, ...caseExtras(elseEntry) },\n onFail,\n gateClass,\n indices: bucket.map((entry) => entry.index).sort((a, b) => a - b),\n ...(ai ? { ai: { alsoSend: ai.sendFields.slice(1) } } : {}),\n });\n }\n return out.sort((a, b) => a.indices[0] - b.indices[0]);\n}\n\n/** Delete several gates at once — a linked rule's whole table, or one group. */\nexport function removeGatesAt(body: RubricBody, indices: number[]): RubricBody {\n const drop = new Set(indices);\n return { ...body, gates: (body.gates ?? []).filter((_, i) => !drop.has(i)) };\n}\n\n// ---------------------------------------------------------------------------\n// Score bands (§A.14 `expect: 'score'`) — a floor gate + a hold gate, ONE card\n// ---------------------------------------------------------------------------\n\n/**\n * The derived shape of a score check's bands. The builder compiles a score\n * check to at most two gates on `ext.<name>.score` — an optional FLOOR\n * (`>= rejectBelow`, onFail reject: \"below this, turn the claim down\") followed\n * by the HOLD gate (`>= approveAt`, onFail review: \"below this, a person\n * decides\"). The floor comes first because the engine acts on the first failing\n * gate. Values are basis points, exactly as the document stores them.\n */\nexport interface ScoreBandsShape {\n /** bps — at/above this the check passes. */\n approveAt: number;\n /** bps — below this the claim is turned down; 0 = no reject band. */\n rejectBelow: number;\n /** The floor gate, when a reject band exists — its code keeps the receipt identity across edits. */\n floor?: { index: number; code: string; gate: RubricGate };\n /** Every gate index this card owns, ascending — delete removes them all. */\n indices: number[];\n}\n\nconst SCORE_SUBJECT = /^ext\\.([A-Za-z0-9_-]+)\\.score$/;\n\n/** A simple `ext.<name>.score >= <int bps>` gate — the score-band family; anything else is not one. */\nfunction scoreGateOf(gate: RubricGate): { name: string; value: number } | undefined {\n const simple = toSimpleRule(gate.when);\n if (!simple || simple.op !== '>=') return undefined;\n const name = SCORE_SUBJECT.exec(simple.field)?.[1];\n if (!name) return undefined;\n const value = simple.value;\n if (typeof value !== 'number' || !Number.isInteger(value) || value < 0 || value > 10000) return undefined;\n return { name, value };\n}\n\n/**\n * The DERIVED score-band recognition — no stored keys, exactly like linked\n * rules: per source, exactly ONE hold gate (onFail review), at most one floor\n * BEFORE it in document order (the order the engine needs), floor below hold,\n * identical guards. Anything else — two holds, a floor above the hold, a floor\n * after the hold, mismatched `appliesWhen` — leaves the gates as individual\n * rules rather than presenting an order the engine will not honour. Returns\n * hold-gate index → its bands; the floor indices land in `claimedFloors`.\n */\nfunction scoreBandsByHold(gates: RubricGate[], skip: Set<number>, claimedFloors: Set<number>): Map<number, ScoreBandsShape> {\n const bySource = new Map<string, { holds: number[]; floors: number[] }>();\n gates.forEach((gate, index) => {\n if (skip.has(index)) return;\n const score = scoreGateOf(gate);\n if (!score) return;\n const entry = bySource.get(score.name) ?? { holds: [], floors: [] };\n ((gate.onFail ?? 'reject') === 'review' ? entry.holds : entry.floors).push(index);\n bySource.set(score.name, entry);\n });\n const out = new Map<number, ScoreBandsShape>();\n for (const { holds, floors } of bySource.values()) {\n if (holds.length !== 1) continue;\n const hold = holds[0];\n const approveAt = scoreGateOf(gates[hold])!.value;\n const lone: ScoreBandsShape = { approveAt, rejectBelow: 0, indices: [hold] };\n if (floors.length === 0) {\n out.set(hold, lone);\n continue;\n }\n if (floors.length > 1) continue;\n const floorIndex = floors[0];\n const floorGate = gates[floorIndex];\n const rejectBelow = scoreGateOf(floorGate)!.value;\n const sameGuard = JSON.stringify(gates[hold].appliesWhen ?? null) === JSON.stringify(floorGate.appliesWhen ?? null);\n if (floorIndex > hold || rejectBelow >= approveAt || !sameGuard) {\n // The floor is not this card's — the hold still reads as a bands card\n // with no reject band, and the floor stays its own rule.\n out.set(hold, lone);\n continue;\n }\n claimedFloors.add(floorIndex);\n out.set(hold, { approveAt, rejectBelow, floor: { index: floorIndex, code: floorGate.code, gate: floorGate }, indices: [floorIndex, hold] });\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Rules — the card-level view of the document\n// ---------------------------------------------------------------------------\n\n/**\n * What a rule DOES. v1 offers two outcomes and no points: a claim is either\n * turned down, or held for a person to look at. Scoring left the authoring\n * surface (the format still carries it — see `emptyRubric`'s `all_pass` — but\n * nothing in the builder can write a scored criterion any more).\n */\nexport type Consequence = 'reject' | 'human';\n\n/** A rule as the author sees it, plus where it lives in the document. */\nexport type UiRule =\n | {\n consequence: 'reject';\n code: string;\n index: number;\n fieldPath: string;\n gate: RubricGate;\n /** Present iff `when` is compound — a rule that GREW more checks (owner 2026-08-03): its derived shape, or the quiet read-only fallback. */\n grown?: GroupShape;\n /** Present iff this is a score check's HOLD gate (§A.14 score) — the card owns its floor gate too. */\n bands?: ScoreBandsShape;\n }\n | { consequence: 'human'; code: string; index: number; fieldPath: string; criterion: RubricCriterion; task?: RubricReviewTask };\n\n/**\n * The question a condition is ABOUT: the first field ref it names, depth-first.\n * For a compound `when` (a grown rule) that is the FIRST member's subject —\n * the card the whole rule renders on; an AI/ext first member resolves on\n * through `resolveRef` to the question its check sends (the anchor field).\n */\nexport function primaryFieldOf(cond: RubricCondition | undefined): string {\n if (!cond || typeof cond !== 'object') return '';\n if ('forEach' in cond && typeof cond.forEach === 'string') return cond.forEach;\n if ('field' in cond && typeof cond.field === 'string') return cond.field;\n const members: RubricCondition[] =\n 'not' in cond\n ? [cond.not]\n : 'all' in cond && Array.isArray(cond.all)\n ? cond.all\n : 'any' in cond && Array.isArray(cond.any)\n ? cond.any\n : 'of' in cond && Array.isArray(cond.of)\n ? cond.of\n : [];\n for (const member of members) {\n const found = primaryFieldOf(member);\n if (found) return found;\n }\n return '';\n}\n\n/**\n * The question a human check is about — the answer the reviewer is shown.\n * Only `ManualScore` reaches this now (`listRules` skips every other node), so\n * there is one arm rather than the switch over all seven score shapes.\n */\nfunction manualScoreField(score: RubricScoreNode | undefined): string {\n return score?.['@type'] === 'ManualScore' ? score.field : '';\n}\n\n/** §A.3 field refs, as they appear inside a calculated value's expression — FORM_SEGMENT grammar, namespace prefixes included. */\nconst FIELD_IN_EXPR = new RegExp(`\\\\$${FORM_SEGMENT}(?:\\\\.${FORM_SEGMENT}|\\\\[\\\\*\\\\])*`);\n\n/**\n * A rule that scores a calculated value belongs to the question that value is\n * calculated FROM — §A.13's worked example scores `~minQty` and the author\n * expects to find it on the \"Quantities delivered\" card, not in a corner\n * labelled \"other\". Likewise an `ext.<name>.*` rule belongs to the question its\n * check sends (§A.14): an external check IS a rule on that question. Resolve\n * one hop, then give up honestly (an unresolved ref keeps its raw form and\n * falls into the no-question bucket).\n */\nfunction resolveRef(ref: string, body: RubricBody): string {\n if (ref.startsWith('ext.')) return extRefQuestion(ref, body) ?? ref;\n if (ref.startsWith('ai.')) return aiRefQuestion(ref, body) ?? ref;\n if (!ref.startsWith('~')) return ref;\n const derived = body.derived?.find((entry) => entry.name === ref.slice(1));\n return (derived && FIELD_IN_EXPR.exec(derived.expr)?.[0]) || ref;\n}\n\n/** Every rule in the document, in document order, tagged with the question it is about. */\nexport function listRules(body: RubricBody | null): UiRule[] {\n if (!body) return [];\n // A gate a linked rule's case table owns renders as that card and never as an\n // individual rule — same doctrine as scored criteria below: recognition, not\n // stored keys. An `all`-compound gate is NOT claimed by anything: it IS a\n // rule — one that grew more checks (owner 2026-08-03) — carrying its derived\n // shape and listed on its first member's card like any other. THE policy gate\n // (the one recognised `any`/`atLeast`, proposal v3) is claimed by the\n // approval section instead; a `foreign` shape claims nothing, so stray\n // policy-family gates stay read-only rules on their cards, deletable.\n const claimed = new Set<number>();\n for (const linked of listLinkedRules(body)) for (const index of linked.indices) claimed.add(index);\n const policy = policyShapeOf(body);\n if (policy.kind === 'policy') claimed.add(policy.index);\n // A score check's floor gate is claimed by its hold gate's card (§A.14 score)\n // — same doctrine as a linked rule's case gates.\n const bandsByHold = scoreBandsByHold(body.gates ?? [], claimed, claimed);\n const rules: UiRule[] = [];\n (body.gates ?? []).forEach((gate, index) => {\n if (claimed.has(index)) return;\n const shape = groupShapeOf(gate.when, body.aiChecks ?? []);\n // An `appliesWhen` the sentence row cannot represent would be silently\n // dropped by a save — a grown rule carrying one is read-only instead\n // (never destroy what the UI can't author).\n const grown = shape && shape.editable && gate.appliesWhen && !toSimpleRule(gate.appliesWhen) ? ({ editable: false } as const) : shape;\n const bands = bandsByHold.get(index);\n rules.push({\n consequence: 'reject',\n code: gate.code,\n index,\n fieldPath: resolveRef(primaryFieldOf(gate.when), body),\n gate,\n ...(grown ? { grown } : {}),\n ...(bands ? { bands } : {}),\n });\n });\n // `criteria[]` is where human checks live — a `ManualScore` criterion IS the\n // 👤 rule. Any OTHER node in there is a scored criterion, which the builder\n // can no longer author; it is skipped rather than surfaced, so nothing the\n // author cannot edit can appear on a card.\n (body.scoring?.criteria ?? []).forEach((criterion, index) => {\n if (criterion.score?.['@type'] !== 'ManualScore') return;\n const fieldPath = resolveRef(manualScoreField(criterion.score), body);\n const task = (body.review?.tasks ?? []).find((t) => t.id === (criterion.score as { reviewTask?: string }).reviewTask);\n rules.push({ consequence: 'human', code: criterion.code, index, fieldPath, criterion, task });\n });\n return rules;\n}\n\n/** Rules grouped by card. A rule about `$items.SKU_1.Quantity` lands on the `$items` card. */\nexport function rulesByCard(body: RubricBody | null, cards?: ReadonlySet<string>): Map<string, UiRule[]> {\n const byCard = new Map<string, UiRule[]>();\n for (const rule of listRules(body)) {\n const key = rule.fieldPath ? rootPath(rule.fieldPath, cards) : '';\n const bucket = byCard.get(key);\n if (bucket) bucket.push(rule);\n else byCard.set(key, [rule]);\n }\n return byCard;\n}\n\n// ---------------------------------------------------------------------------\n// Codes — `^[A-Z0-9]+-[0-9]+-[A-Z0-9-]+$` (§A.6), unique per rubric\n// ---------------------------------------------------------------------------\n\nconst CODE_SEQUENCE = /^[A-Z0-9]+-(\\d+)-/;\n\n/** Every code the document already uses, so a new one can never collide (`RUB_DUPLICATE_CODE`). */\nfunction usedCodes(body: RubricBody | null): string[] {\n if (!body) return [];\n const codes: string[] = [];\n for (const gate of body.gates ?? []) codes.push(gate.code);\n for (const criterion of body.scoring?.criteria ?? []) {\n codes.push(criterion.code);\n if (criterion.score?.['@type'] === 'DeductionsScore') for (const deduction of criterion.score.deduct ?? []) codes.push(deduction.code);\n }\n for (const task of body.review?.tasks ?? []) codes.push(task.id);\n for (const derived of body.derived ?? []) codes.push(derived.name);\n return codes;\n}\n\n/** Turn a field path into a code-safe token: `$items.SKU_1.Quantity` → `ITEMS-SKU-1-QUANTITY`. */\nfunction codeToken(fieldPath: string): string {\n const token = fieldPath\n .replace(/^\\$/, '')\n .replace(/\\[\\*\\]/g, '')\n .replace(/[^A-Za-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .toUpperCase();\n return token.slice(0, 24) || 'ANSWER';\n}\n\n/**\n * Mint the next free code. The author never sees or types one — it exists so the\n * engine can name the exact rule that rejected a claim in its receipt.\n *\n * `alsoUsed` reserves codes that are NOT yet in the committed body — the codes\n * of the other rows in an in-flight draft (e.g. the deductions already added to\n * the widget being edited), so minting three in a row yields three DISTINCT\n * codes instead of colliding on the same `usedCodes(body)` snapshot.\n */\nexport function nextCode(body: RubricBody | null, prefix: string, fieldPath: string, alsoUsed: Iterable<string> = []): string {\n const reserved = [...usedCodes(body), ...alsoUsed];\n const taken = new Set(reserved);\n const highest = reserved.reduce((max, code) => {\n const seq = CODE_SEQUENCE.exec(code)?.[1];\n return seq ? Math.max(max, Number(seq)) : max;\n }, 100);\n const token = codeToken(fieldPath);\n for (let seq = highest + 1; ; seq++) {\n const code = `${prefix}-${seq}-${token}`;\n if (!taken.has(code)) return code;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Writing — every mutation of the body goes through here\n// ---------------------------------------------------------------------------\n\n/**\n * The one way a claim is approved in v1: every check must pass. The author is\n * never asked — there is no method picker any more, and `bindForm` re-pins an\n * older document to this on open so the screen and the document cannot drift.\n *\n * The format still defines `weighted_average`/`minimum`/`quorum`; nothing here\n * can write them. That is deliberate — scoring can come back without a format\n * migration.\n */\nconst APPROVAL_METHOD: RubricScoringMethod = 'all_pass';\n\n/**\n * The format REQUIRES `approveAt` (§A.8) and it is inert under `all_pass`: all\n * criteria pass ⇒ 10000 ≥ 8500 ⇒ approve, one fails ⇒ 0 < 8500 ⇒ reject. It is\n * a constant rather than a control because no slider writes it any more.\n */\nconst APPROVE_AT = 8500;\n\n/**\n * A brand-new rulebook: no rules yet, approved when every check passes.\n *\n * `resource` records the form resource actually read, when the host names it;\n * `#vct` is the convention every protocol follows, so it stays the fallback.\n */\nexport function emptyRubric(protocolDid: string, proof: string, title: string, resource = '#vct'): RubricBody {\n return {\n '@type': 'Rubric',\n title,\n claimSchema: { '@type': 'ClaimSchemaBinding', protocol: protocolDid, resource, proof },\n gates: [],\n scoring: { '@type': 'Scoring', method: APPROVAL_METHOD, approveAt: APPROVE_AT, criteria: [] },\n settlement: { '@type': 'Settlement', onApprove: { pay: 'approval' } },\n };\n}\n\n/**\n * Pin the rules to the form that is actually loaded — WITHOUT ever losing work.\n *\n * When a rubric already exists (the author has rules, or has opened this block\n * before), we only re-write its `claimSchema` binding (protocol / resource /\n * proof) and keep every gate, criterion and review task exactly as they were.\n * `emptyRubric` is minted ONLY when there is genuinely no prior rubric — never\n * as a \"reset\" of one that momentarily read as null. This is the guard that\n * keeps rules alive across a config close/reopen (they round-trip through\n * `block.props.inputs`, so re-binding must be non-destructive).\n */\nexport function bindForm(current: RubricBody | null | undefined, protocol: string, resource: string, proof: string, title: string): RubricBody {\n if (current) {\n return {\n ...current,\n claimSchema: { ...current.claimSchema, protocol, resource, proof },\n // Re-pin the approval rule. A document written before the method picker\n // was removed still says `weighted_average`, which would make the screen\n // (\"when all N checks pass\") lie about what the engine will actually do.\n ...(current.scoring ? { scoring: { ...current.scoring, method: APPROVAL_METHOD } } : {}),\n };\n }\n return emptyRubric(protocol, proof, title, resource);\n}\n\n/** Replace (or append) a reject rule. */\nexport function putGate(body: RubricBody, gate: RubricGate, at?: number): RubricBody {\n const gates = [...(body.gates ?? [])];\n if (at === undefined) gates.push(gate);\n else gates[at] = gate;\n return { ...body, gates };\n}\n\n/** Replace (or append) a human-checked question. */\nexport function putCriterion(body: RubricBody, criterion: RubricCriterion, at?: number): RubricBody {\n const scoring = body.scoring ?? { '@type': 'Scoring' as const, method: APPROVAL_METHOD, approveAt: APPROVE_AT, criteria: [] };\n const criteria = [...(scoring.criteria ?? [])];\n if (at === undefined) criteria.push(criterion);\n else criteria[at] = criterion;\n return { ...body, scoring: { ...scoring, criteria } };\n}\n\n/** Replace (or append) the question a person is asked. */\nexport function putReviewTask(body: RubricBody, task: RubricReviewTask): RubricBody {\n // No default `route`: the engine now demands a REAL Matrix room there (§A.9),\n // so the role lane is the fallback until the author picks a channel or person.\n const review = body.review ?? {\n '@type': 'HumanReview' as const,\n assignTo: { role: 'reviewer' },\n slaHours: 48,\n onTimeout: 'reject' as const,\n tasks: [],\n };\n const tasks = [...(review.tasks ?? [])];\n const at = tasks.findIndex((t) => t.id === task.id);\n if (at < 0) tasks.push(task);\n else tasks[at] = task;\n return { ...body, review: { ...review, tasks } };\n}\n\n/** Delete a rule — and, for a human check, the question that went with it. A score card's floor gate goes with its hold gate. */\nexport function removeRule(body: RubricBody, rule: UiRule): RubricBody {\n if (rule.consequence === 'reject') {\n const drop = new Set(rule.bands?.indices ?? [rule.index]);\n return { ...body, gates: (body.gates ?? []).filter((_, i) => !drop.has(i)) };\n }\n const scoring = body.scoring;\n const next: RubricBody = { ...body, ...(scoring ? { scoring: { ...scoring, criteria: (scoring.criteria ?? []).filter((_, i) => i !== rule.index) } } : {}) };\n if (!rule.task) return next;\n const tasks = (next.review?.tasks ?? []).filter((t) => t.id !== rule.task?.id);\n // An empty review node says nothing — drop it rather than publish a husk.\n if (tasks.length === 0) {\n const { review: _dropped, ...withoutReview } = next;\n return withoutReview;\n }\n return { ...next, review: { ...next.review!, tasks } };\n}\n\n// ---------------------------------------------------------------------------\n// Diagnostics → the card that owns the problem\n// ---------------------------------------------------------------------------\n\n/**\n * Which rule a diagnostic's JSON-Pointer is about (§A.11 diagnostics carry a\n * pointer into the document, so a problem can be shown where it happened\n * instead of in a list at the bottom of the screen).\n *\n * `undefined` = a document-level problem — the thresholds, the settlement, or\n * \"no rules at all\" — which belongs to the summary bar, not to a card.\n */\nexport function ruleForDiagnosticPath(body: RubricBody | null, path: string): UiRule | undefined {\n if (!body || !path) return undefined;\n const rules = listRules(body);\n const gate = /^\\/gates\\/(\\d+)/.exec(path);\n // A score card's floor gate belongs to the hold gate's rule (§A.14 score).\n if (gate) {\n const index = Number(gate[1]);\n return rules.find((r) => r.consequence === 'reject' && (r.index === index || r.bands?.indices.includes(index) === true));\n }\n const criterion = /^\\/scoring\\/criteria\\/(\\d+)/.exec(path);\n if (criterion) return rules.find((r) => r.consequence !== 'reject' && r.index === Number(criterion[1]));\n const task = /^\\/review\\/tasks\\/(\\d+)/.exec(path);\n if (task) {\n const forCriterion = body.review?.tasks?.[Number(task[1])]?.forCriterion;\n return rules.find((r) => r.code === forCriterion);\n }\n return undefined;\n}\n\n/** The card a diagnostic belongs to, or `undefined` for a document-level problem. */\nexport function cardForDiagnosticPath(body: RubricBody | null, path: string, cards?: ReadonlySet<string>): string | undefined {\n const rule = ruleForDiagnosticPath(body, path);\n if (rule?.fieldPath) return rootPath(rule.fieldPath, cards);\n // A linked rule's gates live on the CHECKED question's card (Part 3\n // placement), so their problems point there too. (A grown rule's compound\n // gate is an ordinary rule now — the branch above already found its card.)\n const gate = /^\\/gates\\/(\\d+)/.exec(path);\n if (gate && body) {\n const index = Number(gate[1]);\n const linked = listLinkedRules(body).find((entry) => entry.indices.includes(index));\n if (linked) return rootPath(linked.checkedField, cards);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Pass / fail — the two values a human check's `whenMissing` can hold\n// ---------------------------------------------------------------------------\n\n/**\n * The document counts in basis points, but v1 has no points to show: a check\n * either passes or it does not. These are the only two values the builder\n * writes into a criterion's score, so the 0–100 conversions the old score\n * widgets needed are gone with them.\n */\nexport const PASSED = 10000;\nexport const FAILED = 0;\n","import type { RubricBody, RubricCondition, RubricGate } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { POLICY_DEFAULT_REASON } from './phrases';\nimport { listRules, nextCode, policyMemberRenderable, policyShapeOf, primaryFieldOf, type UiRule } from './ruleModel';\n\n/**\n * The approval policy's editing model (owner 2026-08-03, proposal v3) — the\n * bridge between the \"When is a claim approved?\" tabs and the document, the\n * way `ruleDraft` bridges one rule's editor.\n *\n * The document stores NO builder state: `derivePolicy` reads the tally straight\n * out of the gates (`policyShapeOf` — zero `any`/`atLeast` gates is the \"All of\n * them\" tab, exactly one IS the policy), and `compilePolicy` writes only shapes\n * the engine already evaluates — standalone gates plus at most ONE gate whose\n * `when` is `{any: […]}` / `{atLeast: n, of: […]}`. The unchecked-vs-pinned\n * distinction is presentation-only and is NOT persisted: both compile to a\n * standalone gate, so after a reopen every standalone gate reads back as\n * pinned — enforcement-wise identical, by doctrine.\n *\n * Rows keep the ORIGINAL gate nodes while they are unfolded, so folding a rule\n * and unfolding it again inside one session — or flipping the tabs away and\n * back — restores its bytes verbatim. Only a member recognised from an\n * existing policy has no gate identity to restore; extracting one mints a\n * fresh standalone gate under the policy's own wording.\n */\n\nexport type PolicyTab = 'all' | 'any' | 'atLeast';\n\ntype RejectRule = Extract<UiRule, { consequence: 'reject' }>;\n\n/** One row of the policy's rule list. Exactly one of `rule` / `member` is set. */\nexport interface PolicyRow {\n key: string;\n /** Backed by a standalone gate — kept byte-verbatim unless folded. */\n rule?: RejectRule;\n /** A member of the recognised policy gate — a condition with no gate of its own. */\n member?: RubricCondition;\n /**\n * Cannot fold, pin forced on: a guard rides the gate (a member has no seat\n * for `appliesWhen`), its ending is \"a person checks it\" (a reject policy\n * would silently rewrite it), or its `when` fits no policy member.\n */\n locked: boolean;\n selected: boolean;\n pinned: boolean;\n}\n\nexport interface PolicyState {\n /** The document the rows were derived from — `compilePolicy` rebuilds `gates[]` against it. */\n base: RubricBody;\n /** Two policy-family gates, or one the tabs cannot represent: read-only, compile is a no-op. */\n foreign: boolean;\n tab: PolicyTab;\n rows: PolicyRow[];\n /** The DISPLAYED at-least count — pinned rows included (\"3 of 4\"), exactly what the stepper shows. */\n n: number;\n reason: string;\n /** The recognised policy gate — its identity (code, class, ending, guard) survives an edit. */\n gate?: RubricGate;\n /** Where that gate sits in `base.gates`, so a recompile keeps its place. */\n gateAt?: number;\n}\n\n/** Keep the stepper honest: `pinnedSelected + 1 ≤ n ≤ selectedCount` (at least one rule beyond the pins). */\nexport function clampPolicyN(n: number, pinnedSelected: number, selectedCount: number): number {\n const min = pinnedSelected + 1;\n const max = Math.max(selectedCount, min);\n return Math.min(Math.max(Math.round(n) || min, min), max);\n}\n\n/**\n * Whether the tally can FOLD this rule into the policy gate. A fold keeps only\n * the rule's `when` (its code/reason/ending are replaced by the policy's one\n * wording), so anything a member cannot carry pins the row instead — never\n * silently dropped, never rewritten.\n */\nexport function foldableRule(rule: RejectRule): boolean {\n if (rule.gate.appliesWhen) return false;\n if ((rule.gate.onFail ?? 'reject') !== 'reject') return false;\n if (rule.grown && !rule.grown.editable) return false;\n return policyMemberRenderable(rule.gate.when);\n}\n\n/**\n * The tabs' state, derived from the document alone. ⛔ reject rules only — 👤\n * person-checks are not gates and never appear. With a recognised policy the\n * members render selected+unpinned and every standalone gate selected+pinned\n * (displayed n = stored n + the pinned rows, so the author's \"3 of 4\"\n * survives a reopen). With none, every foldable rule starts in the tally\n * unpinned — switching to a policy tab means \"over these rules\".\n */\nexport function derivePolicy(body: RubricBody): PolicyState {\n const shape = policyShapeOf(body);\n if (shape.kind === 'foreign') return { base: body, foreign: true, tab: 'all', rows: [], n: 1, reason: '' };\n const rejects = listRules(body).filter((rule): rule is RejectRule => rule.consequence === 'reject');\n if (shape.kind === 'none') {\n const rows: PolicyRow[] = rejects.map((rule) => {\n const locked = !foldableRule(rule);\n return { key: rule.code, rule, locked, selected: true, pinned: locked };\n });\n const pinned = rows.filter((row) => row.pinned).length;\n return { base: body, foreign: false, tab: 'all', rows, n: pinned + 1, reason: '' };\n }\n const memberRows: PolicyRow[] = shape.members.map((member, at) => ({ key: `member-${at}`, member, locked: false, selected: true, pinned: false }));\n const gateRows: PolicyRow[] = rejects.map((rule) => ({ key: rule.code, rule, locked: !foldableRule(rule), selected: true, pinned: true }));\n return {\n base: body,\n foreign: false,\n tab: shape.tab,\n rows: [...memberRows, ...gateRows],\n n: (shape.nRest ?? 1) + gateRows.length,\n reason: shape.gate.reason,\n gate: shape.gate,\n gateAt: shape.index,\n };\n}\n\n/**\n * Compile the tabs back into the document — nothing but shapes the engine\n * already ships:\n * - \"All of them\" (or an empty tally): every row is a standalone gate and a\n * document that never had a policy comes back BYTE-IDENTICAL;\n * - \"Any of them\" / \"At least…\": the selected, unpinned rows fold into ONE\n * policy gate (`any` / `atLeast n − pins, of`) that keeps the recognised\n * gate's identity when there is one; pinned and unchecked rows stay\n * standalone, bytes untouched. A single-member compound is kept as the\n * compound (recognition stability), never unwrapped.\n * Members extracted from an existing policy gain minted standalone gates under\n * the policy's wording; AI/ext nodes ride the conditions either way, so no\n * fold or unfold ever orphans one.\n */\nexport function compilePolicy(state: PolicyState): RubricBody {\n if (state.foreign) return state.base;\n const baseGates = state.base.gates ?? [];\n const folded = state.tab === 'all' ? [] : state.rows.filter((row) => row.selected && !row.pinned && !row.locked);\n const members = folded.map((row) => (row.rule ? row.rule.gate.when : row.member!));\n const foldedIndexes = new Set(folded.flatMap((row) => (row.rule ? [row.rule.index] : [])));\n const pinnedSelected = state.rows.filter((row) => row.selected && row.pinned).length;\n const nRest = Math.min(Math.max(state.n - pinnedSelected, 1), Math.max(members.length, 1));\n const reason = state.reason.trim() || POLICY_DEFAULT_REASON;\n\n // A member no longer in the fold (unchecked, pinned, or the All tab\n // dissolving the policy) becomes a standalone gate of its own — minted,\n // since a member has no gate identity to restore.\n const minted: string[] = [];\n const extractedGates: RubricGate[] = state.rows\n .filter((row) => row.member && !folded.includes(row))\n .map((row) => {\n const code = nextCode(state.base, 'RULE', primaryFieldOf(row.member), minted);\n minted.push(code);\n return { '@type': 'Gate', code, reason: state.gate?.reason ?? reason, when: row.member!, onFail: 'reject', class: state.gate?.class ?? 'insufficient_evidence' };\n });\n\n let policyGate: RubricGate | undefined;\n if (state.tab !== 'all' && members.length > 0) {\n const when: RubricCondition = state.tab === 'any' ? { '@type': 'Condition', any: members } : { '@type': 'Condition', atLeast: nRest, of: members };\n const old = state.gate;\n // An unedited recompile reuses the recognised NODE, so even a hand-authored\n // policy gate (its own key order, extra idioms) round-trips byte-identical.\n policyGate =\n old && old.reason === reason && JSON.stringify(old.when) === JSON.stringify(when)\n ? old\n : {\n '@type': 'Gate',\n code: old?.code ?? nextCode(state.base, 'RULE', 'approval', minted),\n reason,\n ...(old?.appliesWhen ? { appliesWhen: old.appliesWhen } : {}),\n when,\n onFail: old?.onFail ?? 'reject',\n class: old?.class ?? 'insufficient_evidence',\n };\n }\n\n const gates: RubricGate[] = [];\n baseGates.forEach((gate, at) => {\n if (at === state.gateAt) {\n if (policyGate) gates.push(policyGate);\n return;\n }\n if (foldedIndexes.has(at)) return;\n gates.push(gate);\n });\n gates.push(...extractedGates);\n if (policyGate && state.gateAt === undefined) gates.push(policyGate);\n return { ...state.base, gates };\n}\n","import React from 'react';\n\n/**\n * The builder's visual voice — every colour a Mantine theme token (styling\n * guide: no hardcoded colour strings), scoped inline to these components so\n * nothing leaks into the host portal's global theme and both colour schemes\n * keep working (the `neutralColor` scale inverts between them).\n *\n * The accent is deliberately scarce: per card it appears on the active\n * segment, the preview sentence's quote bar, and a focused control — nowhere\n * else. The consequences keep their own colours (Mantine red-6 / grape-6,\n * §B.5 rule 4) and always render as soft tinted pills, never solid buttons.\n */\n\nexport const ACCENT = 'var(--mantine-color-accent-5)';\nexport const ACCENT_SOFT = `color-mix(in srgb, ${ACCENT} 10%, transparent)`;\nexport const INK = 'var(--mantine-color-text)';\nexport const SLATE = 'var(--mantine-color-dimmed)';\n/** Low neutral indices are the light-on-light lane (styling guide) — a hairline. */\nexport const HAIRLINE = 'var(--mantine-color-neutralColor-4)';\nconst SURFACE = 'var(--mantine-color-body)';\nconst PANEL_GROUND = 'var(--mantine-color-neutralColor-1)';\nconst SHADOW_TINT = 'color-mix(in srgb, var(--mantine-color-black) 5%, transparent)';\n\n/** One card: hairline border, soft two-layer shadow, room to breathe. */\nexport const cardStyle: React.CSSProperties = {\n background: SURFACE,\n border: `1px solid ${HAIRLINE}`,\n borderRadius: 12,\n boxShadow: `0 1px 2px ${SHADOW_TINT}, 0 8px 28px ${SHADOW_TINT}`,\n};\n\n/** A quiet panel inside a card or the modal — structure without another shadow. */\nexport const panelStyle: React.CSSProperties = {\n background: PANEL_GROUND,\n border: `1px solid ${HAIRLINE}`,\n borderRadius: 10,\n};\n\n/** Section micro-label — the words stay exactly as written; only the type changes. */\nexport const microLabelStyle: React.CSSProperties = {\n fontSize: 11.5,\n fontWeight: 600,\n letterSpacing: '0.07em',\n textTransform: 'uppercase',\n color: SLATE,\n};\n\n/** The lead word of a sentence row (\"If\", \"Then…\", \"Only check this if\"). */\nexport const leadWordStyle: React.CSSProperties = { fontSize: 14, fontWeight: 600, color: INK };\n\n/**\n * Selects and inputs as sentence chips. The border rides Mantine's own\n * `--input-bd` var, set on the WRAPPER so the input's :focus rule can still\n * swap it to the theme's `--input-bd-focus` (the accent) — inline on the input\n * element itself would beat that rule and freeze the border, killing the\n * visible focus state.\n */\nexport const chipInput = {\n wrapper: { '--input-bd': HAIRLINE, '--input-bg': SURFACE } as React.CSSProperties,\n input: {\n borderRadius: 8,\n boxShadow: `0 1px 1px ${SHADOW_TINT}`,\n fontSize: 14,\n fontWeight: 500,\n paddingInline: 12,\n } as React.CSSProperties,\n};\n\n/**\n * The chip treatment for a control that can carry an `error`: Mantine paints\n * the error border through the same wrapper vars, and an inline var would win\n * over it — so an erroring control drops the wrapper vars and keeps the shape.\n */\nexport function chipInputStyles(hasError: boolean): typeof chipInput | { input: React.CSSProperties } {\n return hasError ? { input: chipInput.input } : chipInput;\n}\n\n/** The pill segmented control — active segment filled with the accent. */\nexport const segmentedPill = {\n root: {\n background: SURFACE,\n border: `1px solid ${HAIRLINE}`,\n borderRadius: 999,\n padding: 3,\n '--sc-radius': '999px',\n '--sc-color': ACCENT,\n '--sc-label-color': 'var(--mantine-color-white)',\n } as React.CSSProperties,\n label: { fontSize: 13.5, fontWeight: 500 } as React.CSSProperties,\n};\n\n/**\n * A quiet chip button (templates, one-tap actions) — accent tint on hover only.\n * Colours go through Mantine's button vars, not painted properties, so the\n * hover and disabled states keep working exactly as the framework renders them.\n */\nexport const chipButton = {\n root: {\n fontWeight: 500,\n boxShadow: `0 1px 1px ${SHADOW_TINT}`,\n '--button-radius': '8px',\n '--button-bd': `1px solid ${HAIRLINE}`,\n '--button-bg': SURFACE,\n '--button-color': INK,\n '--button-hover': ACCENT_SOFT,\n '--button-hover-color': INK,\n } as React.CSSProperties,\n};\n\n/** A borderless quiet button — same hover tint, no chip chrome. */\nexport const quietButton = {\n root: {\n fontWeight: 500,\n '--button-radius': '8px',\n '--button-bg': 'transparent',\n '--button-color': SLATE,\n '--button-hover': ACCENT_SOFT,\n '--button-hover-color': INK,\n } as React.CSSProperties,\n};\n\n/** The consequence as a soft tinted pill — its own colour at ~10%, never solid. */\nexport function consequencePillStyle(color: string): React.CSSProperties {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 4,\n borderRadius: 8,\n color,\n background: `color-mix(in srgb, ${color} 10%, transparent)`,\n };\n}\n\n/** Quoted values are the data in the sentence — upright and bolder than the prose. */\nconst QUOTED = /(“[^”]*”)/g;\n\n/**\n * The plain-English sentence, set as an accent quote: accent bar, tinted\n * ground, italic prose. The string is exactly what `describeRule` wrote —\n * only the typography changes here.\n */\nexport const RuleSentence: React.FC<{ text: string }> = ({ text }) => (\n <div\n style={{\n borderLeft: `3px solid ${ACCENT}`,\n background: ACCENT_SOFT,\n borderRadius: '0 8px 8px 0',\n padding: '8px 12px',\n fontSize: 14,\n fontStyle: 'italic',\n lineHeight: 1.55,\n color: INK,\n }}\n >\n {text.split(QUOTED).map((part, at) =>\n part.startsWith('“') ? (\n // Index keys are safe: the segments are a pure projection of `text`.\n <span key={`${part}${at}`} style={{ fontStyle: 'normal', fontWeight: 600 }}>\n {part}\n </span>\n ) : (\n <React.Fragment key={`${part}${at}`}>{part}</React.Fragment>\n )\n )}\n </div>\n);\n","import React, { useMemo, useState } from 'react';\nimport { ActionIcon, Alert, Button, Group, Modal, Paper, ScrollArea, Stack, Text } from '@mantine/core';\nimport { IconAlertTriangle, IconPlus, IconRobot, IconTrash } from '@tabler/icons-react';\nimport type { RubricBody, RubricFieldCatalog, RubricOperator } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { operatorsForKind, validateRubric } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport BaseMultiSelect from '@/mantine/components/Base/BaseMultiSelect';\nimport BasePrimaryButton from '@/mantine/components/Base/BasePrimaryButton';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { actionAlertStyles } from '../../alertStyles';\nimport { ValueInput, LiteralInput } from './ValueInput';\nimport {\n AI_CHECK_LANE_LABEL,\n AI_SEES_LABEL,\n AI_SEES_PLACEHOLDER,\n AI_SETTING_HINT,\n aiSeesHint,\n describeLinked,\n fieldTitle,\n LINKED_AI_ELSE_LEAD,\n LINKED_AI_PLACEHOLDER,\n LINKED_AI_ROW_LEAD,\n LINKED_DUPLICATE_CASE_TEXT,\n LINKED_MISSING_AI_TEXT,\n LINKED_MISSING_CASE_TEXT,\n OPERATOR_PHRASE,\n problemText,\n takesNoValue,\n} from './phrases';\nimport { chipInput, chipInputStyles, leadWordStyle, microLabelStyle, panelStyle, quietButton, RuleSentence } from './rubricStyles';\nimport { applyLinkedDraft, draftFromLinked, newLinkedDraft, type LinkedCaseDraft, type LinkedDraft } from './ruleDraft';\nimport { removeGatesAt, type FieldIndex, type LinkedRule } from './ruleModel';\n\n/**\n * Writing one linked rule — linked-rules design Part 3, zero format change.\n *\n * The case table: \"[Salary] must be [exactly] ___ depending on [Employee\n * name]\", one row per case plus a PERMANENT \"anyone else\" row the author cannot\n * remove — which is what makes the compiled gates exhaustive and\n * non-overlapping by construction. The `notIn` union on the else gate is\n * maintained invisibly; the author never sees it.\n *\n * The check box also offers \"🤖 AI checks it\" (§A.15) — ONE mode for the whole\n * table, never per-row: every case's \"it must be\" becomes an instructions text\n * the AI checks (\"The invoice must show a salary of 3000\"), the anyone-else row\n * included. Each row compiles to its own AiCheck; the guard lattice is exactly\n * the value table's.\n */\n\n/** The check box's \"🤖 AI checks it\" entry — a table-wide mode, not an operator (mirrors `RuleEditor`). */\nconst AI_MODE = '__ai-check__';\n\ninterface LinkedRuleEditorProps {\n opened: boolean;\n onClose: () => void;\n body: RubricBody;\n catalog: RubricFieldCatalog;\n index: FieldIndex;\n /** The checked answer the card was opened from — changeable inside. */\n initialChecked: string;\n /** The linked rule being changed; omitted when adding a new one. */\n editing?: LinkedRule;\n onSave: (draft: LinkedDraft) => void;\n}\n\n/** Kinds a guard can be — where checking \"is exactly this value\" makes sense. */\nconst GUARD_KINDS = new Set(['text', 'number', 'choice']);\n\n/** The checks a case row can ask of the checked answer — every legal operator that takes a value. */\nfunction legalOps(index: FieldIndex, path: string): RubricOperator[] {\n return operatorsForKind(index.get(path)?.kind ?? 'text').filter((op) => !takesNoValue(op));\n}\n\nexport const LinkedRuleEditor: React.FC<LinkedRuleEditorProps> = ({ opened, onClose, body, catalog, index, initialChecked, editing, onSave }) => {\n const [draft, setDraft] = useState<LinkedDraft>(() => {\n if (editing) return draftFromLinked(editing, index);\n const guard = [...index.values()].find((entry) => GUARD_KINDS.has(entry.kind) && entry.path !== initialChecked && !entry.path.includes('[*]'));\n return newLinkedDraft(initialChecked, legalOps(index, initialChecked)[0] ?? '==', guard?.path ?? '');\n });\n\n const checkedField = index.get(draft.checkedField);\n const guardField = index.get(draft.guardField);\n const ctx = useMemo(() => ({ fields: index }), [index]);\n\n const checkedOptions = useMemo(\n () => [...index.values()].filter((entry) => entry.path !== draft.guardField).map((entry) => ({ value: entry.path, label: entry.title })),\n [index, draft.guardField]\n );\n const guardOptions = useMemo(\n () =>\n [...index.values()]\n .filter((entry) => GUARD_KINDS.has(entry.kind) && entry.path !== draft.checkedField && !entry.path.includes('[*]'))\n .map((entry) => ({ value: entry.path, label: entry.title })),\n [index, draft.checkedField]\n );\n const opOptions = useMemo(\n () => [\n ...legalOps(index, draft.checkedField).map((op) => {\n const phrase = OPERATOR_PHRASE[op];\n return { value: op, label: phrase.suffix ? `${phrase.label} … ${phrase.suffix}` : phrase.label };\n }),\n // The AI lane, entered from the check box like everywhere else (§A.15).\n { value: AI_MODE, label: AI_CHECK_LANE_LABEL },\n ],\n [index, draft.checkedField]\n );\n\n /** Another answer to check: the required values were about the old one, so they clear; the guard values stay. */\n const pickChecked = (path: string | null) => {\n if (!path) return;\n setDraft((current) => {\n const legal = legalOps(index, path);\n const op = legal.includes(current.op) ? current.op : legal[0];\n return {\n ...current,\n checkedField: path,\n op,\n cases: current.cases.map((row) => ({ ...row, value: undefined, tolerance: undefined })),\n elseCase: { ...current.elseCase, value: undefined, tolerance: undefined },\n };\n });\n };\n\n /** A new check wants new values — same clearing rule as the plain sentence row. */\n const pickOp = (op: string | null) => {\n if (!op) return;\n // \"AI checks it\" is a mode for the WHOLE table, not an operator. Both sides\n // of every row are kept while the author flips — leaving the lane restores\n // the values untouched (the rule editor's keep-both discipline).\n if (op === AI_MODE) {\n setDraft((current) => ({ ...current, aiMode: true }));\n return;\n }\n setDraft((current) => {\n if (current.aiMode && op === current.op) return { ...current, aiMode: false };\n return {\n ...current,\n aiMode: false,\n op: op as RubricOperator,\n cases: current.cases.map((row) => ({ ...row, value: undefined, tolerance: undefined })),\n elseCase: { ...current.elseCase, value: undefined, tolerance: undefined },\n };\n });\n };\n\n /** Another guard: its values are a different kind of answer, so the case values clear; the required values stay. */\n const pickGuard = (path: string | null) => {\n if (!path) return;\n setDraft((current) => ({ ...current, guardField: path, cases: current.cases.map((row) => ({ ...row, guardValue: undefined })) }));\n };\n\n const setCase = (at: number, patch: Partial<LinkedCaseDraft>) =>\n setDraft((current) => ({ ...current, cases: current.cases.map((row, i) => (i === at ? { ...row, ...patch } : row)) }));\n const addCase = () => setDraft((current) => ({ ...current, cases: [...current.cases, {}] }));\n const removeCase = (at: number) => setDraft((current) => (current.cases.length <= 1 ? current : { ...current, cases: current.cases.filter((_, i) => i !== at) }));\n\n // The table exactly as it would be saved: the gates are compiled onto a\n // throwaway copy and judged by the one validator, so the preview sentence and\n // the problem list are literally what saving produces.\n const preview = useMemo(() => {\n const base = editing ? removeGatesAt(body, editing.indices) : body;\n const applied = applyLinkedDraft(base, { ...draft, editing: undefined }, index);\n const first = base.gates?.length ?? 0;\n const count = draft.cases.length + 1;\n const problems = validateRubric(applied, catalog)\n .filter((diagnostic) => {\n if (diagnostic.severity !== 'error') return false;\n const at = /^\\/gates\\/(\\d+)/.exec(diagnostic.path);\n return !!at && Number(at[1]) >= first && Number(at[1]) < first + count;\n })\n .map(problemText);\n const missingCase = draft.cases.some((row) => row.guardValue === undefined || row.guardValue === '');\n if (missingCase) problems.push(LINKED_MISSING_CASE_TEXT);\n const keys = draft.cases.map((row) => JSON.stringify(row.guardValue ?? null));\n if (new Set(keys).size !== keys.length) problems.push(LINKED_DUPLICATE_CASE_TEXT);\n // An AI asked to check nothing could never answer — every row needs words.\n if (draft.aiMode && [...draft.cases, draft.elseCase].some((row) => !(row.instructions ?? '').trim())) problems.push(LINKED_MISSING_AI_TEXT);\n const sentence = describeLinked(\n {\n checkedField: draft.checkedField,\n op: draft.op,\n guardField: draft.guardField,\n cases: draft.cases,\n elseValue: draft.elseCase.value,\n ...(draft.aiMode ? { ai: true, elseInstructions: draft.elseCase.instructions } : {}),\n },\n ctx\n );\n return { sentence, problems: [...new Set(problems)] };\n }, [body, catalog, ctx, draft, editing, index]);\n\n const missingReason = !draft.reason.trim();\n const canSave = preview.problems.length === 0 && !missingReason && !!draft.guardField;\n const opLabel = OPERATOR_PHRASE[draft.op]?.label ?? '';\n const opSuffix = OPERATOR_PHRASE[draft.op]?.suffix;\n\n return (\n <Modal\n opened={opened}\n onClose={onClose}\n title={editing ? 'Change this rule' : `“${fieldTitle(draft.checkedField, ctx)}” depends on another answer`}\n size=\"xl\"\n radius={14}\n styles={{ title: { fontWeight: 600 } }}\n scrollAreaComponent={ScrollArea.Autosize}\n >\n <Stack gap=\"md\">\n <Group gap={8} align=\"center\" wrap=\"wrap\">\n <BaseSelect w={230} styles={chipInput} data={checkedOptions} value={draft.checkedField} onChange={pickChecked} searchable={checkedOptions.length > 6} />\n <BaseSelect\n w={210}\n styles={chipInput}\n data={opOptions}\n value={draft.aiMode ? AI_MODE : draft.op}\n onChange={pickOp}\n searchable={opOptions.length > 8}\n renderOption={({ option }) => (\n <Group gap={8} wrap=\"nowrap\">\n {option.value === AI_MODE && icon(IconRobot, 16)}\n <Text size=\"sm\">{option.label}</Text>\n </Group>\n )}\n />\n <Text style={leadWordStyle}>… depending on</Text>\n <BaseSelect\n w={230}\n styles={chipInput}\n data={guardOptions}\n value={draft.guardField || null}\n onChange={pickGuard}\n searchable={guardOptions.length > 6}\n placeholder=\"Which answer?\"\n />\n </Group>\n\n <Paper p=\"md\" style={panelStyle}>\n <Stack gap={8}>\n <Text style={microLabelStyle}>The cases</Text>\n {draft.cases.map((row, at) => (\n <Group key={at} gap={8} align=\"flex-start\" wrap=\"wrap\">\n <Text mt={6} style={leadWordStyle}>\n If it is\n </Text>\n <LiteralInput kind={guardField?.kind ?? 'text'} field={guardField} value={row.guardValue} onChange={(next) => setCase(at, { guardValue: next })} />\n {draft.aiMode ? (\n <>\n <Text mt={6} style={leadWordStyle}>\n {LINKED_AI_ROW_LEAD}\n </Text>\n <BaseTextInput\n style={{ flex: 1, minWidth: 260 }}\n styles={chipInput}\n placeholder={LINKED_AI_PLACEHOLDER}\n value={row.instructions ?? ''}\n onChange={(event) => setCase(at, { instructions: event.currentTarget.value })}\n />\n </>\n ) : (\n <>\n <Text mt={6} style={leadWordStyle}>\n it {opLabel}\n </Text>\n <ValueInput op={draft.op} field={checkedField} index={index} value={row.value} tolerance={row.tolerance} onChange={(patch) => setCase(at, patch)} />\n {opSuffix && (\n <Text mt={6} size=\"sm\" c=\"dimmed\">\n {opSuffix}\n </Text>\n )}\n </>\n )}\n <ActionIcon mt={4} variant=\"subtle\" color=\"red\" onClick={() => removeCase(at)} disabled={draft.cases.length <= 1} aria-label=\"Remove this case\">\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n ))}\n\n {/* The permanent row — no remove button exists for it, by design. */}\n <Group gap={8} align=\"flex-start\" wrap=\"wrap\">\n {draft.aiMode ? (\n <>\n <Text mt={6} style={leadWordStyle}>\n {LINKED_AI_ELSE_LEAD}\n </Text>\n <BaseTextInput\n style={{ flex: 1, minWidth: 260 }}\n styles={chipInput}\n placeholder={LINKED_AI_PLACEHOLDER}\n value={draft.elseCase.instructions ?? ''}\n onChange={(event) => setDraft((current) => ({ ...current, elseCase: { ...current.elseCase, instructions: event.currentTarget.value } }))}\n />\n </>\n ) : (\n <>\n <Text mt={6} style={leadWordStyle}>\n For anyone else, it {opLabel}\n </Text>\n <ValueInput\n op={draft.op}\n field={checkedField}\n index={index}\n value={draft.elseCase.value}\n tolerance={draft.elseCase.tolerance}\n onChange={(patch) => setDraft((current) => ({ ...current, elseCase: { ...current.elseCase, ...patch } }))}\n />\n {opSuffix && (\n <Text mt={6} size=\"sm\" c=\"dimmed\">\n {opSuffix}\n </Text>\n )}\n </>\n )}\n </Group>\n\n <Button variant=\"subtle\" size=\"compact-sm\" styles={quietButton} style={{ alignSelf: 'flex-start' }} leftSection={<IconPlus size={14} />} onClick={addCase}>\n Add another case\n </Button>\n </Stack>\n </Paper>\n\n {/* AI mode: what every case's check gets to look at — the checked answer\n always, plus any extra answers, shared by the whole table. The same\n collection-setting hint the inline AI check shows (§C.7 is the hard\n stop; this avoids reaching it). */}\n {draft.aiMode && (\n <Paper p=\"md\" style={panelStyle}>\n <Stack gap=\"xs\">\n <Group gap={6} wrap=\"nowrap\">\n {icon(IconRobot, 16)}\n <Text size=\"sm\" fw={600}>\n {AI_SEES_LABEL}\n </Text>\n </Group>\n <Text size=\"xs\" c=\"dimmed\">\n {aiSeesHint(fieldTitle(draft.checkedField, ctx))}\n </Text>\n <Text size=\"xs\" c=\"dimmed\">\n {AI_SETTING_HINT}\n </Text>\n <BaseMultiSelect\n styles={chipInput}\n placeholder={AI_SEES_PLACEHOLDER}\n data={[...index.values()].filter((entry) => entry.path !== draft.checkedField).map((entry) => ({ value: entry.path, label: entry.title }))}\n value={(draft.alsoSend ?? []).filter((path) => path !== draft.checkedField)}\n onChange={(alsoSend) => setDraft((current) => ({ ...current, alsoSend: alsoSend.length > 0 ? alsoSend : undefined }))}\n searchable\n />\n </Stack>\n </Paper>\n )}\n\n <BaseTextInput\n label=\"What should the claimant be told?\"\n styles={chipInputStyles(missingReason)}\n placeholder=\"e.g. The amount does not match our records\"\n description=\"One message for the whole table — each case adds which answer it was checked against.\"\n error={missingReason ? 'Please write the message.' : undefined}\n value={draft.reason}\n onChange={(event) => setDraft((current) => ({ ...current, reason: event.currentTarget.value }))}\n />\n\n {preview.problems.length > 0 && (\n <Alert color=\"red\" icon={<IconAlertTriangle size={16} />} styles={actionAlertStyles}>\n <Stack gap={2}>\n {preview.problems.map((problem) => (\n <Text key={problem} size=\"xs\">\n {problem}\n </Text>\n ))}\n </Stack>\n </Alert>\n )}\n\n <Stack gap={6}>\n <Text style={microLabelStyle}>This rule reads:</Text>\n <RuleSentence text={preview.sentence} />\n </Stack>\n\n <Group justify=\"flex-end\" gap=\"xs\">\n <Button variant=\"default\" onClick={onClose}>\n Cancel\n </Button>\n <BasePrimaryButton disabled={!canSave} onClick={() => onSave(draft)}>\n {editing ? 'Save the change' : 'Add this rule'}\n </BasePrimaryButton>\n </Group>\n </Stack>\n </Modal>\n );\n};\n","import React, { useMemo } from 'react';\nimport { Group, SegmentedControl, Stack, TagsInput, Text } from '@mantine/core';\nimport { DateTimePicker } from '@mantine/dates';\nimport type { RubricCtxToken, RubricField, RubricFieldKind, RubricOperator } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport BaseMultiSelect from '@/mantine/components/Base/BaseMultiSelect';\nimport BaseNumberInput from '@/mantine/components/Base/BaseNumberInput';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { CTX_LABEL, MEDIA_TYPES, takesNoValue } from './phrases';\nimport type { FieldIndex } from './ruleModel';\nimport { chipInput, segmentedPill } from './rubricStyles';\n\n/**\n * The last box of the sentence — \"If [answer] [check] **[value]**\".\n *\n * Two promises to the author, both of which the format needs kept:\n *\n * 1. **The value box always matches the question.** A date gets a calendar, a\n * choice gets that question's own options, a number gets a number pad. You\n * cannot type a word into a number rule, so `RUB_VALUE_TYPE` should never\n * reach anyone who stays on this screen.\n * 2. **A choice shows its text and stores its value** (§A.3, and the single\n * most likely bug in this block): the devnet form's outlet options are\n * `{value: \"Item 1\", text: \"BRA_1\"}`, the author reads BRA_1 and the rule\n * serializes \"Item 1\". Every option list below is built `{value: choice.value,\n * label: choice.text}` — never the other way round.\n *\n * \"Another answer\" turns any value box into a cross-field rule (§A.4): the\n * refs on offer are filtered to the same kind, so an author can compare a date\n * with a date and never with a photo.\n */\n\ninterface ValueInputProps {\n op: RubricOperator;\n /** The question the check is about — its kind types this box, its choices fill it. */\n field: RubricField | undefined;\n index: FieldIndex;\n value: unknown;\n tolerance?: number;\n onChange: (patch: { value?: unknown; tolerance?: number }) => void;\n disabled?: boolean;\n}\n\n/** Dates the engine knows without asking — how \"before the collection closes\" gets written. */\nconst CTX_DATES: RubricCtxToken[] = ['ctx.now', 'ctx.collection.startDate', 'ctx.collection.endDate', 'ctx.claim.submissionDate'];\n\nexport const ValueInput: React.FC<ValueInputProps> = ({ op, field, index, value, tolerance, onChange, disabled }) => {\n const kind = field?.kind ?? 'text';\n const setValue = (next: unknown) => onChange({ value: next });\n\n // Refs of the same kind — \"another answer\", the cross-field lane.\n const refOptions = useMemo(() => {\n const needed = comparableKind(op, kind);\n const options = [...index.values()]\n .filter((entry) => entry.kind === needed && entry.path !== field?.path && !entry.path.includes('[*]'))\n .map((entry) => ({ value: entry.path, label: entry.title }));\n if (needed === 'date') options.push(...CTX_DATES.map((token) => ({ value: token, label: CTX_LABEL[token] })));\n return options;\n }, [index, op, kind, field?.path]);\n\n if (takesNoValue(op)) return null;\n\n switch (op) {\n case 'between':\n return <PairInput kind={kind === 'date' ? 'date' : 'number'} value={value} onChange={setValue} disabled={disabled} labels={['from', 'to']} />;\n case 'lengthBetween':\n return <PairInput kind=\"number\" value={value} onChange={setValue} disabled={disabled} labels={['at least', 'at most']} />;\n case 'countBetween':\n return <PairInput kind=\"number\" value={value} onChange={setValue} disabled={disabled} labels={['at least', 'at most']} />;\n\n case 'withinDays':\n case 'maxSizeMB':\n return (\n <BaseNumberInput w={140} styles={chipInput} min={0} value={typeof value === 'number' ? value : ''} onChange={(next) => setValue(toNumber(next))} disabled={disabled} />\n );\n\n case 'approx':\n return (\n <Group gap=\"xs\" wrap=\"nowrap\">\n <LiteralOrRef kind=\"number\" field={field} index={index} refOptions={refOptions} value={value} onChange={setValue} disabled={disabled} />\n <Text size=\"xs\" c=\"dimmed\" fw={500}>\n give or take\n </Text>\n <BaseNumberInput\n w={100}\n styles={chipInput}\n min={0}\n value={typeof tolerance === 'number' ? tolerance : ''}\n onChange={(next) => onChange({ tolerance: toNumber(next) ?? 0 })}\n disabled={disabled}\n />\n </Group>\n );\n\n case 'in':\n case 'notIn':\n case 'containsAll':\n case 'containsAny':\n case 'subsetOf':\n return <ListInput field={field} value={value} onChange={setValue} disabled={disabled} />;\n\n case 'contains':\n return <LiteralOrRef kind={kind === 'multichoice' ? 'choice' : kind} field={field} index={index} refOptions={[]} value={value} onChange={setValue} disabled={disabled} />;\n\n case 'mediaTypeIn':\n return (\n <BaseMultiSelect\n w={280}\n styles={chipInput}\n placeholder=\"Pick the file types you accept\"\n data={MEDIA_TYPES.map((type) => ({ value: type.value, label: type.label }))}\n value={Array.isArray(value) ? value.map(String) : []}\n onChange={(next) => setValue(next)}\n disabled={disabled}\n />\n );\n\n case 'matches':\n return (\n <BaseTextInput\n w={260}\n styles={chipInput}\n placeholder=\"e.g. ^INV-[0-9]{6}$\"\n description=\"A simple pattern the answer has to match.\"\n value={typeof value === 'string' ? value : ''}\n onChange={(event) => setValue(event.currentTarget.value)}\n disabled={disabled}\n />\n );\n\n case 'withinRadius': {\n const spec = (value ?? {}) as { center?: unknown; meters?: unknown };\n return (\n <Group gap=\"xs\" wrap=\"nowrap\">\n <BaseSelect\n w={200}\n styles={chipInput}\n placeholder=\"Near which answer?\"\n data={refOptions}\n value={typeof spec.center === 'string' ? spec.center : null}\n onChange={(next) => setValue({ ...spec, center: next || undefined })}\n disabled={disabled}\n />\n <BaseNumberInput\n w={120}\n styles={chipInput}\n min={1}\n suffix=\" m\"\n value={typeof spec.meters === 'number' ? spec.meters : ''}\n onChange={(next) => setValue({ ...spec, meters: toNumber(next) })}\n disabled={disabled}\n />\n </Group>\n );\n }\n\n case 'startsWith':\n case 'endsWith':\n return (\n <BaseTextInput w={220} styles={chipInput} value={typeof value === 'string' ? value : ''} onChange={(event) => setValue(event.currentTarget.value)} disabled={disabled} />\n );\n\n default:\n return <LiteralOrRef kind={comparableKind(op, kind)} field={field} index={index} refOptions={refOptions} value={value} onChange={setValue} disabled={disabled} />;\n }\n};\n\n// ---------------------------------------------------------------------------\n\n/** What kind of value an operator wants for a field of `kind` (a date `>` still wants a date). */\nfunction comparableKind(op: RubricOperator, kind: RubricFieldKind): RubricFieldKind {\n if (op === 'before' || op === 'after') return 'date';\n if (op === '>' || op === '>=' || op === '<' || op === '<=' || op === 'approx') return kind === 'date' ? 'date' : 'number';\n if (op === 'withinRadius') return 'geo';\n return kind;\n}\n\n/** A fixed value, or another answer — the cross-field switch. */\nconst LiteralOrRef: React.FC<{\n kind: RubricFieldKind;\n field: RubricField | undefined;\n index: FieldIndex;\n refOptions: { value: string; label: string }[];\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n}> = ({ kind, field, refOptions, value, onChange, disabled }) => {\n const isRef = typeof value === 'string' && (value.startsWith('$') || value.startsWith('ctx.') || value.startsWith('ext.'));\n const mode = isRef ? 'ref' : 'literal';\n\n return (\n <Stack gap={6}>\n {refOptions.length > 0 && (\n <SegmentedControl\n size=\"xs\"\n styles={segmentedPill}\n value={mode}\n onChange={(next) => onChange(next === 'ref' ? refOptions[0]?.value : undefined)}\n data={[\n { value: 'literal', label: 'A value' },\n { value: 'ref', label: 'Another answer' },\n ]}\n disabled={disabled}\n />\n )}\n {mode === 'ref' ? (\n <BaseSelect\n w={240}\n styles={chipInput}\n placeholder=\"Which answer?\"\n data={refOptions}\n value={typeof value === 'string' ? value : null}\n onChange={(next) => onChange(next || undefined)}\n disabled={disabled}\n searchable\n />\n ) : (\n <LiteralInput kind={kind} field={field} value={value} onChange={onChange} disabled={disabled} />\n )}\n </Stack>\n );\n};\n\n/** One value, typed by the question's kind. Exported for the linked-rule case table's guard values, which are always literals. */\nexport const LiteralInput: React.FC<{ kind: RubricFieldKind; field: RubricField | undefined; value: unknown; onChange: (next: unknown) => void; disabled?: boolean }> = ({\n kind,\n field,\n value,\n onChange,\n disabled,\n}) => {\n switch (kind) {\n case 'number':\n return (\n <BaseNumberInput\n w={160}\n styles={chipInput}\n placeholder=\"0\"\n value={typeof value === 'number' ? value : ''}\n onChange={(next) => onChange(toNumber(next))}\n disabled={disabled}\n />\n );\n case 'date':\n return (\n <DateTimePicker\n w={240}\n styles={chipInput}\n placeholder=\"Pick a date\"\n valueFormat=\"DD MMM YYYY, HH:mm\"\n clearable\n value={isoToDate(value)}\n onChange={(next) => onChange(dateToIso(next))}\n disabled={disabled}\n />\n );\n case 'boolean':\n return (\n <BaseSelect\n w={140}\n styles={chipInput}\n data={[\n { value: 'true', label: 'Yes' },\n { value: 'false', label: 'No' },\n ]}\n value={typeof value === 'boolean' ? String(value) : null}\n onChange={(next) => onChange(next === null ? undefined : next === 'true')}\n disabled={disabled}\n />\n );\n case 'choice':\n case 'multichoice':\n // Shows text, stores value (§A.3).\n if (field?.choices?.length) {\n return (\n <BaseSelect\n w={240}\n styles={chipInput}\n placeholder=\"Pick an option\"\n data={field.choices.map((choice) => ({ value: choice.value, label: choice.text }))}\n value={typeof value === 'string' ? value : null}\n onChange={(next) => onChange(next ?? undefined)}\n disabled={disabled}\n searchable\n />\n );\n }\n return (\n <BaseTextInput w={240} styles={chipInput} value={typeof value === 'string' ? value : ''} onChange={(event) => onChange(event.currentTarget.value)} disabled={disabled} />\n );\n default:\n return (\n <BaseTextInput\n w={240}\n styles={chipInput}\n placeholder=\"Type the value\"\n value={typeof value === 'string' ? value : ''}\n onChange={(event) => onChange(event.currentTarget.value)}\n disabled={disabled}\n />\n );\n }\n};\n\n/** A list of values: the question's own options where it has them, free entries where it doesn't. */\nconst ListInput: React.FC<{ field: RubricField | undefined; value: unknown; onChange: (next: unknown) => void; disabled?: boolean }> = ({ field, value, onChange, disabled }) => {\n const current = Array.isArray(value) ? value.map(String) : [];\n if (field?.choices?.length) {\n return (\n <BaseMultiSelect\n w={300}\n styles={chipInput}\n placeholder=\"Pick the options you allow\"\n data={field.choices.map((choice) => ({ value: choice.value, label: choice.text }))}\n value={current}\n onChange={(next) => onChange(next)}\n disabled={disabled}\n searchable\n />\n );\n }\n const numeric = field?.kind === 'number';\n return (\n <TagsInput\n w={300}\n styles={chipInput}\n placeholder=\"Type a value, press Enter\"\n value={current}\n onChange={(next) => onChange(numeric ? next.map(Number).filter((entry) => !Number.isNaN(entry)) : next)}\n disabled={disabled}\n />\n );\n};\n\n/** `[min, max]` — two boxes, one value. */\nconst PairInput: React.FC<{ kind: 'number' | 'date'; value: unknown; onChange: (next: unknown) => void; disabled?: boolean; labels: [string, string] }> = ({\n kind,\n value,\n onChange,\n disabled,\n labels,\n}) => {\n const pair = Array.isArray(value) ? value : [undefined, undefined];\n const setAt = (at: 0 | 1, next: unknown) => {\n const updated = [pair[0], pair[1]];\n updated[at] = next;\n onChange(updated);\n };\n return (\n <Group gap=\"xs\" wrap=\"nowrap\" align=\"flex-end\">\n {([0, 1] as const).map((at) => (\n <Stack key={at} gap={2}>\n <Text size=\"xs\" c=\"dimmed\" fw={500}>\n {labels[at]}\n </Text>\n {kind === 'date' ? (\n <DateTimePicker\n w={190}\n styles={chipInput}\n valueFormat=\"DD MMM YYYY, HH:mm\"\n clearable\n value={isoToDate(pair[at])}\n onChange={(next) => setAt(at, dateToIso(next))}\n disabled={disabled}\n />\n ) : (\n <BaseNumberInput\n w={110}\n styles={chipInput}\n value={typeof pair[at] === 'number' ? (pair[at] as number) : ''}\n onChange={(next) => setAt(at, toNumber(next))}\n disabled={disabled}\n />\n )}\n </Stack>\n ))}\n </Group>\n );\n};\n\n// ── conversions (the pickers speak Date/string, the document speaks ISO) ────\n\nfunction isoToDate(value: unknown): Date | null {\n if (typeof value !== 'string' || !value) return null;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\nfunction dateToIso(value: Date | null): string | undefined {\n if (!value) return undefined;\n try {\n return value.toISOString();\n } catch {\n return undefined;\n }\n}\n\nfunction toNumber(value: string | number): number | undefined {\n if (value === '' || value === null || value === undefined) return undefined;\n const parsed = typeof value === 'number' ? value : Number(value);\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n","import type {\n RubricAiCheck,\n RubricBody,\n RubricCondition,\n RubricExternalSource,\n RubricGate,\n RubricGateClass,\n RubricOperator,\n RubricReviewAnswerShape,\n RubricReviewTask,\n} from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { linkedCaseText, linkedElseText, SCORE_FLOOR_REASON, SCORE_HOLD_REASON } from './phrases';\nimport {\n FAILED,\n PASSED,\n aiMemberName,\n aiSendFields,\n nextCode,\n putCriterion,\n putGate,\n putReviewTask,\n removeGatesAt,\n removeRule,\n toCondition,\n toSimpleRule,\n type Consequence,\n type FieldIndex,\n type LinkedRule,\n type SimpleRule,\n type UiRule,\n} from './ruleModel';\n\n/**\n * The classes a FAILING check can produce — the format's own type now says so\n * (§A.6), so this is a plain re-export rather than the local `Exclude<…>` it\n * used to be. The author never picks a class at all (it is receipt bookkeeping,\n * never words on a screen); the templates choose the honest one for each rule.\n */\nexport type GateClass = RubricGateClass;\n\n/**\n * One rule while it is being written — the builder's only piece of editing\n * state, and the bridge between the sentence builder and the document.\n *\n * Both consequences are kept side by side on purpose: switching between ⛔ and\n * 👤 must never throw away what the author already typed, and the document only\n * ever hears about the ONE they settled on (`applyDraft`). The payloads are the\n * document's own nodes, so there is no shadow rule format to keep in sync.\n */\nexport interface RuleDraft {\n /** Index of the rule being edited within its list; `undefined` = a new rule. */\n at?: number;\n /** The rule's code. Machine-facing only: it names the rule in the engine's receipt. */\n code: string;\n /** The answer this rule is about — the card's question, one of its inner answers, or (with `ext`) an `ext.<name>.*` ref. */\n field: string;\n consequence: Consequence;\n reject: { when: SimpleRule; reason: string; onFail: 'reject' | 'review'; verdictClass: GateClass };\n human: {\n /**\n * What happens when there is nothing to look at: `PASSED` or `FAILED`. The\n * format stores it as the criterion's score, but v1 shows it as the\n * pass-or-fail choice it actually is.\n */\n whenMissing: number;\n taskId: string;\n prompt: string;\n show: string[];\n answer: RubricReviewAnswerShape;\n map: Record<string, 'approve' | 'partial' | 'reject'>;\n /**\n * WHO reviews — the rubric-wide `review.assignTo.assigneeDid` (§A.9),\n * picked right in the 👤 outcome and committed with the rule (the same\n * one-modal pattern as an inline external check). Loaded from the shared\n * value on open; there is ONE reviewer routing, so the last save wins.\n * One-of with `channelRoomId` — the picker clears the other side.\n */\n assigneeDid?: string;\n /**\n * WHERE reviews land — the rubric-wide `review.route.matrixRoom` (§A.9): a\n * real Matrix room id/alias picked from the entity's channels (or pasted).\n * Anyone in that room reviews. One-of with `assigneeDid`.\n */\n channelRoomId?: string;\n };\n /** Set when the rule's subject is an outside service's answer (§A.14) — authored inline; `applyDraft` upserts the source. */\n ext?: ExtCheckDraft;\n /** Set when the rule's check is \"the AI checks it\" (§A.15) — authored inline; `applyDraft` upserts the check. */\n ai?: AiCheckDraft;\n /**\n * \"Only check this if…\" (`appliesWhen`, §A.6/§A.8): one optional simple\n * condition, written on the gate/criterion whichever consequence is saved.\n * It lives on the GATE, orthogonal to the checks — available whether the\n * rule holds one check or many.\n */\n appliesWhen?: SimpleRule;\n /**\n * \"One rule, many checks\" (owner 2026-08-03): present iff the rule holds TWO\n * OR MORE checks. Absent, the editor and the compile are EXACTLY the\n * single-check rule they always were (pinned byte-identical); present, the\n * gate's `when` is `{all: members}` — several checks in one rule always mean\n * ALL of them (proposal v3) — and `reject.when`/`ai` are dormant seats the\n * collapse writes back into. Only a ⛔ rule ever grows.\n */\n grown?: GrownChecks;\n}\n\n// ---------------------------------------------------------------------------\n// External checks (§A.14) — a kind of rule on a question, authored inline\n// ---------------------------------------------------------------------------\n\n/**\n * The in-progress external check a rule is being written against. Everything\n * about the source EXCEPT what the author never sees: `name` is auto-generated\n * from the question (`$batchNumber` → `batchNumber_check`) and `send` is the\n * one auto pair `{ batchNumber: \"$batchNumber\" }` — no name field, no mapping\n * editor. Committed to `body.sources` by `applyDraft`, alongside the rule.\n */\nexport interface ExtCheckDraft {\n name: string;\n endpoint: string;\n audience: string;\n /**\n * The answer's shape (§A.14.3): a yes/no, or a score out of 100 (stored as\n * basis points 0..10000 in the document — the ×100 happens at compile). A\n * yes/no compiles to the one fixed \"the service must confirm\" gate; a score\n * compiles to its band gates (`bands` below).\n */\n expect: 'boolean' | 'score';\n /** The question answer this check verifies — becomes the auto `send` and anchors the rule to that card. */\n sendField: string;\n /**\n * Score only — the two numbers the author sets, on THEIR scale (0–100):\n * below `rejectBelow` the claim is turned down (0 = no reject band), from\n * `rejectBelow` to `approveAt - 1` a person decides, at `approveAt`+ it\n * passes. Compiles ×100 into the floor + hold gates.\n */\n bands?: { rejectBelow: number; approveAt: number };\n /** Score only — the floor gate's code, kept across edits so its receipt identity survives a re-save. */\n floorCode?: string;\n}\n\n/** The two numbers a fresh score check starts from — reject below 30, pass at 80. */\nexport const SCORE_BANDS_DEFAULT = { rejectBelow: 30, approveAt: 80 } as const;\n\n/** Keep the bands orderable and on the author's 0–100 scale: `0 ≤ rejectBelow < approveAt ≤ 100`. */\nexport function clampBands(bands: { rejectBelow: number; approveAt: number }): { rejectBelow: number; approveAt: number } {\n const approveAt = Math.min(100, Math.max(1, Math.round(bands.approveAt)));\n const rejectBelow = Math.min(approveAt - 1, Math.max(0, Math.round(bands.rejectBelow)));\n return { rejectBelow, approveAt };\n}\n\n/** The document ref a rule reads the check's answer by — the yes/no, or the score. */\nexport function extSubjectRef(ext: ExtCheckDraft): string {\n return `ext.${ext.name}.${ext.expect === 'score' ? 'score' : 'valid'}`;\n}\n\n/** `$batchNumber` → `batchNumber`; nested paths flatten to one `^[A-Za-z0-9_-]+$` token (the engine's send-key grammar). */\nfunction sendKey(fieldPath: string): string {\n return (\n fieldPath\n .replace(/^\\$/, '')\n .replace(/\\[\\*\\]/g, '')\n .replace(/[^A-Za-z0-9_-]+/g, '_')\n .replace(/_{2,}/g, '_')\n .replace(/^[_-]+|[_-]+$/g, '') || 'answer'\n );\n}\n\n/** The auto name: `$batchNumber` → `batchNumber_check`, deduped `_2`, `_3`… against the sources already declared. */\nexport function autoExtName(sendField: string, sources: RubricExternalSource[] | undefined): string {\n const base = `${sendKey(sendField)}_check`;\n const taken = new Set((sources ?? []).map((source) => source.name));\n if (!taken.has(base)) return base;\n for (let n = 2; ; n++) {\n const name = `${base}_${n}`;\n if (!taken.has(name)) return name;\n }\n}\n\n/** The document source an ext draft commits: auto name, auto `send`, no capability (the host mints it). */\nexport function extSourceFromDraft(ext: ExtCheckDraft): RubricExternalSource {\n return { '@type': 'ExternalSource', name: ext.name, endpoint: ext.endpoint, audience: ext.audience, send: { [sendKey(ext.sendField)]: ext.sendField }, expect: ext.expect };\n}\n\n/** Replace-or-append the draft's source in `sources[]` (keyed by name), leaving every other source alone. */\nexport function upsertExtSource(body: RubricBody, ext: ExtCheckDraft): RubricBody {\n const source = extSourceFromDraft(ext);\n const sources = [...(body.sources ?? [])];\n const at = sources.findIndex((entry) => entry.name === source.name);\n if (at < 0) sources.push(source);\n else sources[at] = source;\n return { ...body, sources };\n}\n\n/**\n * Point a draft at its external check's answer. Called whenever `ext` changes;\n * a change that doesn't move the ref (endpoint/audience edits) carries straight\n * through so the author's work is never rebuilt under them. A change that DOES\n * (the name, or the answer type) rewires the subject: a yes/no to the fixed\n * \"the service must confirm\" check, a score to the HOLD gate its bands compile\n * to (`>= approveAt`, held for a person — `applyDraft` adds the floor).\n *\n * The consequence is always ⛔: a service's verdict is a reject check, and 👤\n * makes no sense on it (a machine's verdict has no evidence for a person to\n * look at — ask the person about the answer directly instead).\n */\nexport function withExtSubject(draft: RuleDraft, ext: ExtCheckDraft): RuleDraft {\n const ref = extSubjectRef(ext);\n if (ext.expect === 'score') {\n // Recomputed on EVERY change — a bands edit moves the hold gate's value\n // even though the ref stays put, so there is no early return here.\n const bands = clampBands(ext.bands ?? SCORE_BANDS_DEFAULT);\n return {\n ...draft,\n ext: { ...ext, bands },\n ai: undefined,\n field: ref,\n consequence: 'reject',\n reject: { ...draft.reject, when: { field: ref, op: '>=', value: bands.approveAt * 100 }, onFail: 'review', verdictClass: 'requires_human_review' },\n };\n }\n if (draft.ext && draft.field === ref) return { ...draft, ext };\n return {\n ...draft,\n ext,\n field: ref,\n consequence: 'reject',\n // Fresh lane entry, a rename, or a score flipped back to yes/no — the fixed\n // check with the lane's default ending, never a leftover score ending.\n reject: { ...draft.reject, when: { field: ref, op: 'isTrue' }, onFail: 'reject', verdictClass: 'refuted' },\n };\n}\n\n// ---------------------------------------------------------------------------\n// AI checks (§A.15) — a kind of check on a question, authored inline\n// ---------------------------------------------------------------------------\n\n/**\n * The in-progress AI check a rule is being written against — the ext draft's\n * twin, minus the plumbing the AI lane doesn't have (no endpoint, no audience:\n * the engine is the service). `name` and `send` are auto-generated from the\n * question; the author only ever writes `instructions`. Committed to\n * `body.aiChecks` by `applyDraft`.\n */\nexport interface AiCheckDraft {\n name: string;\n /** The plain-language rules the AI checks the answer against — ALL must hold. */\n instructions: string[];\n /** The question answer the AI checks — always sent first, and anchors the rule to that card. */\n sendField: string;\n /** Extra answers the AI is shown alongside the checked one — files included, the engine sends them as attachments. */\n alsoSend?: string[];\n}\n\n/** The document ref a rule reads the AI check's answer by — always `.valid` (v1 is yes/no only). */\nexport function aiSubjectRef(ai: AiCheckDraft): string {\n return `ai.${ai.name}.valid`;\n}\n\n/**\n * The auto name: `$batchNumber` → `batchNumber_ai`, deduped `_2`, `_3`… against\n * the checks already declared. `alsoTaken` reserves names not yet committed —\n * the other AI members/cases of an in-flight draft, so minting several in a row\n * yields distinct names (same contract as `nextCode`'s `alsoUsed`).\n */\nexport function autoAiName(sendField: string, aiChecks: RubricAiCheck[] | undefined, alsoTaken: Iterable<string> = []): string {\n const base = `${sendKey(sendField)}_ai`;\n const taken = new Set([...(aiChecks ?? []).map((check) => check.name), ...alsoTaken]);\n if (!taken.has(base)) return base;\n for (let n = 2; ; n++) {\n const name = `${base}_${n}`;\n if (!taken.has(name)) return name;\n }\n}\n\n/**\n * The auto `send`: the checked answer first, then every extra answer the author\n * picked — one entry each. A field picked twice sends once; two paths that\n * flatten to the same key token are deduped `_2`, `_3`… so a later answer never\n * silently overwrites an earlier one.\n */\nexport function aiSendOf(sendField: string, alsoSend?: string[]): Record<string, string> {\n const send: Record<string, string> = {};\n const sent = new Set<string>();\n for (const field of [sendField, ...(alsoSend ?? [])]) {\n if (!field || sent.has(field)) continue;\n sent.add(field);\n const base = sendKey(field);\n let key = base;\n for (let n = 2; key in send; n++) key = `${base}_${n}`;\n send[key] = field;\n }\n return send;\n}\n\n/** The document node an AI draft commits: auto name, auto `send`, tidied instructions. */\nexport function aiCheckFromDraft(ai: AiCheckDraft): RubricAiCheck {\n return {\n '@type': 'AiCheck',\n name: ai.name,\n send: aiSendOf(ai.sendField, ai.alsoSend),\n instructions: ai.instructions.map((rule) => rule.trim()).filter((rule) => rule.length > 0),\n expect: 'boolean',\n };\n}\n\n/** Replace-or-append one check node in `aiChecks[]` (keyed by name), leaving every other check alone. */\nfunction putAiCheckNode(body: RubricBody, check: RubricAiCheck): RubricBody {\n const aiChecks = [...(body.aiChecks ?? [])];\n const at = aiChecks.findIndex((entry) => entry.name === check.name);\n if (at < 0) aiChecks.push(check);\n else aiChecks[at] = check;\n return { ...body, aiChecks };\n}\n\n/** Replace-or-append the draft's AI check in `aiChecks[]` (keyed by name), leaving every other check alone. */\nexport function upsertAiCheck(body: RubricBody, ai: AiCheckDraft): RubricBody {\n return putAiCheckNode(body, aiCheckFromDraft(ai));\n}\n\n/**\n * The AI-check draft an existing check reads back as — every `$answer` it sends,\n * anchor first — or `undefined` when the check is not editable here (a send\n * carrying ctx/derived/literal entries was written by hand, and re-saving it\n * through the pickers would silently drop those).\n */\nfunction aiDraftFromCheck(check: RubricAiCheck): AiCheckDraft | undefined {\n const sendFields = aiSendFields(check);\n if (!sendFields) return undefined;\n return {\n name: check.name,\n instructions: check.instructions,\n sendField: sendFields[0],\n ...(sendFields.length > 1 ? { alsoSend: sendFields.slice(1) } : {}),\n };\n}\n\n/**\n * Point a draft at its AI check's answer — `withExtSubject`'s twin, and the one\n * lane with no choice of consequence: an AI check is always a yes/no\n * (`expect: 'boolean'`, §A.15) and that verdict decides the claim, so the rule\n * is a ⛔ gate on the fixed \"the AI must confirm\" check. Not 📊 — the AI answers\n * pass-or-fail, not points — and not 👤: its verdict has no evidence for a\n * person to look at, so ask the person directly instead.\n */\nexport function withAiSubject(draft: RuleDraft, ai: AiCheckDraft): RuleDraft {\n const ref = aiSubjectRef(ai);\n if (draft.ai && draft.field === ref) return { ...draft, ai };\n return {\n ...draft,\n ai,\n ext: undefined,\n field: ref,\n consequence: 'reject',\n reject: { ...draft.reject, when: { field: ref, op: 'isTrue' } },\n };\n}\n\nconst AI_SUBJECT_REF = /^ai\\.([A-Za-z0-9_-]+)\\.(valid|reason)$/;\nconst EXT_SUBJECT_REF = /^ext\\.([A-Za-z0-9_-]+)\\.(valid|score|reason)$/;\n\n/**\n * The ai/ext ref an existing rule reads, if its check is one. Only a ⛔ gate can\n * hold one: both `withAiSubject` and `withExtSubject` pin their rule to 'reject'\n * (a machine's yes/no IS the check), so a 👤 rule never carries a check ref.\n */\nfunction checkRefOfRule(rule: UiRule, pattern: RegExp): string | undefined {\n if (rule.consequence !== 'reject') return undefined;\n const candidate = toSimpleRule(rule.gate.when)?.field;\n return candidate && pattern.test(candidate) ? candidate : undefined;\n}\n\n/** A blank rule about `field`, ready for a template to fill in or the author to build by hand. */\nexport function newDraft(body: RubricBody | null, field: string, op: SimpleRule['op'] = 'present'): RuleDraft {\n return {\n code: nextCode(body, 'RULE', field),\n field,\n consequence: 'reject',\n reject: { when: { field, op }, reason: '', onFail: 'reject', verdictClass: 'refuted' },\n human: {\n whenMissing: FAILED,\n taskId: nextCode(body, 'ASK', field),\n prompt: '',\n show: [field],\n answer: { type: 'boolean' },\n map: { true: 'approve', false: 'reject' },\n // The shared reviewer routing, as it stands — so saving without touching\n // the picker writes back exactly what was there.\n assigneeDid: body?.review?.assignTo?.assigneeDid,\n channelRoomId: body?.review?.route?.matrixRoom,\n },\n };\n}\n\n/** Load an existing rule back into the editor. */\nexport function draftFromRule(rule: UiRule, body: RubricBody | null): RuleDraft {\n // A rule that GREW (an `all`-compound `when`, owner 2026-08-03) re-opens\n // with its checks box. Members load like the single lanes below: an AI\n // member from its check (`groupShapeOf` already guaranteed it exists and its\n // send is picker-representable), everything else as the sentence it is. The\n // stored class rides `grown.verdictClass` so an unedited save is byte-stable.\n if (rule.consequence === 'reject' && rule.grown?.editable) {\n const base = plainDraftFromRule(rule, body);\n return {\n ...base,\n grown: {\n members: rule.grown.members.map((member) => {\n const name = aiMemberName(member);\n const check = name ? body?.aiChecks?.find((entry) => entry.name === name) : undefined;\n const ai = check ? aiDraftFromCheck(check) : undefined;\n return ai ? { kind: 'ai' as const, ai } : { kind: 'check' as const, rule: member };\n }),\n verdictClass: gateClassOf(rule.gate.class),\n },\n };\n }\n const draft = plainDraftFromRule(rule, body);\n // An ai-check rule re-opens the same inline instructions, populated from the\n // check it references (§A.15).\n const aiRef = checkRefOfRule(rule, AI_SUBJECT_REF);\n const aiName = aiRef ? AI_SUBJECT_REF.exec(aiRef)?.[1] : undefined;\n const aiCheck = aiName ? body?.aiChecks?.find((entry) => entry.name === aiName) : undefined;\n if (aiRef && aiCheck) {\n const sendField = Object.values(aiCheck.send).find((value): value is string => typeof value === 'string' && value.startsWith('$'));\n // An ai rule is a ⛔ gate on the fixed \"the AI must confirm\" check — the\n // editor offers no other consequence for it. A 📊 criterion reading an AI\n // check predates that (hand-authored, or written before the lane was\n // pinned): re-open it as the gate it can now be, condition and all, rather\n // than into a score editor the author cannot leave.\n const when = draft.reject.when.field === aiRef ? draft.reject.when : { field: aiRef, op: 'isTrue' as const };\n return {\n ...draft,\n field: aiRef,\n consequence: 'reject',\n reject: { ...draft.reject, when },\n // Every sent answer loads back — anchor first, the rest into the picker.\n // A hand-authored send the pickers can't represent falls back to the\n // anchor-only read it always had.\n ai: aiDraftFromCheck(aiCheck) ?? { name: aiCheck.name, instructions: aiCheck.instructions, sendField: sendField ?? rule.fieldPath },\n };\n }\n // An ext-subject rule re-opens the same inline check, populated from the\n // source it references (§A.14) — the subject is the check's answer again.\n const extRef = checkRefOfRule(rule, EXT_SUBJECT_REF);\n const name = extRef ? EXT_SUBJECT_REF.exec(extRef)?.[1] : undefined;\n const source = name ? body?.sources?.find((entry) => entry.name === name) : undefined;\n if (!extRef || !source) return draft;\n const sendField = Object.values(source.send).find((value): value is string => typeof value === 'string' && value.startsWith('$'));\n if (source.expect === 'score') {\n // A score check re-opens as its bands card. Only the recognised HOLD gate\n // carries `bands` (`listRules`); a lone hand-authored floor is NOT the\n // card — it stays the plain sentence it is, its ending untouched.\n const bands = rule.consequence === 'reject' ? rule.bands : undefined;\n if (!bands) return draft;\n return {\n ...draft,\n field: extRef,\n consequence: 'reject',\n reject: {\n ...draft.reject,\n when: { field: extRef, op: '>=', value: bands.approveAt },\n onFail: 'review',\n // The author's message lives on the FLOOR gate — the hold gate's\n // reason is generated and never shown as theirs.\n reason: bands.floor?.gate.reason ?? '',\n },\n ext: {\n name: source.name,\n endpoint: source.endpoint,\n audience: source.audience,\n expect: 'score',\n sendField: sendField ?? rule.fieldPath,\n // Document bps → the author's 0–100 scale (hand-authored odd values\n // snap to whole points on the next save).\n bands: { rejectBelow: Math.round(bands.rejectBelow / 100), approveAt: Math.round(bands.approveAt / 100) },\n ...(bands.floor ? { floorCode: bands.floor.code } : {}),\n },\n };\n }\n return {\n ...draft,\n field: extRef,\n ext: { name: source.name, endpoint: source.endpoint, audience: source.audience, expect: 'boolean', sendField: sendField ?? rule.fieldPath },\n };\n}\n\nfunction plainDraftFromRule(rule: UiRule, body: RubricBody | null): RuleDraft {\n const base = newDraft(body, rule.fieldPath);\n base.at = rule.index;\n base.code = rule.code;\n\n switch (rule.consequence) {\n case 'reject':\n return {\n ...base,\n consequence: 'reject',\n appliesWhen: toSimpleRule(rule.gate.appliesWhen),\n reject: {\n when: toSimpleRule(rule.gate.when) ?? base.reject.when,\n reason: rule.gate.reason,\n onFail: rule.gate.onFail ?? 'reject',\n verdictClass: gateClassOf(rule.gate.class),\n },\n };\n case 'human': {\n const manual = rule.criterion.score as { whenMissing?: number };\n return {\n ...base,\n consequence: 'human',\n appliesWhen: toSimpleRule(rule.criterion.appliesWhen),\n human: {\n ...base.human, // carries the shared reviewer (assigneeDid)\n // Anything that isn't a clean pass reads as a fail — the control only\n // offers the two, so a legacy in-between value settles on one.\n whenMissing: manual.whenMissing === PASSED ? PASSED : FAILED,\n taskId: rule.task?.id ?? base.human.taskId,\n prompt: rule.task?.prompt ?? '',\n show: rule.task?.show ?? [rule.fieldPath],\n answer: rule.task?.answer ?? base.human.answer,\n map: rule.task?.map ?? base.human.map,\n },\n };\n }\n default:\n return base;\n }\n}\n\n/**\n * Commit a draft to the document.\n *\n * A rule that changed consequence (⛔ → 👤) must move between the document's\n * lists, so the old one is removed first — the author renamed the outcome, they\n * did not create a second rule.\n *\n * `fieldTitle` is the question's name as it reads on the form. It only feeds a\n * criterion's `reason`, which nobody types but a claimant may well read in the\n * engine's account of their claim — \"A person checked Quantities delivered\"\n * says something; \"A person checked productSku_quantityDelivery\" says it in a\n * language they never agreed to learn.\n */\nexport function applyDraft(body: RubricBody, draft: RuleDraft, editing?: UiRule, fieldTitle?: string): RubricBody {\n // An inline external check (§A.14) or AI check (§A.15) commits WITH its rule:\n // the node is upserted here, so the rule's `ext.<name>.*`/`ai.<name>.*` ref\n // always resolves in the same document that carries it. A cancelled modal\n // commits nothing; a node no rule references any more is pruned by the caller\n // (`pruneDanglingSources`) after the rule change lands.\n const withSource = draft.ext ? upsertExtSource(body, draft.ext) : draft.ai ? upsertAiCheck(body, draft.ai) : body;\n const moved = editing !== undefined && editing.consequence !== draft.consequence;\n const target = moved ? removeRule(withSource, editing) : withSource;\n const at = moved ? undefined : draft.at;\n // \"Only check this if…\" (§A.6/§A.8) — written on whichever node is saved.\n const appliesWhen = draft.appliesWhen ? { appliesWhen: toCondition(draft.appliesWhen) } : {};\n\n switch (draft.consequence) {\n case 'reject': {\n // A score card owns TWO gates (§A.14 score), so replacing it removes both\n // and inserts at the first's seat — putGate's replace-at-index only fits\n // the one-gate rules, which keep their byte-identical path below.\n const ownedBands = !moved && editing?.consequence === 'reject' && editing.bands ? editing.bands.indices : undefined;\n const base = ownedBands ? removeGatesAt(target, ownedBands) : target;\n const putRejectGates = (b: RubricBody, add: RubricGate[]): RubricBody => {\n if (ownedBands) {\n const gates = [...(b.gates ?? [])];\n gates.splice(Math.min(...ownedBands), 0, ...add);\n return { ...b, gates };\n }\n if (add.length === 1) return putGate(b, add[0], at);\n // A one-gate rule became a score pair: the pair takes the gate's seat.\n const gates = [...(b.gates ?? [])];\n if (at === undefined) gates.push(...add);\n else gates.splice(at, 1, ...add);\n return { ...b, gates };\n };\n\n // A score check (§A.14 score) compiles to its band gates: the optional\n // floor FIRST — the engine acts on the first failing gate, so \"too low →\n // turned down\" must be able to speak before \"borderline → a person\".\n if (draft.ext?.expect === 'score') {\n const bands = clampBands(draft.ext.bands ?? SCORE_BANDS_DEFAULT);\n const ref = extSubjectRef(draft.ext);\n const hold: RubricGate = {\n '@type': 'Gate',\n code: draft.code,\n reason: SCORE_HOLD_REASON,\n ...appliesWhen,\n when: { '@type': 'Condition', field: ref, op: '>=', value: bands.approveAt * 100 },\n onFail: 'review',\n class: 'requires_human_review',\n };\n if (bands.rejectBelow <= 0) return putRejectGates(base, [hold]);\n const floor: RubricGate = {\n '@type': 'Gate',\n code: draft.ext.floorCode ?? nextCode(base, 'RULE', draft.ext.sendField, [draft.code]),\n reason: draft.reject.reason.trim() || SCORE_FLOOR_REASON,\n ...appliesWhen,\n when: { '@type': 'Condition', field: ref, op: '>=', value: bands.rejectBelow * 100 },\n onFail: 'reject',\n class: 'refuted',\n };\n return putRejectGates(base, [floor, hold]);\n }\n\n // A rule that GREW (owner 2026-08-03): one gate, compound `when`. Each AI\n // member's check commits WITH the rule, exactly as the single AI lane's\n // does (§A.15) — the ref the gate reads always resolves in the same\n // document that carries it. A member removed loses its reader; the\n // caller's `pruneDanglingSources` sweeps it after the change lands.\n const grown = draft.grown;\n if (grown && grown.members.length >= 2) {\n const withMemberChecks = grown.members.reduce((acc, member) => (member.kind === 'ai' ? upsertAiCheck(acc, member.ai) : acc), base);\n return putRejectGates(withMemberChecks, [\n {\n '@type': 'Gate',\n code: draft.code,\n reason: draft.reject.reason.trim() || 'This claim does not meet the rules',\n ...appliesWhen,\n when: grownWhen(grown),\n onFail: draft.reject.onFail,\n class: grown.verdictClass ?? 'refuted',\n },\n ]);\n }\n return putRejectGates(base, [\n {\n '@type': 'Gate',\n code: draft.code,\n reason: draft.reject.reason.trim() || 'This claim does not meet the rules',\n ...appliesWhen,\n when: toCondition(draft.reject.when),\n onFail: draft.reject.onFail,\n class: draft.reject.verdictClass,\n },\n ]);\n }\n case 'human': {\n const task: RubricReviewTask = {\n '@type': 'ReviewTask',\n id: draft.human.taskId,\n forCriterion: draft.code,\n prompt: draft.human.prompt.trim() || 'Does this look right?',\n show: draft.human.show,\n answer: draft.human.answer,\n map: draft.human.map,\n };\n const withCriterion = putCriterion(\n target,\n {\n '@type': 'Criterion',\n code: draft.code,\n reason: reasonFor(draft, fieldTitle),\n // `weight` is REQUIRED by the format and read by `weighted_average`\n // alone — inert under `all_pass`, which is the only method v1 writes.\n // A constant keeps it out of the author's way without breaking shape.\n weight: 1,\n ...appliesWhen,\n score: { '@type': 'ManualScore', field: draft.field, whenMissing: draft.human.whenMissing, reviewTask: task.id },\n },\n at\n );\n const withTask = putReviewTask(withCriterion, task);\n // The reviewer routing travels WITH the rule (§A.9) and is rubric-wide,\n // so the picker in any 👤 rule edits the shared value. One-of: a channel\n // (`route.matrixRoom`, a real room the whole lane reviews in) OR a named\n // person (`assignTo.assigneeDid`) — writing one clears the other, and the\n // role lane stays as the fallback when neither is picked.\n const { route: _route, ...review } = withTask.review!;\n const assignTo = { role: review.assignTo?.role || 'reviewer', ...(draft.human.assigneeDid ? { assigneeDid: draft.human.assigneeDid } : {}) };\n return {\n ...withTask,\n review: { ...review, assignTo, ...(draft.human.channelRoomId ? { route: { matrixRoom: draft.human.channelRoomId } } : {}) },\n };\n }\n default:\n return body;\n }\n}\n\n/**\n * The wording that lands in the engine's receipt for a human check. The author\n * is never asked for it — a rejection message is theirs to write, but a\n * criterion's `reason` is bookkeeping, so it is derived from the question.\n */\nfunction reasonFor(draft: RuleDraft, fieldTitle?: string): string {\n // An ext/ai rule's subject path (`ext.<name>.valid`, `ai.<name>.valid`) is\n // machine language — name the question the check verifies, or the check\n // itself, never the raw ref.\n const question = fieldTitle?.trim() || (draft.ext ? `the ${draft.ext.name} check` : draft.ai ? 'the AI check' : plainField(draft.field));\n return `A person checked ${question}`;\n}\n\nfunction plainField(field: string): string {\n // Namespace prefixes are machine addressing — a default reason reads\n // \"A person checked hiveId\", never \"A person checked ixo:hiveId\".\n return field\n .replace(/^\\$/, '')\n .replace(/\\[\\*\\]/g, '')\n .split('.')\n .map((seg) => (seg.includes(':') ? seg.split(':').pop() || seg : seg))\n .join(' ');\n}\n\n/**\n * The stored class, or the honest default for a gate that never set one. The\n * old runtime narrowing (\"it passed\" is not a class a reject rule can hold) is\n * gone: the format's type no longer admits `supported`/`partial` at all (§A.6).\n */\nfunction gateClassOf(value: GateClass | undefined): GateClass {\n return value ?? 'refuted';\n}\n\n// ---------------------------------------------------------------------------\n// Grown rules (owner 2026-08-03, v3) — many checks, ALL must hold, still ONE rule\n// ---------------------------------------------------------------------------\n\n/**\n * One member while its rule is being written: an ordinary sentence check, or\n * \"the AI checks it\" — the same inline AI lane a single-check rule has\n * (§A.15), whose check commits WITH the rule.\n */\nexport type GroupMemberDraft = { kind: 'check'; rule: SimpleRule } | { kind: 'ai'; ai: AiCheckDraft };\n\n/**\n * The grown state of a ⛔ rule — see `RuleDraft.grown`. Compiles to exactly ONE\n * gate whose `when` is `{all: members}` — the per-rule knob is retired\n * (proposal v3; any/at-least are the approval policy's, `policyModel.ts`) —\n * so everything gates have keeps working unchanged (`onFail`, `code`,\n * `reason`, `class`, `appliesWhen`) without the author ever meeting those words.\n */\nexport interface GrownChecks {\n members: GroupMemberDraft[];\n /**\n * The class loaded from an EXISTING compound gate — kept verbatim on save\n * (the byte-stable round trip). Absent for a rule grown this edit session,\n * where save mints the honest default (`refuted` — every check contradicts\n * a rule the author wrote).\n */\n verdictClass?: GateClass;\n}\n\n/**\n * GROW: the current check becomes the first member (the AI lane rides along as\n * an AI member) and a second, mildest-possible check on `seedField` joins it.\n * Every check must pass — adding one can only tighten a rule, never loosen it.\n * No-op for a rule that already grew, for 👤 (person-checks rules never grow),\n * and for the ext lane (an outside service's answer has no member row to edit\n * its endpoint in).\n */\nexport function growDraft(draft: RuleDraft, seedField: string): RuleDraft {\n if (draft.grown || draft.ext || draft.consequence !== 'reject') return draft;\n const first: GroupMemberDraft = draft.ai ? { kind: 'ai', ai: draft.ai } : { kind: 'check', rule: draft.reject.when };\n return { ...draft, ai: undefined, grown: { members: [first, { kind: 'check', rule: { field: seedField, op: 'present' } }] } };\n}\n\n/** One more check on a grown rule. */\nexport function addGrownMember(draft: RuleDraft, seedField: string): RuleDraft {\n if (!draft.grown) return draft;\n return { ...draft, grown: { ...draft.grown, members: [...draft.grown.members, { kind: 'check', rule: { field: seedField, op: 'present' } }] } };\n}\n\n/**\n * Remove one check. Down to ONE member the grown state COLLAPSES back into the\n * plain single-check editor: a sentence member becomes the rule's check again,\n * an AI member re-enters the inline AI lane (`withAiSubject`) — the rule never\n * loses its identity (code, reason, ending, \"only check this if…\").\n */\nexport function removeGrownMember(draft: RuleDraft, at: number): RuleDraft {\n const grown = draft.grown;\n if (!grown) return draft;\n const members = grown.members.filter((_, i) => i !== at);\n if (members.length >= 2) return { ...draft, grown: { ...grown, members } };\n const [last] = members;\n const base = { ...draft, grown: undefined };\n if (!last) return base;\n if (last.kind === 'ai') return withAiSubject(base, last.ai);\n // Mirror `pickSubject`'s show sync so a later switch to 👤 shows the right answer.\n const show = last.rule.field.startsWith('$') && !base.human.show.includes(last.rule.field) ? [last.rule.field] : base.human.show;\n return { ...base, ai: undefined, field: last.rule.field, reject: { ...base.reject, when: last.rule }, human: { ...base.human, show } };\n}\n\n/** The condition one member compiles to — an AI member is the fixed \"the AI must confirm\" check. */\nfunction memberCondition(member: GroupMemberDraft): RubricCondition {\n return member.kind === 'ai' ? { '@type': 'Condition', field: aiSubjectRef(member.ai), op: 'isTrue' } : toCondition(member.rule);\n}\n\n/** The `when` a grown rule compiles to — every check must hold (proposal v3: always `all`). */\nfunction grownWhen(grown: GrownChecks): RubricCondition {\n return { '@type': 'Condition', all: grown.members.map(memberCondition) };\n}\n\n// ---------------------------------------------------------------------------\n// Linked rules (linked-rules design Part 3) — the case table's draft\n// ---------------------------------------------------------------------------\n\n/** One named row: the guard's value and what the checked answer must then be. */\nexport interface LinkedCaseDraft {\n guardValue?: unknown;\n value?: unknown;\n tolerance?: number;\n /** AI mode: what the AI checks for this case, in the author's words (the check's ONE instruction). */\n instructions?: string;\n /** AI mode: the per-case check's name — kept across an edit; minted at save when absent. */\n aiName?: string;\n /** Kept across an edit so the gate keeps its receipt identity; minted at save when absent. */\n code?: string;\n}\n\n/**\n * The case table while it is being written. `elseCase` is a field of the draft,\n * not an entry of `cases` — the model itself has no way to remove the \"anyone\n * else\" row, which is what makes the compiled table exhaustive by construction.\n */\nexport interface LinkedDraft {\n checkedField: string;\n op: RubricOperator;\n guardField: string;\n /** The one wording the author writes; each gate's reason is generated from it plus its case. */\n reason: string;\n cases: LinkedCaseDraft[];\n elseCase: { value?: unknown; tolerance?: number; instructions?: string; aiName?: string; code?: string };\n onFail: 'reject' | 'review';\n verdictClass: GateClass;\n /** The gate indices this card replaces when editing; `undefined` = a new table. */\n editing?: number[];\n /**\n * AI mode — ONE mode for the whole table, never per-row: every case's \"it\n * must be\" is an instructions text the AI checks (one AiCheck per case). The\n * value side of each row is kept while the author flips modes; only the\n * saved mode compiles.\n */\n aiMode?: boolean;\n /** AI mode: extra answers the AI is shown alongside the checked one — shared by every case. */\n alsoSend?: string[];\n}\n\n/** A blank one-case table. */\nexport function newLinkedDraft(checkedField: string, op: RubricOperator, guardField: string): LinkedDraft {\n return { checkedField, op, guardField, reason: '', cases: [{}], elseCase: {}, onFail: 'reject', verdictClass: 'refuted' };\n}\n\n/** The generated per-case reason: the author's one wording, plus which case this gate is. */\nfunction linkedReason(prefix: string, caseText: string): string {\n return `${prefix} — ${caseText}`;\n}\n\n/** Load a recognised linked rule back into the editor, recovering the author's one wording. */\nexport function draftFromLinked(linked: LinkedRule, fields: FieldIndex): LinkedDraft {\n // The prefix is recovered by stripping the exact suffix compile generated for\n // the first case; a reason that doesn't carry it (hand-authored) is used\n // whole. Deterministic either way — recompiling regenerates the suffixes.\n const first = linked.cases[0].gate.reason;\n const suffix = ` — ${linkedCaseText(linked.guardField, linked.cases[0].guardValue, { fields })}`;\n const reason = first.endsWith(suffix) ? first.slice(0, -suffix.length) : first;\n return {\n checkedField: linked.checkedField,\n // An AI table's gates carry no value check, so `op` holds nothing to keep —\n // '==' is the neutral seat the editor re-legalises if the author switches\n // the table back to values.\n op: linked.ai ? '==' : linked.op,\n guardField: linked.guardField,\n reason,\n cases: linked.cases.map((entry) => ({\n guardValue: entry.guardValue,\n value: entry.when.value,\n tolerance: entry.when.tolerance,\n ...(linked.ai ? { instructions: entry.instructions, aiName: entry.aiName } : {}),\n code: entry.code,\n })),\n elseCase: {\n value: linked.elseCase.when.value,\n tolerance: linked.elseCase.when.tolerance,\n ...(linked.ai ? { instructions: linked.elseCase.instructions, aiName: linked.elseCase.aiName } : {}),\n code: linked.elseCase.code,\n },\n onFail: linked.onFail,\n verdictClass: linked.gateClass,\n editing: linked.indices,\n ...(linked.ai ? { aiMode: true, ...(linked.ai.alsoSend.length > 0 ? { alsoSend: linked.ai.alsoSend } : {}) } : {}),\n };\n}\n\n/**\n * Commit a linked draft: one gate per named case plus the \"anyone else\" gate,\n * whose `notIn` list the builder maintains as the union of every named case —\n * the author never sees it. Editing replaces the old gates in place.\n *\n * AI mode compiles the SAME guard lattice — exhaustiveness by construction is\n * untouched — with each row's check swapped for its own AiCheck: the row's\n * instructions text becomes the check's one instruction, the shared `send` is\n * the checked answer plus `alsoSend`, and the gate's `when` reads\n * `ai.<name>.valid`. Names survive edits (`aiName`); a replaced or removed\n * row's check loses its reader and the caller's `pruneDanglingSources` sweeps it.\n */\nexport function applyLinkedDraft(body: RubricBody, draft: LinkedDraft, fields: FieldIndex): RubricBody {\n const at = draft.editing?.length ? Math.min(...draft.editing) : undefined;\n const base = draft.editing?.length ? removeGatesAt(body, draft.editing) : body;\n const prefix = draft.reason.trim() || 'This claim does not meet the rules';\n const minted: string[] = [];\n const codeOf = (row: { code?: string }): string => {\n const code = row.code ?? nextCode(base, 'RULE', draft.checkedField, minted);\n minted.push(code);\n return code;\n };\n const inGuard = (row: LinkedCaseDraft): RubricCondition => ({ '@type': 'Condition', field: draft.guardField, op: 'in', value: [row.guardValue] });\n const elseGuard: RubricCondition = { '@type': 'Condition', field: draft.guardField, op: 'notIn', value: draft.cases.map((row) => row.guardValue) };\n\n if (draft.aiMode) {\n const mintedNames: string[] = [];\n const nameOf = (row: { aiName?: string }): string => {\n const name = row.aiName ?? autoAiName(draft.checkedField, base.aiChecks, mintedNames);\n mintedNames.push(name);\n return name;\n };\n const send = aiSendOf(draft.checkedField, draft.alsoSend);\n const rows: { row: { instructions?: string; aiName?: string; code?: string }; appliesWhen: RubricCondition; caseText: string }[] = [\n ...draft.cases.map((row) => ({ row, appliesWhen: inGuard(row), caseText: linkedCaseText(draft.guardField, row.guardValue, { fields }) })),\n { row: draft.elseCase, appliesWhen: elseGuard, caseText: linkedElseText() },\n ];\n const checks: RubricAiCheck[] = [];\n const aiGates: RubricGate[] = rows.map(({ row, appliesWhen, caseText }) => {\n const name = nameOf(row);\n checks.push({\n '@type': 'AiCheck',\n name,\n send,\n instructions: [(row.instructions ?? '').trim()].filter((rule) => rule.length > 0),\n expect: 'boolean',\n });\n return {\n '@type': 'Gate',\n code: codeOf(row),\n reason: linkedReason(prefix, caseText),\n appliesWhen,\n when: { '@type': 'Condition', field: `ai.${name}.valid`, op: 'isTrue' },\n onFail: draft.onFail,\n class: draft.verdictClass,\n };\n });\n const withChecks = checks.reduce(putAiCheckNode, base);\n const gates = [...(withChecks.gates ?? [])];\n gates.splice(at ?? gates.length, 0, ...aiGates);\n return { ...withChecks, gates };\n }\n\n const whenOf = (row: { value?: unknown; tolerance?: number }): RubricCondition =>\n toCondition({ field: draft.checkedField, op: draft.op, value: row.value, tolerance: row.tolerance });\n const caseGates: RubricGate[] = draft.cases.map((row) => ({\n '@type': 'Gate',\n code: codeOf(row),\n reason: linkedReason(prefix, linkedCaseText(draft.guardField, row.guardValue, { fields })),\n appliesWhen: inGuard(row),\n when: whenOf(row),\n onFail: draft.onFail,\n class: draft.verdictClass,\n }));\n const elseGate: RubricGate = {\n '@type': 'Gate',\n code: codeOf(draft.elseCase),\n reason: linkedReason(prefix, linkedElseText()),\n appliesWhen: elseGuard,\n when: whenOf(draft.elseCase),\n onFail: draft.onFail,\n class: draft.verdictClass,\n };\n const gates = [...(base.gates ?? [])];\n gates.splice(at ?? gates.length, 0, ...caseGates, elseGate);\n return { ...base, gates };\n}\n","import React from 'react';\nimport { ActionIcon, Alert, Box, Button, Group, Paper, Stack, Text } from '@mantine/core';\nimport { IconAlertTriangle, IconLink, IconPencil, IconPlus, IconTrash } from '@tabler/icons-react';\nimport type { RubricAiCheck, RubricField } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport type { RubricProblem } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport { actionAlertStyles } from '../../alertStyles';\nimport { CONSEQUENCES, consequenceIcon, describeLinked, describeRule, GROUP_OUTSIDE_BUILDER_TEXT, KIND_LABEL, LINKED_ADD_LABEL, linkedSentenceOf, problemText } from './phrases';\nimport { cardStyle, consequencePillStyle, microLabelStyle, quietButton, RuleSentence, SLATE } from './rubricStyles';\nimport type { FieldIndex, LinkedRule, UiRule } from './ruleModel';\n\n/**\n * One question of the claim form, and the rules on it — rubric-spec §B.5 rule\n * 2: \"one card per form question; the form IS the navigation\".\n *\n * Everything the author reads here is a sentence (`describeRule`) and every\n * problem is named where it happened, on the question it is about. The card\n * never says what a rule IS — only what it does. A linked rule (Part 3) lists\n * here too: its gates all check THIS question, so this is its card. A rule\n * that GREW more checks (owner 2026-08-03) lists on its FIRST member's card —\n * the grown sentence names every check (all must pass; proposal v3 retired the\n * per-rule knob). A compound the builder cannot represent (hand-authored\n * nesting, `not`, a stray policy-family gate, …) renders as the quiet\n * read-only row — still deletable, never rewritten.\n */\n\ninterface RuleCardProps {\n field: RubricField;\n rules: UiRule[];\n /** The linked rules whose CHECKED answer is this card's question (Part 3 placement). */\n linked?: LinkedRule[];\n /** The problems whose JSON-Pointer resolved to a rule on this card. */\n problems: RubricProblem[];\n index: FieldIndex;\n /** The document's AI checks — a grown rule's AI member line reads what the AI checks, never the raw ref. */\n aiChecks?: RubricAiCheck[];\n onAdd: () => void;\n onEdit: (rule: UiRule) => void;\n onDelete: (rule: UiRule) => void;\n /** Absent when no other question can serve as the guard — the affordance hides. */\n onAddLinked?: () => void;\n onEditLinked?: (linked: LinkedRule) => void;\n onDeleteLinked?: (linked: LinkedRule) => void;\n disabled?: boolean;\n}\n\nexport const RuleCard: React.FC<RuleCardProps> = ({\n field,\n rules,\n linked,\n problems,\n index,\n aiChecks,\n onAdd,\n onEdit,\n onDelete,\n onAddLinked,\n onEditLinked,\n onDeleteLinked,\n disabled,\n}) => {\n const errors = problems.filter((problem) => problem.severity === 'error');\n const warnings = problems.filter((problem) => problem.severity === 'warning');\n const ctx = { fields: index, aiChecks };\n\n return (\n <Paper p={18} style={{ ...cardStyle, ...(errors.length > 0 ? { borderColor: 'var(--mantine-color-red-6)' } : {}) }}>\n <Stack gap=\"sm\">\n <Group gap=\"xs\" justify=\"space-between\" wrap=\"nowrap\">\n <Group gap={8} wrap=\"nowrap\">\n <Text size=\"sm\" c=\"dimmed\">\n ●\n </Text>\n <Text size=\"sm\" fw={600}>\n {field.title}\n </Text>\n {field.isRequired && (\n <Text size=\"xs\" c=\"dimmed\">\n (always asked)\n </Text>\n )}\n </Group>\n <Text style={microLabelStyle}>{KIND_LABEL[field.kind]}</Text>\n </Group>\n\n {rules.length === 0 && (linked ?? []).length === 0 ? (\n <Text size=\"xs\" c=\"dimmed\" pl={20}>\n No rules yet — this answer won&apos;t be checked.\n </Text>\n ) : (\n rules.map((rule) => {\n const grownShape = rule.consequence === 'reject' ? rule.grown : undefined;\n return (\n <Group key={rule.code} gap=\"sm\" align=\"flex-start\" wrap=\"nowrap\" pl={20}>\n <Box mt={2} style={consequencePillStyle(CONSEQUENCES.find((entry) => entry.value === rule.consequence)?.color ?? SLATE)}>\n {consequenceIcon(rule.consequence, 15)}\n </Box>\n <Box style={{ flex: 1 }}>\n {grownShape && !grownShape.editable ? (\n // A compound the builder cannot represent — quiet, honest,\n // and deletable; never rewritten (§B.5 doctrine).\n <Text size=\"xs\" c=\"dimmed\">\n {GROUP_OUTSIDE_BUILDER_TEXT}\n </Text>\n ) : (\n <RuleSentence text={describeRule(rule, ctx)} />\n )}\n </Box>\n {(!grownShape || grownShape.editable) && (\n <ActionIcon variant=\"subtle\" onClick={() => onEdit(rule)} disabled={disabled} aria-label={`Change the rule on ${field.title}`}>\n <IconPencil size={16} />\n </ActionIcon>\n )}\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => onDelete(rule)} disabled={disabled} aria-label={`Delete the rule on ${field.title}`}>\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n );\n })\n )}\n\n {(linked ?? []).map((entry) => (\n <Group key={entry.elseCase.code} gap=\"sm\" align=\"flex-start\" wrap=\"nowrap\" pl={20}>\n <Box mt={2} style={consequencePillStyle(entry.onFail === 'review' ? 'var(--mantine-color-grape-6)' : 'var(--mantine-color-red-6)')}>\n {consequenceIcon(entry.onFail === 'review' ? 'human' : 'reject', 15)}\n </Box>\n <Box style={{ flex: 1 }}>\n <RuleSentence text={describeLinked(linkedSentenceOf(entry), ctx)} />\n </Box>\n <ActionIcon variant=\"subtle\" onClick={() => onEditLinked?.(entry)} disabled={disabled || !onEditLinked} aria-label={`Change the linked rule on ${field.title}`}>\n <IconPencil size={16} />\n </ActionIcon>\n <ActionIcon\n variant=\"subtle\"\n color=\"red\"\n onClick={() => onDeleteLinked?.(entry)}\n disabled={disabled || !onDeleteLinked}\n aria-label={`Delete the linked rule on ${field.title}`}\n >\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n ))}\n\n {errors.length > 0 && (\n <Alert color=\"red\" icon={<IconAlertTriangle size={16} />} styles={actionAlertStyles} p=\"xs\">\n <Stack gap={2}>\n {unique(errors).map((problem) => (\n <Text key={problem} size=\"xs\">\n {problem}\n </Text>\n ))}\n </Stack>\n </Alert>\n )}\n\n {warnings.length > 0 && (\n <Alert color=\"yellow\" styles={actionAlertStyles} p=\"xs\">\n <Stack gap={2}>\n {unique(warnings).map((problem) => (\n <Text key={problem} size=\"xs\">\n {problem}\n </Text>\n ))}\n </Stack>\n </Alert>\n )}\n\n <Group pl={20} gap=\"xs\">\n <Button size=\"compact-xs\" variant=\"subtle\" styles={quietButton} leftSection={<IconPlus size={14} />} onClick={onAdd} disabled={disabled}>\n Add a rule\n </Button>\n {onAddLinked && (\n <Button size=\"compact-xs\" variant=\"subtle\" styles={quietButton} leftSection={<IconLink size={14} />} onClick={onAddLinked} disabled={disabled}>\n {LINKED_ADD_LABEL}\n </Button>\n )}\n </Group>\n </Stack>\n </Paper>\n );\n};\n\nfunction unique(problems: RubricProblem[]): string[] {\n return [...new Set(problems.map(problemText))];\n}\n","import React, { useMemo, useState } from 'react';\nimport { ActionIcon, Alert, Box, Button, Divider, Group, Modal, Paper, ScrollArea, Stack, Text } from '@mantine/core';\nimport { IconAlertTriangle, IconPlus, IconRobot, IconTrash, IconWand, IconWorld, IconX } from '@tabler/icons-react';\nimport type { RubricBody, RubricField, RubricFieldCatalog } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { operatorsForKind, validateRubric } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport BasePrimaryButton from '@/mantine/components/Base/BasePrimaryButton';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { actionAlertStyles } from '../../alertStyles';\nimport { AiCheckInline } from './AiCheckInline';\nimport { ConditionRow } from './ConditionRow';\nimport { ExternalCheckInline } from './ExternalCheckInline';\nimport { ReviewTaskEditor } from './ReviewTaskEditor';\nimport {\n AI_CHECK_LANE_LABEL,\n CONSEQUENCES,\n consequenceIcon,\n describeRule,\n fieldTitle,\n GROUP_AI_MEMBER_LEAD,\n GROW_RULE_LABEL,\n GROWN_CHECKS_LABEL,\n problemText,\n SCORE_MESSAGE_LABEL,\n} from './phrases';\nimport { chipButton, chipInput, chipInputStyles, HAIRLINE, leadWordStyle, microLabelStyle, panelStyle, quietButton, RuleSentence } from './rubricStyles';\nimport {\n addGrownMember,\n applyDraft,\n autoAiName,\n autoExtName,\n draftFromRule,\n growDraft,\n newDraft,\n removeGrownMember,\n upsertAiCheck,\n upsertExtSource,\n withAiSubject,\n withExtSubject,\n type AiCheckDraft,\n type ExtCheckDraft,\n type RuleDraft,\n} from './ruleDraft';\nimport { listRules, removeRule, ruleForDiagnosticPath, targetableFields, type Consequence, type FieldIndex, type SimpleRule, type UiRule } from './ruleModel';\nimport { templatesForField } from './templates';\n\n/**\n * Writing one rule — rubric-spec §B.5, \"Adding a rule\".\n *\n * Adding shows the one-tap templates FIRST (they cover ~90% of real rules);\n * \"Custom rule\" opens the sentence builder behind them. Editing goes straight\n * to the sentence.\n *\n * An external check (§A.14) is a KIND OF RULE ON A QUESTION, authored right\n * here: the subject picker offers \"an outside service checks this answer\",\n * which reveals the inline check (endpoint, answer type, Test) in the sentence\n * flow. The source's name and `send` payload are generated from the question —\n * the author never manages sources anywhere else.\n *\n * A ⛔ rule can also GROW (owner 2026-08-03): \"Add another check to this rule\"\n * turns the one sentence into a checks box — each member the same sentence row\n * (or the inline AI lane). Several checks in one rule always mean ALL of them\n * (proposal v3 retired the per-rule knob; any/at-least live in the rulebook's\n * approval policy instead). With one check nothing changes at all — the rule\n * edits and compiles exactly as it always did; with two or more it compiles to\n * ONE gate whose `when` is `{all: […]}`. Removing checks down to one collapses\n * back to the plain editor. 👤 rules never grow, and there is no separate\n * \"group\" concept anywhere.\n *\n * Three things make a broken rule hard to write here:\n * - the answer box only offers questions that exist on the form,\n * - the check box only offers operators the core says are legal for that\n * answer's kind (`operatorsForKind`),\n * - the rule is validated AS THE DRAFT IT WOULD BECOME — the draft is applied\n * to a throwaway copy of the document and run through `validateRubric`, so\n * the preview sentence and the problem list are literally what saving\n * produces, not a second opinion about it.\n */\n\ninterface RuleEditorProps {\n opened: boolean;\n onClose: () => void;\n /** The document as it stands — the draft is applied to a copy of it for preview. */\n body: RubricBody;\n catalog: RubricFieldCatalog;\n index: FieldIndex;\n /** The card this rule lives on. */\n field: RubricField;\n /** The rule being changed; omitted when adding a new one. */\n editing?: UiRule;\n onSave: (draft: RuleDraft) => void;\n}\n\n/** The subject picker's \"an outside service checks this answer\" entry — a mode, not a path. */\nconst EXT_SUBJECT = '__external-check__';\n/** The check box's \"🤖 AI checks it\" entry (§A.15) — a mode too, entered from the check dropdown. */\nconst AI_CHECK = '__ai-check__';\n\nexport const RuleEditor: React.FC<RuleEditorProps> = ({ opened, onClose, body, catalog, index, field, editing, onSave }) => {\n const [draft, setDraft] = useState<RuleDraft>(() => (editing ? draftFromRule(editing, body) : newDraft(body, field.path)));\n const [showTemplates, setShowTemplates] = useState(!editing);\n\n const ext = draft.ext;\n const ai = draft.ai;\n const grown = draft.grown;\n // The document as the draft sees it: the in-progress checks upserted (the\n // single lane's, and every grown AI member's), so `ext.<name>.*`/`ai.<name>.*`\n // resolves in every picker and preview BEFORE Save persists them.\n const draftBody = useMemo(() => {\n const withLane = ext ? upsertExtSource(body, ext) : ai ? upsertAiCheck(body, ai) : body;\n return grown ? grown.members.reduce((acc, member) => (member.kind === 'ai' ? upsertAiCheck(acc, member.ai) : acc), withLane) : withLane;\n }, [body, ext, ai, grown]);\n\n // Everything this rule may be about: the question, each answer inside it (for\n // a table or a group) — and the outside-service lane (§A.14). The AI lane\n // (§A.15) is entered from the CHECK dropdown instead, so it only surfaces\n // here as the current subject while it is active.\n const fieldOptions = useMemo(() => targetableFields(field).map((entry) => ({ value: entry.path, label: entry.title })), [field]);\n const subjectOptions = useMemo(\n () => [\n ...fieldOptions,\n { value: EXT_SUBJECT, label: 'An outside service checks this answer' },\n ...(ai ? [{ value: AI_CHECK, label: `The AI checks “${index.get(ai.sendField)?.title ?? field.title}”` }] : []),\n ],\n [fieldOptions, ai, index, field.title]\n );\n const showOptions = useMemo(() => [...index.values()].map((entry) => ({ value: entry.path, label: entry.title })), [index]);\n const templates = useMemo(() => templatesForField(field, body), [field, body]);\n // A machine's answer has no evidence for a person to look at, so neither the\n // ext nor the ai lane can ask one — both are ⛔ gates on the fixed \"the check\n // must confirm\" condition.\n //\n // An ai rule has no choice at all: the AI answers yes/no (§A.15\n // `expect: 'boolean'`) and that verdict decides the claim, so it is always a\n // ⛔ gate and the \"Then…\" picker is not rendered for it. What DOES vary is the\n // gate's ending (`onFail`) — reject outright, or hold the claim for a person —\n // and that picker takes its place inside the ⛔ panel.\n const consequences = useMemo(() => (ai || ext ? CONSEQUENCES.filter((entry) => entry.value === 'reject') : CONSEQUENCES), [ext, ai]);\n\n // The rule exactly as it would be saved: same sentence, same problems.\n // The rule being edited is lifted out first — otherwise the draft and its own\n // original would sit in the document together and report a clash with itself.\n const preview = useMemo(() => {\n const applied = applyDraft(\n editing ? removeRule(body, editing) : body,\n { ...draft, at: undefined },\n undefined,\n index.get(draft.ext?.sendField ?? draft.ai?.sendField ?? draft.field)?.title\n );\n const rule = listRules(applied).find((entry) => entry.code === draft.code);\n const problems = validateRubric(applied, catalog)\n .filter((diagnostic) => diagnostic.severity === 'error' && ruleForDiagnosticPath(applied, diagnostic.path)?.code === draft.code)\n .map(problemText);\n return { sentence: rule ? describeRule(rule, { fields: index, aiChecks: applied.aiChecks }) : '', problems: [...new Set(problems)] };\n }, [body, catalog, draft, editing, index]);\n\n const pickTemplate = (next: RuleDraft) => {\n setDraft({ ...next, at: draft.at, code: draft.code });\n setShowTemplates(false);\n };\n\n /** Change what the rule is about: another answer, the outside-service lane, or (while active) the AI lane. */\n const pickSubject = (path: string | null) => {\n if (!path || path === AI_CHECK || path.startsWith('~')) return;\n if (path === EXT_SUBJECT) {\n setDraft((current) => {\n if (current.ext) return current;\n const sendField = current.field.startsWith('$') ? current.field : field.path;\n return withExtSubject({ ...current, ai: undefined }, { name: autoExtName(sendField, body.sources), endpoint: '', audience: '', expect: 'boolean', sendField });\n });\n return;\n }\n setDraft((current) => {\n const legal = operatorsForKind(index.get(path)?.kind ?? 'text');\n const keepWhen = !current.ext && !current.ai && legal.includes(current.reject.when.op);\n return {\n ...current,\n ext: undefined,\n ai: undefined,\n field: path,\n reject: { ...current.reject, when: keepWhen ? { ...current.reject.when, field: path } : { field: path, op: legal[0] } },\n human: { ...current.human, show: current.human.show.includes(path) ? current.human.show : [path] },\n };\n });\n };\n\n /** The check dropdown picked \"🤖 AI checks it\" — enter the AI lane on the answer the sentence names (§A.15). */\n const enterAiCheck = () => {\n setDraft((current) => {\n if (current.ai) return current;\n const sendField = current.field.startsWith('$') ? current.field : field.path;\n return withAiSubject(current, { name: autoAiName(sendField, body.aiChecks), instructions: [''], sendField });\n });\n };\n\n /** The inline check changed — re-point the draft at its answer (`withExtSubject` keeps untouched work). */\n const setExt = (next: ExtCheckDraft) => setDraft((current) => withExtSubject(current, next));\n\n /** The inline AI rules changed — same contract as `setExt`. */\n const setAi = (next: AiCheckDraft) => setDraft((current) => withAiSubject(current, next));\n\n const setRejectRule = (rule: SimpleRule) => {\n // The sentence's answer box carries the outside-service lane too (§A.14).\n if (rule.field === EXT_SUBJECT) {\n pickSubject(EXT_SUBJECT);\n return;\n }\n setDraft((current) => ({ ...current, field: rule.field, reject: { ...current.reject, when: rule } }));\n };\n\n const setConsequence = (consequence: Consequence) =>\n setDraft((current) => {\n if (consequence !== 'reject') return { ...current, consequence };\n // A score check's when is its hold gate — the bands editor owns it, never this reset.\n if (current.ext?.expect === 'score') return { ...current, consequence };\n // An ext/ai reject is the one fixed check: the machine must confirm (§A.14/§A.15).\n if (current.ext || current.ai) return { ...current, consequence, reject: { ...current.reject, when: { field: current.field, op: 'isTrue' } } };\n // Coming back to ⛔: the sentence must still be a legal check for the answer.\n const legal = operatorsForKind(index.get(current.field)?.kind ?? 'text');\n const when = legal.includes(current.reject.when.op) ? current.reject.when : { field: current.field, op: legal[0] };\n return { ...current, consequence, reject: { ...current.reject, when } };\n });\n\n /** ⛔ has two endings (§A.6 `onFail`): turn the claim down, or hold it for a person to look at. */\n const setOnFail = (onFail: 'reject' | 'review') => setDraft((current) => ({ ...current, reject: { ...current.reject, onFail } }));\n\n // ── The rule GROWS (owner 2026-08-03) — the checks box's handlers. ─────────\n /** The quiet affordance: the current check becomes member one, the mildest second check joins it, knob \"All of them\". */\n const grow = () => setDraft((current) => growDraft(current, field.path));\n const addCheck = () => setDraft((current) => addGrownMember(current, field.path));\n /** Removing down to ONE collapses back into the plain single-check editor. */\n const removeCheck = (at: number) => setDraft((current) => removeGrownMember(current, at));\n const setMemberRule = (at: number, rule: SimpleRule) =>\n setDraft((current) =>\n current.grown\n ? { ...current, grown: { ...current.grown, members: current.grown.members.map((member, i) => (i === at ? { kind: 'check' as const, rule } : member)) } }\n : current\n );\n const setMemberAi = (at: number, memberAi: AiCheckDraft) =>\n setDraft((current) =>\n current.grown\n ? { ...current, grown: { ...current.grown, members: current.grown.members.map((member, i) => (i === at ? { kind: 'ai' as const, ai: memberAi } : member)) } }\n : current\n );\n /** The member's check dropdown picked \"🤖 AI checks it\" — that member becomes the AI lane on the answer its sentence named. */\n const toAiMember = (at: number) =>\n setDraft((current) => {\n const state = current.grown;\n const member = state?.members[at];\n if (!state || !member || member.kind === 'ai') return current;\n const sendField = member.rule.field.startsWith('$') ? member.rule.field : field.path;\n // Names must be free of the document's checks AND the other in-draft AI members'.\n const taken = state.members.flatMap((entry) => (entry.kind === 'ai' ? [entry.ai.name] : []));\n const memberAi: AiCheckDraft = { name: autoAiName(sendField, body.aiChecks, taken), instructions: [''], sendField };\n return { ...current, grown: { ...state, members: state.members.map((entry, i) => (i === at ? { kind: 'ai' as const, ai: memberAi } : entry)) } };\n });\n /** A hand-authored member may read something no picker offers (an ext/ai answer) — keep it selectable rather than blank. */\n const memberOptionsFor = (rule: SimpleRule) =>\n showOptions.some((option) => option.value === rule.field) ? showOptions : [...showOptions, { value: rule.field, label: fieldTitle(rule.field, { fields: index }) }];\n\n // A score check's endings are its bands (§A.14 score): the ⛔ panel shows the\n // rejection message only while a reject band exists, and the reject-or-review\n // picker never shows — the bands editor owns that choice.\n const scoreExt = ext?.expect === 'score';\n const scoreFloorOn = scoreExt && (ext?.bands?.rejectBelow ?? 0) > 0;\n // The ending picker shows for an ai rule (which has no other consequence to\n // choose), for a GROWN rule (same — it is always ⛔), and for ANY rule already\n // set to hold for review — otherwise a rule loaded that way, or one that left\n // the AI lane still holding, would be stuck on an ending with no control to\n // change it back.\n const holdsForReview = draft.reject.onFail === 'review';\n const showOnFail = draft.consequence === 'reject' && !scoreExt && (!!ai || !!grown || holdsForReview);\n // A held claim is never turned down, so nobody reads a rejection message —\n // the ⛔ panel drops the field, and Save stops waiting for it. A score check\n // needs one exactly when its reject band exists (the floor gate's wording).\n const needsMessage = draft.consequence === 'reject' && (scoreExt ? scoreFloorOn : !holdsForReview);\n const missingMessage = needsMessage && !draft.reject.reason.trim();\n // A half-declared check must not save: its endpoint and audience are what the\n // engine calls and addresses — without them the rule could never be answered.\n const extIncomplete = !!ext && !(/^https?:\\/\\//.test(ext.endpoint) && /^did:web:/.test(ext.audience));\n // …and an AI asked to check nothing could never answer either (§A.15) — the\n // single lane's, or any grown AI member's.\n const aiIncomplete =\n (!!ai && ai.instructions.every((rule) => !rule.trim())) || !!grown?.members.some((member) => member.kind === 'ai' && member.ai.instructions.every((rule) => !rule.trim()));\n const canSave = preview.problems.length === 0 && !missingMessage && !extIncomplete && !aiIncomplete;\n\n return (\n <Modal\n opened={opened}\n onClose={onClose}\n title={editing ? 'Change this rule' : `Add a rule to “${field.title}”`}\n size=\"xl\"\n radius={14}\n styles={{ title: { fontWeight: 600 } }}\n // A tall sentence builder must never outrun a short window: cap the body at\n // the viewport and scroll it internally, so the header and the action\n // buttons at the bottom stay reachable without zooming the browser out.\n scrollAreaComponent={ScrollArea.Autosize}\n >\n {showTemplates ? (\n <Stack gap=\"sm\">\n <Text size=\"sm\" c=\"dimmed\">\n Pick one — you can change it afterwards.\n </Text>\n {templates.map((template) => (\n <Button key={template.id} variant=\"default\" justify=\"flex-start\" size=\"md\" styles={chipButton} onClick={() => pickTemplate(template.draft)}>\n {template.label}\n </Button>\n ))}\n {templates.length === 0 && (\n <Text size=\"sm\" c=\"dimmed\">\n There are no quick rules for this kind of answer — build your own below.\n </Text>\n )}\n <Divider label=\"or\" labelPosition=\"center\" color={HAIRLINE} />\n <Button variant=\"subtle\" styles={quietButton} leftSection={<IconWand size={16} />} onClick={() => setShowTemplates(false)}>\n Custom rule\n </Button>\n </Stack>\n ) : (\n <Stack gap=\"md\">\n {grown ? (\n /* The checks box (owner 2026-08-03, v3): every check a sentence row\n (or the inline AI lane). ALL of them must pass — no knob; any/\n at-least belong to the rulebook's approval policy. Compiles to\n ONE gate whose `when` is `{all: […]}`. */\n <Paper p=\"md\" style={panelStyle}>\n <Stack gap={8}>\n <Text style={microLabelStyle}>{GROWN_CHECKS_LABEL}</Text>\n {grown.members.map((member, at) => (\n <Group key={`${at}-${grown.members.length}`} gap=\"xs\" align=\"flex-start\" wrap=\"nowrap\">\n <Box style={{ flex: 1 }}>\n {member.kind === 'check' ? (\n <ConditionRow\n index={index}\n options={memberOptionsFor(member.rule)}\n sources={draftBody.sources}\n aiChecks={draftBody.aiChecks}\n rule={member.rule}\n onChange={(next) => setMemberRule(at, next)}\n lead=\"\"\n extraOperators={[{ value: AI_CHECK, label: AI_CHECK_LANE_LABEL, Icon: IconRobot }]}\n onPickExtra={() => toAiMember(at)}\n />\n ) : (\n // The AI member: the question the AI looks at, then the\n // same inline instructions (+ \"what can the AI see\")\n // every AI lane has. No operator, no value — the check\n // IS the sentence.\n <Stack gap={8}>\n <Group gap={8} align=\"center\" wrap=\"wrap\">\n <Text style={leadWordStyle}>{GROUP_AI_MEMBER_LEAD}</Text>\n <BaseSelect\n w={230}\n styles={chipInput}\n data={showOptions}\n value={member.ai.sendField}\n onChange={(path) => path && setMemberAi(at, { ...member.ai, sendField: path })}\n searchable={showOptions.length > 6}\n />\n </Group>\n <AiCheckInline\n ai={member.ai}\n questionTitle={fieldTitle(member.ai.sendField, { fields: index })}\n index={index}\n onChange={(next) => setMemberAi(at, next)}\n />\n </Stack>\n )}\n </Box>\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => removeCheck(at)} aria-label=\"Remove this check\">\n <IconTrash size={16} />\n </ActionIcon>\n </Group>\n ))}\n <Button variant=\"subtle\" size=\"compact-sm\" styles={quietButton} style={{ alignSelf: 'flex-start' }} leftSection={<IconPlus size={14} />} onClick={addCheck}>\n {GROW_RULE_LABEL}\n </Button>\n </Stack>\n </Paper>\n ) : draft.consequence === 'reject' && !ext && !ai ? (\n <ConditionRow\n index={index}\n options={subjectOptions}\n rule={draft.reject.when}\n onChange={setRejectRule}\n lead=\"If\"\n extraOperators={[{ value: AI_CHECK, label: AI_CHECK_LANE_LABEL, Icon: IconRobot }]}\n onPickExtra={enterAiCheck}\n />\n ) : (\n <BaseSelect\n label=\"Which answer is this rule about?\"\n w={300}\n styles={chipInput}\n data={subjectOptions}\n value={ext ? EXT_SUBJECT : ai ? AI_CHECK : draft.field}\n onChange={pickSubject}\n searchable={subjectOptions.length > 6}\n renderOption={({ option }) => {\n const OptionIcon = option.value === AI_CHECK ? IconRobot : option.value === EXT_SUBJECT ? IconWorld : undefined;\n return (\n <Group gap={8} wrap=\"nowrap\">\n {OptionIcon && icon(OptionIcon, 16)}\n <Text size=\"sm\">{option.label}</Text>\n </Group>\n );\n }}\n />\n )}\n\n {/* The inline check (§A.14): endpoint → auto-detected identity → answer\n type → Test, right in the sentence flow. Committed with the rule. */}\n {ext && <ExternalCheckInline ext={ext} questionTitle={index.get(ext.sendField)?.title ?? field.title} onChange={setExt} />}\n\n {/* The inline AI check (§A.15): the rules the AI holds the answer to,\n right in the sentence flow. Committed with the rule, like ext.\n `index` switches on the \"what can the AI see\" picker — extra\n answers sent alongside the checked one. */}\n {ai && <AiCheckInline ai={ai} questionTitle={index.get(ai.sendField)?.title ?? field.title} index={index} onChange={setAi} />}\n\n {/* An ai rule skips this entirely — it is always ⛔, and the choice it\n does have (reject or hold for a person) lives in the panel below.\n A GROWN rule skips it too: only ⛔ rules grow, so there is no\n consequence to pick. */}\n {!ai && !grown && (\n <Stack gap={6}>\n <Text style={leadWordStyle}>Then…</Text>\n <Group gap=\"sm\" align=\"stretch\" grow>\n {consequences.map((consequence) => (\n <ConsequenceCard\n key={consequence.value}\n active={draft.consequence === consequence.value}\n tint={consequence.color}\n iconNode={consequenceIcon(consequence.value, 22)}\n title={consequence.label}\n description={consequence.hint}\n onClick={() => setConsequence(consequence.value)}\n />\n ))}\n </Group>\n </Stack>\n )}\n\n <Paper p=\"md\" style={panelStyle}>\n {draft.consequence === 'reject' && (\n <Stack gap=\"xs\">\n {ext && !scoreExt && (\n <Text size=\"xs\" c=\"dimmed\">\n The outside service must confirm this answer — when it doesn’t, the claim is rejected with your message.\n </Text>\n )}\n {scoreExt && (\n <Text size=\"xs\" c=\"dimmed\">\n {scoreFloorOn\n ? 'The bands above decide: too low is turned down with your message, the middle waits for a person, high enough passes.'\n : 'The bands above decide: below the passing score the claim waits for a person — nothing is turned down automatically.'}\n </Text>\n )}\n {ai && (\n <Text size=\"xs\" c=\"dimmed\">\n The AI reads this answer against your rules and gives a yes or a no. When it says no…\n </Text>\n )}\n {showOnFail && (\n <Group gap=\"sm\" align=\"stretch\" grow>\n <ConsequenceCard\n active={!holdsForReview}\n tint=\"var(--mantine-color-red-6)\"\n iconNode={consequenceIcon('reject', 22)}\n title=\"Reject the claim\"\n description=\"The claim is turned down straight away, with your message.\"\n onClick={() => setOnFail('reject')}\n />\n <ConsequenceCard\n active={holdsForReview}\n tint=\"var(--mantine-color-grape-6)\"\n iconNode={consequenceIcon('human', 22)}\n title=\"A person checks it\"\n description=\"The claim is held for a reviewer instead of being turned down.\"\n onClick={() => setOnFail('review')}\n />\n </Group>\n )}\n {/* Held claims are never turned down, so there is no message to write. */}\n {needsMessage && (\n <BaseTextInput\n label={scoreExt ? SCORE_MESSAGE_LABEL : 'What should the claimant be told?'}\n styles={chipInputStyles(missingMessage)}\n placeholder=\"e.g. Delivery date outside the collection period\"\n description=\"They will read this, so say plainly what went wrong.\"\n error={missingMessage ? 'Please write the message.' : undefined}\n value={draft.reject.reason}\n onChange={(event) => setDraft({ ...draft, reject: { ...draft.reject, reason: event.currentTarget.value } })}\n />\n )}\n </Stack>\n )}\n {draft.consequence === 'human' && (\n <ReviewTaskEditor fieldOptions={showOptions} draft={draft.human} onChange={(human) => setDraft((current) => ({ ...current, human }))} />\n )}\n </Paper>\n\n {/* \"Only check this if…\" (`appliesWhen`) — optional, collapsed until asked for. */}\n {draft.appliesWhen ? (\n <Paper p=\"sm\" style={panelStyle}>\n <Group gap=\"xs\" align=\"flex-start\" wrap=\"nowrap\">\n <Box style={{ flex: 1 }}>\n <ConditionRow\n index={index}\n options={showOptions}\n sources={draftBody.sources}\n aiChecks={draftBody.aiChecks}\n rule={draft.appliesWhen}\n onChange={(rule) => setDraft((current) => ({ ...current, appliesWhen: rule }))}\n lead=\"Only check this if\"\n />\n </Box>\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => setDraft((current) => ({ ...current, appliesWhen: undefined }))} aria-label=\"Always check this rule\">\n <IconX size={16} />\n </ActionIcon>\n </Group>\n </Paper>\n ) : (\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n styles={quietButton}\n style={{ alignSelf: 'flex-start' }}\n leftSection={<IconPlus size={14} />}\n onClick={() => setDraft((current) => ({ ...current, appliesWhen: { field: field.path, op: 'present' } }))}\n >\n Only check this if…\n </Button>\n )}\n\n {/* The one quiet growth affordance (owner 2026-08-03): only a ⛔ rule\n grows — never 👤, never the ext lane (an outside service's answer\n has no member row to edit its endpoint in). */}\n {draft.consequence === 'reject' && !grown && !ext && (\n <Button variant=\"subtle\" size=\"compact-sm\" styles={quietButton} style={{ alignSelf: 'flex-start' }} leftSection={<IconPlus size={14} />} onClick={grow}>\n {GROW_RULE_LABEL}\n </Button>\n )}\n\n {preview.problems.length > 0 && (\n <Alert color=\"red\" icon={<IconAlertTriangle size={16} />} styles={actionAlertStyles}>\n <Stack gap={2}>\n {preview.problems.map((problem) => (\n <Text key={problem} size=\"xs\">\n {problem}\n </Text>\n ))}\n </Stack>\n </Alert>\n )}\n\n <Stack gap={6}>\n <Text style={microLabelStyle}>This rule reads:</Text>\n <RuleSentence text={preview.sentence} />\n </Stack>\n\n <Group justify=\"space-between\">\n {!editing ? (\n <Button variant=\"subtle\" styles={quietButton} onClick={() => setShowTemplates(true)}>\n Back to the quick rules\n </Button>\n ) : (\n <span />\n )}\n <Group gap=\"xs\">\n <Button variant=\"default\" onClick={onClose}>\n Cancel\n </Button>\n <BasePrimaryButton disabled={!canSave} onClick={() => onSave(draft)}>\n {editing ? 'Save the change' : 'Add this rule'}\n </BasePrimaryButton>\n </Group>\n </Group>\n </Stack>\n )}\n </Modal>\n );\n};\n\n/**\n * Ban / chart / person — the consequence is a picture, never a word like \"gate\"\n * (§B.5 rule 4). Selected state is the consequence's OWN colour as a soft tint\n * (red for reject, grape for a person) — a pill, never a solid fill. Exported\n * for the group editor's reject-or-review ending, which is the same choice.\n */\nexport const ConsequenceCard: React.FC<{ active: boolean; tint: string; iconNode: React.ReactNode; title: string; description: string; onClick: () => void }> = ({\n active,\n tint,\n iconNode,\n title,\n description,\n onClick,\n}) => (\n <Paper\n p=\"sm\"\n onClick={onClick}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick();\n }\n }}\n style={{\n flex: 1,\n cursor: 'pointer',\n borderRadius: 10,\n border: `1px solid ${active ? `color-mix(in srgb, ${tint} 55%, transparent)` : HAIRLINE}`,\n background: active ? `color-mix(in srgb, ${tint} 10%, transparent)` : undefined,\n transition: 'border-color 120ms ease, background 120ms ease',\n }}\n >\n <Stack gap={4}>\n <Group gap={6} align=\"center\" wrap=\"nowrap\">\n {iconNode}\n <Text fw={600} style={{ fontSize: 13.5, color: active ? tint : undefined }}>\n {title}\n </Text>\n </Group>\n <Text size=\"xs\" c=\"dimmed\">\n {description}\n </Text>\n </Stack>\n </Paper>\n);\n","import React from 'react';\nimport { ActionIcon, Button, Group, Paper, Stack, Text } from '@mantine/core';\nimport { IconPlus, IconRobot, IconX } from '@tabler/icons-react';\nimport BaseMultiSelect from '@/mantine/components/Base/BaseMultiSelect';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { AI_SEES_LABEL, AI_SEES_PLACEHOLDER, AI_SETTING_HINT, aiSeesHint } from './phrases';\nimport type { AiCheckDraft } from './ruleDraft';\nimport type { FieldIndex } from './ruleModel';\nimport { chipInput, panelStyle, quietButton } from './rubricStyles';\n\n/**\n * The inline AI check (§A.15) — the body of the \"🤖 AI checks it\" lane, right\n * in the rule-sentence flow (the `ExternalCheckInline` twin, minus the\n * plumbing: no endpoint, no audience — the engine's own AI is the service).\n * The author only writes the rules the answer is checked against, one short\n * line each; `name` and `send` are derived from the question. Everything lives\n * on the draft and persists through `applyDraft` → block inputs — no React\n * state at all.\n */\n\ninterface AiCheckInlineProps {\n ai: AiCheckDraft;\n /** The question's title, for the explainer. */\n questionTitle: string;\n onChange: (next: AiCheckDraft) => void;\n disabled?: boolean;\n /**\n * When given, the \"what can the AI see\" picker is offered: extra answers sent\n * alongside the checked one (`alsoSend`) — any kind, files included, since\n * the engine sends file answers as the attachments themselves.\n */\n index?: FieldIndex;\n}\n\nexport const AiCheckInline: React.FC<AiCheckInlineProps> = ({ ai, questionTitle, onChange, disabled, index }) => {\n const setRule = (at: number, text: string) => onChange({ ...ai, instructions: ai.instructions.map((rule, i) => (i === at ? text : rule)) });\n const removeRule = (at: number) => onChange({ ...ai, instructions: ai.instructions.filter((_, i) => i !== at) });\n const addRule = () => onChange({ ...ai, instructions: [...ai.instructions, ''] });\n\n return (\n <Paper p=\"md\" style={panelStyle}>\n <Stack gap=\"xs\">\n <Group gap={6} wrap=\"nowrap\">\n {icon(IconRobot, 16)}\n <Text size=\"sm\" fw={600}>\n What should the AI check?\n </Text>\n </Group>\n <Text size=\"xs\" c=\"dimmed\">\n While a claim is judged, the AI reads “{questionTitle}” and passes it only when every rule below holds.\n </Text>\n {/* AI checks are a per-collection paid opt-in on the Evaluation Engine block, and this\n panel cannot see that setting. With it off the check never runs and every claim reading\n it is held for review — so say it up front rather than at publish. The engine's\n pre-publish check (§C.7) is the hard stop; this is the hint that avoids reaching it. */}\n <Text size=\"xs\" c=\"dimmed\">\n {AI_SETTING_HINT}\n </Text>\n\n <Stack gap={6}>\n {ai.instructions.map((rule, at) => (\n // Index keys are safe here: rows are edited in place and only ever\n // removed by index — there is no identity to preserve across reorders.\n <Group key={at} gap=\"xs\" wrap=\"nowrap\">\n <BaseTextInput\n style={{ flex: 1 }}\n styles={chipInput}\n placeholder=\"e.g. Looks like a real batch code, not a placeholder\"\n value={rule}\n onChange={(event) => setRule(at, event.currentTarget.value)}\n disabled={disabled}\n />\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={() => removeRule(at)} disabled={disabled || ai.instructions.length <= 1} aria-label=\"Remove this rule\">\n <IconX size={16} />\n </ActionIcon>\n </Group>\n ))}\n <Button size=\"xs\" variant=\"subtle\" styles={quietButton} leftSection={<IconPlus size={14} />} onClick={addRule} disabled={disabled} style={{ alignSelf: 'flex-start' }}>\n Add a rule\n </Button>\n </Stack>\n\n {index && (\n <BaseMultiSelect\n label={AI_SEES_LABEL}\n styles={chipInput}\n placeholder={AI_SEES_PLACEHOLDER}\n description={aiSeesHint(questionTitle)}\n data={[...index.values()].filter((entry) => entry.path !== ai.sendField).map((entry) => ({ value: entry.path, label: entry.title }))}\n value={(ai.alsoSend ?? []).filter((path) => path !== ai.sendField)}\n onChange={(alsoSend) => onChange({ ...ai, alsoSend: alsoSend.length > 0 ? alsoSend : undefined })}\n searchable\n disabled={disabled}\n />\n )}\n </Stack>\n </Paper>\n );\n};\n","import React, { useMemo } from 'react';\nimport { Group, Text } from '@mantine/core';\nimport type { Icon as TablerIcon } from '@tabler/icons-react';\nimport { operatorsForKind } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport type { RubricAiCheck, RubricExternalSource, RubricOperator } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { OPERATOR_PHRASE } from './phrases';\nimport { aiRefField, extRefField, type FieldIndex, type SimpleRule } from './ruleModel';\nimport { chipInput, leadWordStyle } from './rubricStyles';\nimport { ValueInput } from './ValueInput';\n\n/**\n * The sentence itself — `If [answer] [check] [value]` (§B.5).\n *\n * Reused by every editor that needs a check: the reject rule, \"pass or fail\"\n * points, each level, each deduction, and \"only when…\". One row, one grammar,\n * one place where a check can go wrong.\n *\n * The check box is filled by the CORE's `operatorsForKind` (§A.4's legality\n * table) — never a hand-written list. That is what makes an illegal rule\n * unconstructible rather than merely diagnosed: the author cannot pick \">\" for\n * a photo, because it is not in the box.\n */\n\ninterface ConditionRowProps {\n index: FieldIndex;\n /** The answers this row may be about — the card's question and its inner answers (or an ext/ai subject's answer). */\n options: { value: string; label: string }[];\n /** Declared external checks (§A.14) — only for resolving an ext subject's kind; never a picker list of their own. */\n sources?: RubricExternalSource[];\n /** Declared AI checks (§A.15) — only for resolving an ai subject's kind, like `sources`. */\n aiChecks?: RubricAiCheck[];\n rule: SimpleRule;\n onChange: (next: SimpleRule) => void;\n /** Word in front of the sentence (\"If\", \"when\", \"take points off when\"). */\n lead?: string;\n /** Hide the answer box when the sentence already named it a line above. */\n showField?: boolean;\n disabled?: boolean;\n /**\n * Extra NON-operator entries for the check box — the \"AI checks it\" lane\n * (§A.15). Picking one calls `onPickExtra` instead of `onChange`: it is a\n * mode switch the parent owns, not an operator the rule can carry. `Icon`\n * (a Tabler icon, §B.5 rule 4 — pictures, not emoji) marks the entry apart\n * from the plain operators.\n */\n extraOperators?: { value: string; label: string; Icon?: TablerIcon }[];\n onPickExtra?: (value: string) => void;\n}\n\nexport const ConditionRow: React.FC<ConditionRowProps> = ({\n index,\n options,\n sources,\n aiChecks,\n rule,\n onChange,\n lead = 'If',\n showField = true,\n disabled,\n extraOperators,\n onPickExtra,\n}) => {\n // A rule may gate on a form answer OR on an external/AI check's answer\n // (§A.14/§A.15) — resolve the ref to a synthetic field so its kind types the\n // row too.\n const field = index.get(rule.field) ?? extRefField(rule.field, sources) ?? aiRefField(rule.field, aiChecks);\n const kind = field?.kind ?? 'text';\n\n const operatorOptions = useMemo(\n () => [\n ...operatorsForKind(kind).map((op) => {\n const phrase = OPERATOR_PHRASE[op];\n return { value: op, label: phrase.suffix ? `${phrase.label} … ${phrase.suffix}` : phrase.label };\n }),\n ...(extraOperators ?? []),\n ],\n [kind, extraOperators]\n );\n\n const pickField = (path: string | null) => {\n if (!path) return;\n const nextKind = (index.get(path) ?? extRefField(path, sources) ?? aiRefField(path, aiChecks))?.kind ?? 'text';\n const legal = operatorsForKind(nextKind);\n // Keep the check when it still makes sense for the new answer; otherwise the\n // sentence would read as nonsense until the author noticed.\n const op = legal.includes(rule.op) ? rule.op : legal[0];\n // The value (and `approx`'s tolerance, which the operator needs to be valid\n // at all) survives only while the check itself does.\n const kept = op === rule.op;\n onChange({ field: path, op, value: kept ? rule.value : undefined, tolerance: kept ? rule.tolerance : undefined });\n };\n\n const pickOperator = (op: string | null) => {\n if (!op) return;\n if (extraOperators?.some((entry) => entry.value === op)) {\n onPickExtra?.(op);\n return;\n }\n // A new check wants a new value: \"between 2 and 8\" cannot carry over to\n // \"must be one of\". Clearing beats leaving a value that no longer fits.\n onChange({ field: rule.field, op: op as RubricOperator, value: undefined, tolerance: undefined });\n };\n\n return (\n <Group gap={8} align=\"flex-start\" wrap=\"wrap\">\n <Text mt={6} style={leadWordStyle}>\n {lead}\n </Text>\n {showField && (\n <BaseSelect w={220} styles={chipInput} data={options} value={rule.field} onChange={pickField} disabled={disabled || options.length <= 1} searchable={options.length > 6} />\n )}\n <BaseSelect\n w={230}\n styles={chipInput}\n data={operatorOptions}\n value={rule.op}\n onChange={pickOperator}\n disabled={disabled}\n searchable={operatorOptions.length > 8}\n renderOption={({ option }) => {\n const Icon = extraOperators?.find((entry) => entry.value === option.value)?.Icon;\n return (\n <Group gap={8} wrap=\"nowrap\">\n {Icon && icon(Icon, 16)}\n <Text size=\"sm\">{option.label}</Text>\n </Group>\n );\n }}\n />\n <ValueInput\n op={rule.op}\n field={field}\n index={index}\n value={rule.value}\n tolerance={rule.tolerance}\n onChange={(patch) => onChange({ ...rule, ...patch })}\n disabled={disabled}\n />\n </Group>\n );\n};\n","import React, { useState } from 'react';\nimport { Alert, Box, Button, Code, Divider, Group, Loader, Paper, SegmentedControl, Stack, Text } from '@mantine/core';\nimport { IconAlertTriangle, IconCheck, IconWorld } from '@tabler/icons-react';\nimport type { SourcePreviewResult } from '@/core/lib/actionRegistry/types';\nimport BaseNumberInput from '@/mantine/components/Base/BaseNumberInput';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { useBlocknoteHandlers } from '@/mantine/context/BlocknoteContext';\nimport { EXT_ANSWER_TYPE_LABEL, EXT_ANSWERS_BOOLEAN_LABEL, EXT_ANSWERS_SCORE_LABEL } from './phrases';\nimport { clampBands, extSourceFromDraft, SCORE_BANDS_DEFAULT, type ExtCheckDraft } from './ruleDraft';\nimport { chipButton, chipInput, HAIRLINE, microLabelStyle, panelStyle, quietButton, segmentedPill } from './rubricStyles';\n\n/**\n * The inline external check (§A.14) — the body of the \"an outside service\n * checks this answer\" subject, right in the rule-sentence flow. The author\n * gives a web address and the answer type; everything machine-facing is\n * derived (`name` from the question, `send` as the one auto pair, `audience`\n * detected from the endpoint), so there is nothing to manage and no way to\n * type an invalid token. The draft persists through the rule editor's draft →\n * `applyDraft` → block inputs; ONLY the transient scratch here (a sample value,\n * a test result, the detection status) is React state.\n *\n * The answer type is the author's choice (§A.14.3): a yes/no, or a score out\n * of 100. A score reveals the bands — the two numbers that make three zones\n * (reject below / a person decides / passes) — right here in the check panel,\n * so what the service answers and what the answer does sit together.\n */\n\ninterface ExternalCheckInlineProps {\n ext: ExtCheckDraft;\n /** The question's title, for the explainer and the sample-value box. */\n questionTitle: string;\n onChange: (next: ExtCheckDraft) => void;\n disabled?: boolean;\n}\n\nexport const ExternalCheckInline: React.FC<ExternalCheckInlineProps> = ({ ext, questionTitle, onChange, disabled }) => {\n const handlers = useBlocknoteHandlers();\n const canTest = typeof handlers.testExternalSource === 'function';\n\n // Test scratch + detection status — genuinely ephemeral UI, like any\n // in-progress input. The check itself (endpoint, audience, expect) lives on\n // the draft and persists via onChange.\n const [sample, setSample] = useState('');\n const [result, setResult] = useState<SourcePreviewResult | null>(null);\n const [testing, setTesting] = useState(false);\n const [detecting, setDetecting] = useState(false);\n const [detectError, setDetectError] = useState<string | null>(null);\n // Reveal a manual `did:web:` box only when auto-detection can't do it — the\n // format still REQUIRES an audience, so the author can always fill it by hand.\n const [manual, setManual] = useState(false);\n\n const detect = async (endpoint: string) => {\n if (!endpoint.trim()) return;\n if (typeof handlers.resolveSourceDid !== 'function') {\n setManual(true);\n setDetectError('Couldn’t detect who this service is automatically — enter its did:web address.');\n return;\n }\n setDetecting(true);\n setDetectError(null);\n try {\n const outcome = await handlers.resolveSourceDid({ endpoint: endpoint.trim() });\n if (outcome.resolved && outcome.did) {\n onChange({ ...ext, audience: outcome.did });\n setManual(false);\n } else {\n setDetectError(outcome.error || 'Couldn’t detect who this service is — enter its did:web address.');\n setManual(true);\n }\n } catch (error) {\n setDetectError(error instanceof Error ? error.message : String(error));\n setManual(true);\n } finally {\n setDetecting(false);\n }\n };\n\n const runTest = async () => {\n if (!handlers.testExternalSource) return;\n const source = extSourceFromDraft(ext);\n setTesting(true);\n setResult(null);\n try {\n setResult(await handlers.testExternalSource({ source, sampleValues: { [Object.keys(source.send)[0]]: sample } }));\n } catch (error) {\n setResult({\n ok: false,\n reachable: false,\n httpStatus: null,\n contractOk: false,\n expect: ext.expect,\n value: null,\n reason: null,\n error: readableError(error),\n sent: {},\n audience: ext.audience,\n elapsedMs: 0,\n });\n } finally {\n setTesting(false);\n }\n };\n\n const ready = /^https?:\\/\\//.test(ext.endpoint) && /^did:web:/.test(ext.audience);\n\n return (\n <Paper p=\"md\" style={panelStyle}>\n <Stack gap=\"xs\">\n <Group gap={6} wrap=\"nowrap\">\n {icon(IconWorld, 16)}\n <Text size=\"sm\" fw={600}>\n The outside service\n </Text>\n </Group>\n <Text size=\"xs\" c=\"dimmed\">\n While a claim is judged, the engine sends “{questionTitle}” to this service and uses its answer in the rule.\n </Text>\n\n <Stack gap={4}>\n <BaseTextInput\n label=\"Web address\"\n styles={chipInput}\n placeholder=\"https://…\"\n value={ext.endpoint}\n onChange={(event) => onChange({ ...ext, endpoint: event.currentTarget.value })}\n onBlur={(event) => detect(event.currentTarget.value)}\n disabled={disabled}\n />\n {detecting && (\n <Group gap={6} wrap=\"nowrap\">\n <Loader size={12} />\n <Text size=\"xs\" c=\"dimmed\">\n Finding who this service is…\n </Text>\n </Group>\n )}\n {!detecting && ext.audience && !manual && (\n <Group gap={6} wrap=\"nowrap\">\n {icon(IconCheck, 14, 'var(--mantine-color-green-6)')}\n <Text size=\"xs\" c=\"dimmed\" style={{ wordBreak: 'break-all' }}>\n detected {ext.audience}\n </Text>\n <Button size=\"compact-xs\" variant=\"subtle\" styles={quietButton} onClick={() => setManual(true)} disabled={disabled}>\n change\n </Button>\n </Group>\n )}\n {!detecting && (manual || detectError) && (\n <Stack gap={2}>\n {detectError && (\n <Text size=\"xs\" c=\"red\">\n {detectError}\n </Text>\n )}\n <BaseTextInput\n label=\"Who it is (did:web)\"\n styles={chipInput}\n placeholder=\"did:web:example.com\"\n value={ext.audience}\n onChange={(event) => onChange({ ...ext, audience: event.currentTarget.value })}\n disabled={disabled}\n />\n </Stack>\n )}\n </Stack>\n\n {/* The answer type (§A.14.3) — flipping to a score seeds the default bands. */}\n <Divider label={EXT_ANSWER_TYPE_LABEL} labelPosition=\"left\" color={HAIRLINE} styles={{ label: microLabelStyle }} />\n <SegmentedControl\n styles={segmentedPill}\n value={ext.expect}\n onChange={(expect) => onChange(expect === 'score' ? { ...ext, expect: 'score', bands: ext.bands ?? { ...SCORE_BANDS_DEFAULT } } : { ...ext, expect: 'boolean' })}\n disabled={disabled}\n data={[\n { value: 'boolean', label: EXT_ANSWERS_BOOLEAN_LABEL },\n { value: 'score', label: EXT_ANSWERS_SCORE_LABEL },\n ]}\n style={{ alignSelf: 'flex-start' }}\n />\n\n {ext.expect === 'score' && <ScoreBandsEditor ext={ext} onChange={onChange} disabled={disabled} />}\n\n <Divider label=\"Try it\" labelPosition=\"left\" color={HAIRLINE} styles={{ label: microLabelStyle }} />\n <Group gap=\"xs\" align=\"flex-end\" wrap=\"wrap\">\n <BaseTextInput\n w={260}\n styles={chipInput}\n label={`Sample ${questionTitle}`}\n placeholder=\"a value to try\"\n value={sample}\n onChange={(event) => setSample(event.currentTarget.value)}\n disabled={disabled}\n />\n <Button\n size=\"xs\"\n variant=\"light\"\n styles={chipButton}\n leftSection={testing ? <Loader size={12} /> : icon(IconWorld, 14)}\n onClick={runTest}\n disabled={disabled || !canTest || !ready || testing}\n >\n Test this check\n </Button>\n {!canTest ? (\n <Text size=\"xs\" c=\"dimmed\">\n Testing isn’t available here.\n </Text>\n ) : (\n !ready && (\n <Text size=\"xs\" c=\"dimmed\">\n Enter the web address first.\n </Text>\n )\n )}\n </Group>\n\n {result && <TestResult result={result} ext={ext} />}\n </Stack>\n </Paper>\n );\n};\n\n/**\n * The bands (§A.14 score): two numbers, three zones, one bar. The author's\n * scale is 0–100 (the ×100 to basis points happens at compile); `clampBands`\n * keeps `0 ≤ reject-below < passes-at ≤ 100` whatever is typed.\n */\nconst ScoreBandsEditor: React.FC<{ ext: ExtCheckDraft; onChange: (next: ExtCheckDraft) => void; disabled?: boolean }> = ({ ext, onChange, disabled }) => {\n const bands = clampBands(ext.bands ?? SCORE_BANDS_DEFAULT);\n const commit = (next: { rejectBelow: number; approveAt: number }) => onChange({ ...ext, bands: clampBands(next) });\n const zone = (background: string, width: number, label: string) => (\n <Box\n style={{\n width: `${width}%`,\n background,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 10,\n fontWeight: 700,\n color: 'var(--mantine-color-white)',\n opacity: 0.85,\n }}\n >\n {width >= 14 ? label : ''}\n </Box>\n );\n return (\n <Stack gap={8}>\n <Group gap={8} align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\">Below</Text>\n <BaseNumberInput\n w={72}\n styles={chipInput}\n min={0}\n max={99}\n allowDecimal={false}\n value={bands.rejectBelow}\n onChange={(next) => commit({ ...bands, rejectBelow: typeof next === 'number' ? next : 0 })}\n disabled={disabled}\n aria-label=\"Reject below this score\"\n />\n <Text size=\"sm\">the claim is turned down · at</Text>\n <BaseNumberInput\n w={72}\n styles={chipInput}\n min={1}\n max={100}\n allowDecimal={false}\n value={bands.approveAt}\n onChange={(next) => commit({ ...bands, approveAt: typeof next === 'number' ? next : 100 })}\n disabled={disabled}\n aria-label=\"Passes at this score\"\n />\n <Text size=\"sm\">or more it passes</Text>\n </Group>\n <Box style={{ display: 'flex', height: 22, borderRadius: 6, overflow: 'hidden', border: `1px solid ${HAIRLINE}` }} aria-hidden>\n {zone('var(--mantine-color-red-8)', bands.rejectBelow, 'turned down')}\n {zone('var(--mantine-color-yellow-8)', bands.approveAt - bands.rejectBelow, 'a person decides')}\n {zone('var(--mantine-color-green-8)', 100 - bands.approveAt, 'passes')}\n </Box>\n <Text size=\"xs\" c=\"dimmed\">\n In between — from {bands.rejectBelow} to {bands.approveAt - 1} — the claim waits for a person to decide.\n </Text>\n </Stack>\n );\n};\n\n/** The outcome of a live test — a yes/no, or a score placed in its band — with what actually went over the wire. */\nconst TestResult: React.FC<{ result: SourcePreviewResult; ext: ExtCheckDraft }> = ({ result, ext }) => {\n const title = (() => {\n if (!result.ok) return 'Did not pass';\n if (result.expect === 'score' && typeof result.value === 'number') {\n // The engine answers in basis points; the author reads /100 (§A.14.3).\n const score = Math.round(result.value / 100);\n const bands = clampBands(ext.bands ?? SCORE_BANDS_DEFAULT);\n const outcome = score >= bands.approveAt ? 'it would pass' : score >= bands.rejectBelow ? 'a person would decide' : 'the claim would be turned down';\n return `Scored ${score} / 100 — ${outcome}`;\n }\n return `Passed — ${result.value ? 'yes' : 'no'}`;\n })();\n return (\n <Alert color={result.ok ? 'green' : 'red'} icon={result.ok ? <IconCheck size={16} /> : <IconAlertTriangle size={16} />} title={title}>\n <Stack gap={4}>\n {!result.ok && (\n <Text size=\"xs\">{[result.error, result.httpStatus != null ? `HTTP ${result.httpStatus}` : null].filter(Boolean).join(' · ') || 'The check could not be completed.'}</Text>\n )}\n {result.reason && (\n <Text size=\"xs\" c=\"dimmed\">\n {result.reason}\n </Text>\n )}\n <Text size=\"xs\" c=\"dimmed\">\n Sent: <Code style={{ fontSize: 11 }}>{JSON.stringify(result.sent)}</Code>\n </Text>\n </Stack>\n </Alert>\n );\n};\n\n/** The `{ error: { message, details } }` AppError envelope, in plain words — never a raw \"status 400\". */\nfunction readableError(error: unknown): string {\n return appErrorMessage(error) ?? (error instanceof Error ? error.message : String(error));\n}\n\nfunction appErrorMessage(error: unknown): string | null {\n if (!error || typeof error !== 'object') return null;\n const source = error as { response?: { data?: unknown }; data?: unknown; error?: unknown };\n for (const candidate of [source.response?.data, source.data, source]) {\n const envelope = candidate && typeof candidate === 'object' ? (candidate as { error?: unknown }).error : undefined;\n if (envelope && typeof envelope === 'object' && typeof (envelope as { message?: unknown }).message === 'string') {\n const { message, details } = envelope as { message: string; details?: unknown };\n const detail =\n typeof details === 'string'\n ? details\n : Array.isArray(details)\n ? details.map((d) => (typeof d === 'string' ? d : JSON.stringify(d))).join('; ')\n : details\n ? JSON.stringify(details)\n : '';\n return detail ? `${message} — ${detail}` : message;\n }\n }\n return null;\n}\n","import React, { useEffect, useState } from 'react';\nimport { ActionIcon, Group, Loader, Paper, SegmentedControl, Stack, TagsInput, Text } from '@mantine/core';\nimport { IconBan, IconCircleCheck, IconMessages, IconPercentage, IconUser, IconX } from '@tabler/icons-react';\nimport type { RubricReviewAnswerShape } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { matrixUserIdToDid } from '@/core/lib/matrixDm';\nimport BaseMultiSelect from '@/mantine/components/Base/BaseMultiSelect';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport BaseTextArea from '@/mantine/components/Base/BaseTextArea';\nimport BaseTextInput from '@/mantine/components/Base/BaseTextInput';\nimport { icon } from '@/mantine/components/ReusablePanel';\nimport { useBlocknoteHandlers, type MatrixSpaceStructure } from '@/mantine/context/BlocknoteContext';\nimport { UserSearch } from '../governance/_shared/UserSearch';\nimport { answerLabel } from './phrases';\nimport type { RuleDraft } from './ruleDraft';\nimport { FAILED, PASSED } from './ruleModel';\nimport { chipInput, chipInputStyles, microLabelStyle, panelStyle, segmentedPill } from './rubricStyles';\n\n/** What a reviewer's answer does — colour-coded like the rest of the builder (§B.5 rule 4). */\nconst VERDICT_OPTIONS = [\n { value: 'approve', label: 'Approve the claim', Icon: IconCircleCheck, color: 'var(--mantine-color-green-6)' },\n { value: 'partial', label: 'Part-approve it', Icon: IconPercentage, color: 'var(--mantine-color-blue-6)' },\n { value: 'reject', label: 'Reject the claim', Icon: IconBan, color: 'var(--mantine-color-red-6)' },\n] as const;\n\n/**\n * \"👤 A person checks\" — rubric-spec §A.9, \"review is authored, not improvised\".\n *\n * The author writes the exact question, picks exactly what the reviewer will be\n * shown, and says what each answer does. The reviewer's answer IS the decision;\n * nobody interprets it later. That is why every answer must be given an\n * outcome here (`RUB_REVIEW_ANSWER_UNMAPPED`) — an unanswerable question is a\n * claim that never resolves.\n *\n * Only the two answer shapes that CAN decide anything are offered: Yes/No and a\n * short list. A number or free writing cannot be mapped to an outcome, so a\n * person could answer and the claim would still be stuck — exactly the trap\n * this screen exists to prevent.\n *\n * A person is asked only about evidence that is THERE. A machine can tell that\n * a photo is missing; it just cannot tell what is in one. So a missing answer\n * never waits for anybody — it passes or fails on the spot and the claim is\n * decided. That is what the last control on this screen sets, and why the copy\n * here never promises that somebody will always look.\n */\n\ninterface ReviewTaskEditorProps {\n /** Everything the reviewer could be shown. */\n fieldOptions: { value: string; label: string }[];\n draft: RuleDraft['human'];\n onChange: (next: RuleDraft['human']) => void;\n}\n\nexport const ReviewTaskEditor: React.FC<ReviewTaskEditorProps> = ({ fieldOptions, draft, onChange }) => {\n const answers = possibleAnswers(draft.answer);\n\n const pickShape = (type: string | null) => {\n if (type === 'boolean') {\n onChange({ ...draft, answer: { type: 'boolean' }, map: { true: 'approve', false: 'reject' } });\n } else if (type === 'enum') {\n const options = draft.answer.type === 'enum' ? draft.answer.options : [];\n onChange({ ...draft, answer: { type: 'enum', options }, map: mapFor(options, draft.map) });\n }\n };\n\n const setOptions = (options: string[]) => onChange({ ...draft, answer: { type: 'enum', options }, map: mapFor(options, draft.map) });\n\n return (\n <Stack gap=\"sm\">\n <BaseTextArea\n label=\"What should the person be asked?\"\n styles={chipInput}\n placeholder=\"e.g. Does the delivery photo clearly show the goods at the outlet?\"\n description=\"Ask one plain question they can answer by looking.\"\n minRows={2}\n autosize\n value={draft.prompt}\n onChange={(event) => onChange({ ...draft, prompt: event.currentTarget.value })}\n />\n\n <BaseMultiSelect\n label=\"What should they see?\"\n styles={chipInput}\n placeholder=\"Pick the answers to show them\"\n description=\"They will only see what you pick here.\"\n data={fieldOptions}\n value={draft.show}\n onChange={(show) => onChange({ ...draft, show })}\n searchable\n />\n\n <BaseSelect\n label=\"How do they answer?\"\n w={240}\n styles={chipInput}\n data={[\n { value: 'boolean', label: 'Yes or No' },\n { value: 'enum', label: 'Pick one from a list' },\n ]}\n value={draft.answer.type}\n onChange={pickShape}\n />\n\n {draft.answer.type === 'enum' && (\n <TagsInput label=\"The answers they can pick\" styles={chipInput} placeholder=\"Type an answer, press Enter\" value={draft.answer.options} onChange={setOptions} />\n )}\n\n <Stack gap={6}>\n <Text style={microLabelStyle}>What does each answer do?</Text>\n {answers.length === 0 ? (\n <Text size=\"xs\" c=\"dimmed\">\n Add at least one answer above.\n </Text>\n ) : (\n answers.map((answer) => (\n <Group key={answer} gap=\"xs\" align=\"center\">\n <Text size=\"sm\" fw={500} style={{ width: 160 }}>\n {answerLabel(answer)}\n </Text>\n <Text size=\"xs\" c=\"dimmed\">\n →\n </Text>\n <BaseSelect\n w={200}\n styles={chipInput}\n data={VERDICT_OPTIONS.map(({ value, label }) => ({ value, label }))}\n renderOption={({ option }) => {\n const verdict = VERDICT_OPTIONS.find((entry) => entry.value === option.value);\n return (\n <Group gap={8} wrap=\"nowrap\">\n {verdict && icon(verdict.Icon, 16, verdict.color)}\n <Text size=\"sm\">{option.label}</Text>\n </Group>\n );\n }}\n value={draft.map[answer] ?? null}\n onChange={(verdict) => verdict && onChange({ ...draft, map: { ...draft.map, [answer]: verdict as 'approve' | 'partial' | 'reject' } })}\n />\n </Group>\n ))\n )}\n </Stack>\n\n <Stack gap={6}>\n <Text style={microLabelStyle}>If nothing was attached</Text>\n <SegmentedControl\n w={280}\n styles={segmentedPill}\n data={[\n { value: String(FAILED), label: 'The check fails' },\n { value: String(PASSED), label: 'The check passes' },\n ]}\n value={draft.whenMissing === PASSED ? String(PASSED) : String(FAILED)}\n onChange={(value) => onChange({ ...draft, whenMissing: Number(value) })}\n />\n <Text size=\"xs\" c=\"dimmed\" maw={320}>\n Nobody is asked when there is nothing to look at — the claim is decided this way instead.\n </Text>\n </Stack>\n\n <Text size=\"xs\" c=\"dimmed\">\n When there IS something to look at, the claim waits for the person&apos;s answer — it cannot be approved before then.\n </Text>\n\n <ReviewerPicker draft={draft} onChange={onChange} />\n </Stack>\n );\n};\n\n/** A real Matrix room id (`!room:server`) or alias (`#alias:server`) — the shapes the engine accepts. */\nconst ROOM_SHAPE = /^[!#][^\\s:]+:.+$/;\n\n/**\n * Who reviews (§A.9) — a toggle between the two routings, committed with the\n * rule as ONE rubric-wide value (every 👤 rule shows and edits the same one):\n *\n * - **A channel** (the default): a real Matrix room picked from the entity's\n * own channels (`sourceDomainSpaces`) or pasted — anyone in that room can\n * review. Lands as `review.route.matrixRoom`.\n * - **A person**: the standard people-search; the DID lands as\n * `review.assignTo.assigneeDid` (`matrixUserIdToDid` is idempotent on a DID).\n *\n * The two are one-of — picking one clears the other; with neither, the role\n * lane decides. Only ephemeral scratch (the loaded room list, a search's\n * display name, the toggle) is React state; the picked value lives on the draft.\n */\nconst ReviewerPicker: React.FC<{ draft: RuleDraft['human']; onChange: (next: RuleDraft['human']) => void }> = ({ draft, onChange }) => {\n const [mode, setMode] = useState<'channel' | 'person'>(draft.assigneeDid && !draft.channelRoomId ? 'person' : 'channel');\n const [pickedName, setPickedName] = useState<string | null>(null);\n\n const pickPerson = (did?: string, displayName?: string) => {\n setPickedName(did ? displayName ?? null : null);\n onChange({ ...draft, assigneeDid: did ? matrixUserIdToDid(did) : undefined, channelRoomId: undefined });\n };\n const pickChannel = (roomId?: string) => onChange({ ...draft, channelRoomId: roomId || undefined, assigneeDid: undefined });\n\n return (\n <Stack gap={6}>\n <Text style={microLabelStyle}>Who checks it?</Text>\n <SegmentedControl\n w={320}\n size=\"xs\"\n styles={segmentedPill}\n value={mode}\n onChange={(value) => setMode(value as 'channel' | 'person')}\n data={[\n {\n value: 'channel',\n label: (\n <Group gap={6} wrap=\"nowrap\" justify=\"center\">\n {icon(IconMessages, 14)}\n <span>A channel</span>\n </Group>\n ),\n },\n {\n value: 'person',\n label: (\n <Group gap={6} wrap=\"nowrap\" justify=\"center\">\n {icon(IconUser, 14)}\n <span>A person</span>\n </Group>\n ),\n },\n ]}\n />\n {mode === 'channel' ? (\n <Stack gap={6}>\n <Text size=\"xs\" c=\"dimmed\">\n Anyone in the channel can pick the review up. Leave it empty and anyone with the reviewer role can.\n </Text>\n {draft.channelRoomId ? (\n <>\n <PickedValue title=\"Review channel\" value={draft.channelRoomId} onClear={() => pickChannel(undefined)} clearLabel=\"Remove this channel\" />\n <EngineChannelAccess roomId={draft.channelRoomId} />\n </>\n ) : (\n <ChannelSearch onPick={pickChannel} />\n )}\n </Stack>\n ) : (\n <Stack gap={6}>\n <Text size=\"xs\" c=\"dimmed\">\n Name the person who reviews these claims. Leave it open and anyone with the reviewer role can pick it up.\n </Text>\n {draft.assigneeDid ? (\n <PickedValue title={pickedName ?? 'Assigned reviewer'} value={draft.assigneeDid} onClear={() => pickPerson(undefined)} clearLabel=\"Remove this reviewer\" />\n ) : (\n <UserSearch onPick={(user) => pickPerson(user.did, user.displayName)} placeholder=\"Search for the person who checks\" />\n )}\n </Stack>\n )}\n </Stack>\n );\n};\n\n/**\n * F4 (Matrix integration spec §9.5) — the engine's way into the channel.\n *\n * Routing reviews to a channel is what gives the engine permission to post there,\n * so the invite goes out the moment the channel is picked or changed rather than\n * waiting behind a button the author has to find. It joins as an ordinary member;\n * no elevated power is asked for in a room the author owns.\n *\n * The host does the inviting (the block has no chat client of its own). An older\n * host without the handler shows nothing — the author's rubric is still valid,\n * and the engine can be added to the channel by hand.\n */\nconst EngineChannelAccess: React.FC<{ roomId: string }> = ({ roomId }) => {\n const handlers = useBlocknoteHandlers();\n const invite = handlers.inviteEvalEngineToChannel;\n const [state, setState] = useState<'working' | 'ready' | 'unavailable' | 'failed'>('working');\n\n useEffect(() => {\n if (typeof invite !== 'function') return;\n let alive = true;\n setState('working');\n invite({ roomId })\n // \"Already there\" is the outcome we wanted, not an error.\n .then((result) => alive && setState(result?.status === 'not-configured' ? 'unavailable' : 'ready'))\n .catch((error) => {\n console.warn('[eval.rubric] could not invite the eval engine to the review channel:', error);\n if (alive) setState('failed');\n });\n return () => {\n alive = false;\n };\n }, [roomId, invite]);\n\n if (typeof invite !== 'function' || state === 'unavailable') return null;\n\n if (state === 'working') {\n return (\n <Group gap={6} wrap=\"nowrap\">\n <Loader size={12} />\n <Text size=\"xs\" c=\"dimmed\">\n Giving the eval engine access to this channel…\n </Text>\n </Group>\n );\n }\n\n if (state === 'failed') {\n return (\n <Text size=\"xs\" c=\"red\">\n Couldn’t give the eval engine access to this channel. Open the channel and invite it yourself, or pick another one.\n </Text>\n );\n }\n\n return (\n <Group gap={6} wrap=\"nowrap\">\n {icon(IconCircleCheck, 14, 'var(--mantine-color-green-6)')}\n <Text size=\"xs\" c=\"dimmed\">\n The eval engine can post review requests here.\n </Text>\n </Group>\n );\n};\n\n/** The picked channel/person, with its raw id underneath and an ✕ to re-pick. */\nconst PickedValue: React.FC<{ title: string; value: string; onClear: () => void; clearLabel: string }> = ({ title, value, onClear, clearLabel }) => (\n <Paper p=\"xs\" style={panelStyle}>\n <Group gap=\"xs\" justify=\"space-between\" wrap=\"nowrap\">\n <Stack gap={0}>\n <Text size=\"sm\" fw={500}>\n {title}\n </Text>\n <Text size=\"xs\" c=\"dimmed\" style={{ wordBreak: 'break-all' }}>\n {value}\n </Text>\n </Stack>\n <ActionIcon variant=\"subtle\" color=\"red\" onClick={onClear} aria-label={clearLabel}>\n <IconX size={16} />\n </ActionIcon>\n </Group>\n </Paper>\n);\n\ntype ChannelOptions = Array<{ value: string; label: string } | { group: string; items: Array<{ value: string; label: string }> }>;\n\n/**\n * The domain's channels as a dropdown — plus a paste box, because a room the\n * domain doesn't own (or a host without the handlers) is still a legal routing.\n *\n * Listing prefers the host's `listDomainChannels` (the LIVE channel list: the\n * joined, named rooms under the domain's main space via the client-side\n * `m.space.child` walk — what the product means by \"channels\"). An older host\n * without it falls back to flattening `sourceDomainSpaces`, whose `rooms`\n * arrays are only the space skeleton and usually empty.\n */\nconst ChannelSearch: React.FC<{ onPick: (roomId: string) => void }> = ({ onPick }) => {\n const handlers = useBlocknoteHandlers();\n const canList = typeof handlers.listDomainChannels === 'function' || typeof handlers.sourceDomainSpaces === 'function';\n\n // The loaded list is an ephemeral server-data cache, like a search's results.\n const [options, setOptions] = useState<ChannelOptions>([]);\n const [loading, setLoading] = useState(canList);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [pasted, setPasted] = useState('');\n\n useEffect(() => {\n if (!canList) return;\n let alive = true;\n const load = async (): Promise<ChannelOptions> => {\n if (typeof handlers.listDomainChannels === 'function') {\n const rooms = await handlers.listDomainChannels();\n return rooms.map((room) => ({ value: room.roomId, label: room.name || room.roomId }));\n }\n const tree = (await handlers.sourceDomainSpaces!()) as MatrixSpaceStructure;\n const label = (room: { roomId: string; roomAlias: string }) => room.roomAlias || room.roomId;\n const groups = [\n { group: 'This entity', items: (tree.rooms ?? []).map((room) => ({ value: room.roomId, label: label(room) })) },\n ...Object.entries(tree.subspaces ?? {}).map(([name, subspace]) => ({\n group: name,\n items: (subspace?.rooms ?? []).map((room) => ({ value: room.roomId, label: label(room) })),\n })),\n ];\n return groups.filter((entry) => entry.items.length > 0);\n };\n load()\n .then((loaded) => alive && setOptions(loaded))\n .catch((error) => {\n // Say WHY the list is missing — a silent fallback to the paste box\n // reads as \"the dropdown never shipped\".\n console.warn('[eval.rubric] channel listing failed:', error);\n if (alive) setLoadError(error instanceof Error ? error.message : String(error));\n })\n .finally(() => alive && setLoading(false));\n return () => {\n alive = false;\n };\n // Load once per mount — the domain's rooms don't change under an open modal.\n }, []);\n\n const pastedValid = ROOM_SHAPE.test(pasted.trim());\n const empty = !loading && options.length === 0;\n\n return (\n <Stack gap={6}>\n {/* The dropdown is the way in: every channel of the current domain space,\n grouped, searchable. It only steps aside when there is nothing to list. */}\n {canList && !empty && (\n <BaseSelect\n w={320}\n styles={chipInput}\n placeholder={loading ? 'Finding this domain’s channels…' : 'Pick one of this domain’s channels'}\n data={options}\n value={null}\n onChange={(roomId) => roomId && onPick(roomId)}\n searchable\n disabled={loading}\n rightSection={loading ? <Loader size={12} /> : undefined}\n />\n )}\n {(empty || !canList) && (\n <Text size=\"xs\" c={loadError ? 'red' : 'dimmed'}>\n {loadError\n ? `Couldn’t list this domain’s channels (${loadError}) — paste the channel id instead.`\n : canList\n ? 'No channels found in this domain space — paste the channel id instead.'\n : 'Channels can’t be listed here — paste the channel id instead.'}\n </Text>\n )}\n <BaseTextInput\n w={320}\n styles={chipInputStyles(Boolean(pasted.trim() && !pastedValid))}\n placeholder=\"…or paste a channel id (!room:server)\"\n value={pasted}\n error={pasted.trim() && !pastedValid ? 'A channel id starts with ! or # and contains :server' : undefined}\n onChange={(event) => setPasted(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && pastedValid) onPick(pasted.trim());\n }}\n onBlur={() => {\n if (pastedValid) onPick(pasted.trim());\n }}\n />\n </Stack>\n );\n};\n\n/** Every answer the reviewer could give — the ones that must each have an outcome. */\nfunction possibleAnswers(answer: RubricReviewAnswerShape): string[] {\n if (answer.type === 'boolean') return ['true', 'false'];\n if (answer.type === 'enum') return answer.options;\n return [];\n}\n\n/** Keep the outcomes the author already set; give any new answer a safe default. */\nfunction mapFor(options: string[], existing: Record<string, 'approve' | 'partial' | 'reject'>): Record<string, 'approve' | 'partial' | 'reject'> {\n return Object.fromEntries(options.map((option) => [option, existing[option] ?? 'reject']));\n}\n","import type { RubricBody, RubricField, RubricFieldKind } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { newDraft, type RuleDraft } from './ruleDraft';\n\n/**\n * One-tap rules — rubric-spec §B.5, \"clicking + Add a rule first offers\n * templates for that field's kind … this covers ~90% of real rules\".\n *\n * A template is a complete, already-valid rule: tapping one adds a rule that\n * publishes as-is. The sentence builder behind \"Custom rule\" is the escape\n * hatch, not the front door — an author who never opens it should still be able\n * to write the whole devnet example in §A.13.\n *\n * `TEMPLATES` is a `Record` over the kind union, so a new field kind cannot\n * ship without someone deciding what its one-tap rules are.\n */\n\nexport interface RuleTemplate {\n id: string;\n label: string;\n /** Filled in by `templatesForField` — the draft the tap produces. */\n draft: RuleDraft;\n}\n\ninterface TemplateDef {\n id: string;\n label: string;\n /** `undefined` = this template cannot apply to this particular question (e.g. a choice list with no options). */\n build: (field: RubricField, body: RubricBody | null) => RuleDraft | undefined;\n}\n\n// ── the individual templates ───────────────────────────────────────────────\n\nconst mustBeFilledIn: TemplateDef = {\n id: 'present',\n label: 'Must be filled in',\n build: (field, body) => reject(newDraft(body, field.path, 'present'), `${field.title} is missing`, 'insufficient_evidence'),\n};\n\nconst mustBeAttached: TemplateDef = {\n id: 'attached',\n label: 'Must be attached',\n build: (field, body) => reject(newDraft(body, field.path, 'present'), `${field.title} is missing`, 'insufficient_evidence'),\n};\n\nconst mustBeDuringPeriod: TemplateDef = {\n id: 'withinWindow',\n label: 'Must be during the collection period',\n build: (field, body) => reject(newDraft(body, field.path, 'withinWindow'), `${field.title} is outside the collection period`, 'refuted'),\n};\n\nconst cannotBeInFuture: TemplateDef = {\n id: 'notInFuture',\n label: 'Cannot be in the future',\n build: (field, body) => reject(newDraft(body, field.path, 'notInFuture'), `${field.title} is in the future`, 'refuted'),\n};\n\nconst mustBeOneOf: TemplateDef = {\n id: 'in',\n label: 'Must be one of…',\n build: (field, body) => {\n if (!field.choices || field.choices.length === 0) return undefined;\n const draft = newDraft(body, field.path, 'in');\n // Pre-ticked with every option the form offers. The list stores the choices'\n // VALUES; the author only ever sees their texts (§A.3).\n draft.reject.when = { field: field.path, op: 'in', value: field.choices.map((choice) => choice.value) };\n return reject(draft, `${field.title} is not allowed`, 'out_of_authority');\n },\n};\n\nconst mustBeAtLeast: TemplateDef = {\n id: 'atLeast',\n label: 'Must be at least…',\n build: (field, body) => {\n const draft = newDraft(body, field.path, '>=');\n draft.reject.when = { field: field.path, op: '>=', value: 1 };\n return reject(draft, `${field.title} is too low`, 'refuted');\n },\n};\n\nconst mustBeAPdf: TemplateDef = {\n id: 'pdf',\n label: 'Must be a PDF',\n build: (field, body) => {\n const draft = newDraft(body, field.path, 'mediaTypeIn');\n draft.reject.when = { field: field.path, op: 'mediaTypeIn', value: ['application/pdf'] };\n return reject(draft, `${field.title} must be a PDF`, 'invalid_evidence');\n },\n};\n\nconst aPersonChecks: TemplateDef = {\n id: 'human',\n label: 'A person checks it',\n build: (field, body) => {\n const draft = newDraft(body, field.path);\n draft.consequence = 'human';\n draft.human = { ...draft.human, prompt: `Does “${field.title}” show what it should?`, show: [field.path] };\n return draft;\n },\n};\n\nconst mustBeTicked: TemplateDef = {\n id: 'isTrue',\n label: 'Must be ticked',\n build: (field, body) => reject(newDraft(body, field.path, 'isTrue'), `${field.title} was not confirmed`, 'refuted'),\n};\n\nconst everyRowMust: TemplateDef = {\n id: 'everyRow',\n label: 'Every row must be filled in',\n build: (field, body) => {\n // Prefer a number column: \"every row's quantity …\" is the rule people write.\n const column = field.columns?.find((inner) => inner.kind === 'number') ?? field.columns?.[0];\n if (!column) return undefined;\n return reject(newDraft(body, column.path, 'present'), `Every row of ${field.title} must be complete`, 'insufficient_evidence');\n },\n};\n\nconst mustHaveEntries: TemplateDef = {\n id: 'countBetween',\n label: 'Must have at least one entry',\n build: (field, body) => {\n const draft = newDraft(body, field.path, 'countBetween');\n draft.reject.when = { field: field.path, op: 'countBetween', value: [1, 100] };\n return reject(draft, `${field.title} is empty`, 'insufficient_evidence');\n },\n};\n\nconst mustBeInProjectArea: TemplateDef = {\n id: 'withinBoundary',\n label: 'Must be inside the project area',\n build: (field, body) => {\n const draft = newDraft(body, field.path, 'withinBoundary');\n draft.reject.when = { field: field.path, op: 'withinBoundary', value: 'ctx.collection.projectBoundary' };\n return reject(draft, `${field.title} is outside the project area`, 'out_of_authority');\n },\n};\n\n// ── the per-kind menu (§B.5's list) ────────────────────────────────────────\n\nconst TEMPLATES: Record<RubricFieldKind, TemplateDef[]> = {\n text: [mustBeFilledIn],\n number: [mustBeAtLeast],\n date: [mustBeDuringPeriod, cannotBeInFuture],\n choice: [mustBeOneOf],\n multichoice: [mustBeFilledIn, mustHaveEntries],\n boolean: [mustBeTicked],\n file: [mustBeAttached, mustBeAPdf, aPersonChecks],\n signature: [mustBeAttached, aPersonChecks],\n geo: [mustBeInProjectArea],\n rows: [everyRowMust, mustHaveEntries],\n cells: [mustBeFilledIn],\n keyed_choice: [mustBeFilledIn],\n keyed_text: [mustBeFilledIn],\n};\n\n/** The one-tap rules on offer for this question, already built. */\nexport function templatesForField(field: RubricField, body: RubricBody | null): RuleTemplate[] {\n const templates: RuleTemplate[] = [];\n for (const def of TEMPLATES[field.kind] ?? []) {\n const draft = def.build(field, body);\n if (draft) templates.push({ id: def.id, label: def.label, draft });\n }\n return templates;\n}\n\n/** Finish a reject draft: the message the claimant will read, and the reason it was turned down. */\nfunction reject(draft: RuleDraft, reason: string, verdictClass: RuleDraft['reject']['verdictClass']): RuleDraft {\n draft.consequence = 'reject';\n draft.reject = { ...draft.reject, reason, verdictClass };\n return draft;\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Group, Paper, SegmentedControl, Stack, Switch, Text } from '@mantine/core';\nimport type { RubricBody } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport BaseNumberInput from '@/mantine/components/Base/BaseNumberInput';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport {\n FREQUENCY_BREACH_LABEL,\n FREQUENCY_BREACH_OPTIONS,\n FREQUENCY_BREACH_REVIEW_HINT,\n FREQUENCY_EXPLAINER,\n FREQUENCY_MAX_LEAD,\n FREQUENCY_PERIOD_ARIA,\n FREQUENCY_PERIOD_OPTIONS,\n FREQUENCY_TITLE,\n frequencyMaxNoun,\n} from './phrases';\nimport { compileFrequency, deriveFrequency, type FrequencyState } from './frequencyModel';\nimport { cardStyle, chipInput, segmentedPill } from './rubricStyles';\n\n/**\n * \"Limit how often each person can claim\" — the frequency rule's section\n * (dup-detection spec §13), the same document-level card as \"This claim must be\n * unique\": the whole state is DERIVED from the document (`deriveFrequency`) and\n * every change compiles straight back (`compileFrequency`) — no stored builder\n * state. The one local mirror is the in-progress edit itself, which re-derives\n * on an EXTERNAL document change and skips only the echo of its own write.\n *\n * The controls read as one sentence — \"At most [2] claims [per month]\" — and\n * the breach behaviour is the same two-consequence surface as everywhere else\n * (§B.5): a person checks (the engine default), or reject.\n */\n\ninterface FrequencyRuleProps {\n body: RubricBody;\n onChange: (next: RubricBody) => void;\n disabled?: boolean;\n}\n\nexport const FrequencyRule: React.FC<FrequencyRuleProps> = ({ body, onChange, disabled }) => {\n const [state, setState] = useState<FrequencyState>(() => deriveFrequency(body));\n const lastWrittenRef = useRef<string | null>(null);\n const bodyJson = JSON.stringify(body);\n useEffect(() => {\n // Re-derive on an EXTERNAL document change only — our own write echoes back\n // through the block's inputs and must not clobber the in-progress edit.\n if (bodyJson === lastWrittenRef.current) return;\n setState(deriveFrequency(body));\n // `bodyJson` (content) is the real dependency — `body`'s identity churns on every write.\n }, [bodyJson]);\n\n const commit = (next: FrequencyState) => {\n setState(next);\n const compiled = compileFrequency(body, next);\n const json = JSON.stringify(compiled);\n lastWrittenRef.current = json;\n if (json !== bodyJson) onChange(compiled);\n };\n\n return (\n <Paper p={18} style={cardStyle}>\n <Stack gap=\"sm\">\n <Group gap=\"sm\" justify=\"space-between\" align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\" fw={600}>\n {FREQUENCY_TITLE}\n </Text>\n <Switch size=\"sm\" checked={state.on} onChange={(event) => commit({ ...state, on: event.currentTarget.checked })} disabled={disabled} aria-label={FREQUENCY_TITLE} />\n </Group>\n\n {state.on && (\n <Stack gap=\"sm\">\n <Text size=\"xs\" c=\"dimmed\">\n {FREQUENCY_EXPLAINER}\n </Text>\n\n {/* The limit as one sentence: \"At most [2] claims [per month]\". */}\n <Group gap={8} align=\"center\" wrap=\"nowrap\">\n <Text size=\"sm\" fw={500}>\n {FREQUENCY_MAX_LEAD}\n </Text>\n <BaseNumberInput\n w={80}\n styles={chipInput}\n min={1}\n allowDecimal={false}\n value={state.max}\n onChange={(next) => commit({ ...state, max: typeof next === 'number' && next >= 1 ? Math.round(next) : 1 })}\n disabled={disabled}\n aria-label={FREQUENCY_MAX_LEAD}\n />\n <Text size=\"sm\" fw={500}>\n {frequencyMaxNoun(state.max)}\n </Text>\n <BaseSelect\n w={130}\n styles={chipInput}\n data={FREQUENCY_PERIOD_OPTIONS}\n value={state.per}\n onChange={(per) => commit({ ...state, per: (per ?? state.per) as FrequencyState['per'] })}\n disabled={disabled}\n aria-label={FREQUENCY_PERIOD_ARIA}\n />\n </Group>\n\n <Stack gap={6}>\n <Text size=\"sm\" fw={500}>\n {FREQUENCY_BREACH_LABEL}\n </Text>\n <SegmentedControl\n styles={segmentedPill}\n value={state.onBreach}\n onChange={(onBreach) => commit({ ...state, onBreach: onBreach as FrequencyState['onBreach'] })}\n disabled={disabled}\n data={FREQUENCY_BREACH_OPTIONS}\n />\n {/* Review is the engine's default for a reason — say what it means where the author decides. */}\n {state.onBreach === 'review' && (\n <Text size=\"xs\" c=\"dimmed\">\n {FREQUENCY_BREACH_REVIEW_HINT}\n </Text>\n )}\n </Stack>\n </Stack>\n )}\n </Stack>\n </Paper>\n );\n};\n","import type { RubricBody, RubricFrequency } from '@/core/lib/actionRegistry/actions/evalRubric/types';\n\n/**\n * \"Limit how often each person can claim\" — the frequency rule's editing model\n * (dup-detection spec §13), the bridge between the toggle/stepper/selects and\n * the document, the way `uniqueModel` bridges the duplicate rule's card.\n *\n * The document stores NO builder state: `deriveFrequency` reads everything off\n * `body.frequency`, and `compileFrequency` writes only the §13 grammar the\n * engine parses (eval-engine `schema.ts`, `Frequency`). Patch-style on purpose:\n * what the controls do not edit — the block's `id`, a hand-authored `label` —\n * survives a recompile verbatim, and the toggle OFF on a document that never\n * had one is byte-identical, so opening the panel never dirties a rubric.\n */\n\n/** One block per rubric, so one stable id — stable across setting changes, like the unique rule's. */\nconst DEFAULT_ID = 'claim-limit';\n/** A fresh card reads \"At most 1 claim per month\" — the spec's own worked example (§13). */\nconst DEFAULT_MAX = 1;\nconst DEFAULT_PER: RubricFrequency['per'] = 'month';\n\nexport interface FrequencyState {\n on: boolean;\n /** The window budget, min 1 — the count includes the claim being evaluated. */\n max: number;\n per: RubricFrequency['per'];\n /** The ENGINE'S DEFAULT is `review` — over the limit means a person checks, never an automatic reject. */\n onBreach: NonNullable<RubricFrequency['onBreach']>;\n}\n\n/** The controls' state, derived from the document alone. Absent `onBreach` bytes mean the engine default — review. */\nexport function deriveFrequency(body: RubricBody): FrequencyState {\n const frequency = body.frequency;\n return {\n on: !!frequency,\n max: frequency?.max ?? DEFAULT_MAX,\n per: frequency?.per ?? DEFAULT_PER,\n onBreach: frequency?.onBreach ?? 'review',\n };\n}\n\n/**\n * Compile the controls back into the document. OFF strips the block; ON writes\n * the §13 grammar with `onBreach` omitted when it is the engine's default\n * (`review`) — the bytes carry no key the engine would fill in anyway, matching\n * the minimal-bytes convention of `unique.ai`. An UNCHANGED toggle keeps the\n * prior bytes verbatim, so a hand-written explicit `onBreach: \"review\"`\n * survives a recompile rather than being silently stripped.\n */\nexport function compileFrequency(body: RubricBody, state: FrequencyState): RubricBody {\n if (!state.on) {\n if (body.frequency === undefined) return body;\n const { frequency: _off, ...rest } = body;\n return rest;\n }\n const prior = body.frequency;\n const onBreach = state.onBreach === (prior?.onBreach ?? 'review') ? prior?.onBreach : state.onBreach === 'review' ? undefined : 'reject';\n return {\n ...body,\n frequency: {\n '@type': 'Frequency',\n id: prior?.id ?? DEFAULT_ID,\n ...(prior?.label !== undefined ? { label: prior.label } : {}),\n max: state.max,\n per: state.per,\n ...(onBreach !== undefined ? { onBreach } : {}),\n },\n };\n}\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { Alert, Badge, Group, Paper, Slider, Stack, Switch, Text } from '@mantine/core';\nimport type { RubricBody, RubricField, RubricFieldCatalog } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport BaseMultiSelect from '@/mantine/components/Base/BaseMultiSelect';\nimport BaseSelect from '@/mantine/components/Base/BaseSelect';\nimport { actionAlertStyles } from '../../alertStyles';\nimport {\n UNIQUE_AI_LABEL,\n UNIQUE_AI_OFF_WARNING,\n UNIQUE_AI_ON_HINT,\n UNIQUE_BY_HINT,\n UNIQUE_BY_LABEL,\n UNIQUE_BY_PLACEHOLDER,\n UNIQUE_EXPLAINER,\n UNIQUE_FILE_BADGE,\n UNIQUE_GRANULARITY_OPTIONS,\n UNIQUE_PRICING_NOTE,\n UNIQUE_REJECT_LABEL,\n UNIQUE_REVIEW_LABEL,\n UNIQUE_TITLE,\n uniqueGranularityLead,\n} from './phrases';\nimport { cardStyle, chipInput } from './rubricStyles';\nimport { compileUnique, deriveUnique, withGranularity, withRejectAt, withReviewAt, type UniqueGranularity, type UniqueState } from './uniqueModel';\n\n/**\n * \"This claim must be unique\" — the duplicate rule's section (dup-detection\n * spec §6), the same document-level card as \"When is a claim approved?\": the\n * whole state is DERIVED from the document (`deriveUnique`) and every change\n * compiles straight back (`compileUnique`) — no stored builder state. The one\n * local mirror is the in-progress edit itself, which re-derives on an EXTERNAL\n * document change and skips only the echo of its own write.\n *\n * The key picker draws from the same field catalog every other picker reads\n * (§B.4), so the author can only ever key on questions that exist. File-kind\n * fields are pickable and badged: they match by file fingerprint (CID/pHash),\n * so a re-saved or recompressed copy of the same document still counts.\n */\n\ninterface UniqueRuleProps {\n body: RubricBody;\n catalog: RubricFieldCatalog;\n onChange: (next: RubricBody) => void;\n disabled?: boolean;\n}\n\n/** Container questions address no single value, so they cannot serve as a key component. */\nconst CONTAINER_KINDS = new Set<RubricField['kind']>(['keyed_choice', 'cells', 'rows', 'keyed_text']);\n\nexport const UniqueRule: React.FC<UniqueRuleProps> = ({ body, catalog, onChange, disabled }) => {\n const [state, setState] = useState<UniqueState>(() => deriveUnique(body));\n const lastWrittenRef = useRef<string | null>(null);\n const bodyJson = JSON.stringify(body);\n useEffect(() => {\n // Re-derive on an EXTERNAL document change only — our own write echoes back\n // through the block's inputs and must not clobber the in-progress edit.\n if (bodyJson === lastWrittenRef.current) return;\n setState(deriveUnique(body));\n // `bodyJson` (content) is the real dependency — `body`'s identity churns on every write.\n }, [bodyJson]);\n\n const commit = (next: UniqueState) => {\n setState(next);\n const compiled = compileUnique(body, next);\n const json = JSON.stringify(compiled);\n lastWrittenRef.current = json;\n if (json !== bodyJson) onChange(compiled);\n };\n\n const keyFields = useMemo(() => catalog.fields.filter((field) => !CONTAINER_KINDS.has(field.kind)), [catalog]);\n const fieldByPath = useMemo(() => new Map(keyFields.map((field) => [field.path, field])), [keyFields]);\n // A ref the catalog no longer carries (hand-authored, or the form moved) stays\n // visible and removable rather than silently vanishing from the pills.\n const options = useMemo(\n () => [...keyFields.map((field) => ({ value: field.path, label: field.title })), ...state.by.filter((ref) => !fieldByPath.has(ref)).map((ref) => ({ value: ref, label: ref }))],\n [keyFields, fieldByPath, state.by]\n );\n const pickedFileTitles = state.by.filter((ref) => fieldByPath.get(ref)?.kind === 'file').map((ref) => fieldByPath.get(ref)!.title);\n const pickedDateRefs = state.by.filter((ref) => fieldByPath.get(ref)?.kind === 'date');\n\n return (\n <Paper p={18} style={cardStyle}>\n <Stack gap=\"sm\">\n <Group gap=\"sm\" justify=\"space-between\" align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\" fw={600}>\n {UNIQUE_TITLE}\n </Text>\n <Switch size=\"sm\" checked={state.on} onChange={(event) => commit({ ...state, on: event.currentTarget.checked })} disabled={disabled} aria-label={UNIQUE_TITLE} />\n </Group>\n\n {state.on && (\n <Stack gap=\"sm\">\n <Text size=\"xs\" c=\"dimmed\">\n {UNIQUE_EXPLAINER}\n </Text>\n\n <BaseMultiSelect\n label={UNIQUE_BY_LABEL}\n description={UNIQUE_BY_HINT}\n placeholder={state.by.length === 0 ? UNIQUE_BY_PLACEHOLDER : undefined}\n data={options}\n value={state.by}\n onChange={(by) => commit({ ...state, by })}\n renderOption={({ option }) => (\n <Group gap=\"xs\" wrap=\"nowrap\" justify=\"space-between\" style={{ flex: 1 }}>\n <Text size=\"sm\">{option.label}</Text>\n {fieldByPath.get(option.value)?.kind === 'file' && (\n <Badge size=\"xs\" variant=\"light\" color=\"neutralColor\">\n {UNIQUE_FILE_BADGE}\n </Badge>\n )}\n </Group>\n )}\n styles={chipInput}\n searchable\n disabled={disabled}\n />\n\n {/* The pills cannot carry the badge, so a picked file field is named here. */}\n {pickedFileTitles.length > 0 && (\n <Text size=\"xs\" c=\"dimmed\">\n {pickedFileTitles.map((title) => `“${title}”`).join(', ')} — {UNIQUE_FILE_BADGE}: a re-saved or recompressed copy still matches.\n </Text>\n )}\n\n {/* A picked DATE field gets a coarseness row (engine `UniqueBy.granularity`):\n \"exactly\" is the default and emits a plain ref; day/month/year emit\n `{ref, granularity}` so the key compares dates at that coarseness. */}\n {pickedDateRefs.map((ref) => (\n <Group key={ref} gap={8} align=\"center\" wrap=\"nowrap\">\n <Text size=\"xs\" c=\"dimmed\">\n {uniqueGranularityLead(fieldByPath.get(ref)!.title)}\n </Text>\n <BaseSelect\n w={180}\n styles={chipInput}\n data={UNIQUE_GRANULARITY_OPTIONS}\n value={state.granularity[ref] ?? 'exact'}\n onChange={(value) => commit(withGranularity(state, ref, value && value !== 'exact' ? (value as UniqueGranularity) : undefined))}\n disabled={disabled}\n aria-label={uniqueGranularityLead(fieldByPath.get(ref)!.title)}\n />\n </Group>\n ))}\n\n <Switch\n size=\"sm\"\n label={UNIQUE_AI_LABEL}\n description={state.ai ? UNIQUE_AI_ON_HINT : undefined}\n checked={state.ai}\n onChange={(event) => commit({ ...state, ai: event.currentTarget.checked })}\n styles={{ label: { fontWeight: 500 } }}\n disabled={disabled}\n />\n\n {/* Switching the judge off has a consequence the author must see (owner 2026-08-05):\n the similar-but-not-identical zone passes with only a recorded score. */}\n {!state.ai && (\n <Alert color=\"yellow\" styles={actionAlertStyles} p=\"xs\">\n <Text size=\"xs\">{UNIQUE_AI_OFF_WARNING}</Text>\n </Alert>\n )}\n\n {/* Pricing is bundled — say so where the author decides, so nothing implies a separate AI charge. */}\n <Text size=\"xs\" c=\"dimmed\">\n {UNIQUE_PRICING_NOTE}\n </Text>\n\n <Stack gap={4}>\n <Group justify=\"space-between\">\n <Text size=\"sm\" fw={500}>\n {UNIQUE_REJECT_LABEL}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ff=\"monospace\">\n ≥ {state.rejectAtPct}%\n </Text>\n </Group>\n <Slider\n min={0}\n max={100}\n step={1}\n value={state.rejectAtPct}\n onChange={(pct) => setState(withRejectAt(state, pct))}\n onChangeEnd={(pct) => commit(withRejectAt(state, pct))}\n label={(pct) => `≥ ${pct}%`}\n color=\"accent.5\"\n disabled={disabled}\n />\n </Stack>\n\n <Stack gap={4}>\n <Group justify=\"space-between\">\n <Text size=\"sm\" fw={500}>\n {UNIQUE_REVIEW_LABEL}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ff=\"monospace\">\n ≥ {state.reviewAtPct}%\n </Text>\n </Group>\n <Slider\n min={0}\n max={100}\n step={1}\n value={state.reviewAtPct}\n onChange={(pct) => setState(withReviewAt(state, pct))}\n onChangeEnd={(pct) => commit(withReviewAt(state, pct))}\n label={(pct) => `≥ ${pct}%`}\n color=\"accent.5\"\n disabled={disabled}\n />\n </Stack>\n </Stack>\n )}\n </Stack>\n </Paper>\n );\n};\n","import type { RubricBody, RubricUnique, RubricUniqueBy } from '@/core/lib/actionRegistry/actions/evalRubric/types';\n\n/**\n * \"This claim must be unique\" — the duplicate rule's editing model\n * (dup-detection spec §6), the bridge between the toggle/picker/sliders and\n * the document, the way `policyModel` bridges the approval tabs.\n *\n * The document stores NO builder state: `deriveUnique` reads everything off\n * `body.unique`, and `compileUnique` writes only the §6 grammar the engine\n * already parses. Patch-style on purpose: what the controls do not edit — the\n * block's `id`, a hand-authored `label`, a `{ref, granularity}` key entry, a\n * tuned `ai.maxPairs`, a custom `countPrior` — survives a recompile verbatim,\n * so opening the panel never rewrites a hand-authored block, and the toggle\n * OFF on a document that never had one is byte-identical.\n */\n\n/** The §6 defaults, spelled out — the builder writes them explicitly so the machine view is honest. */\nconst DEFAULT_COUNT_PRIOR: NonNullable<RubricUnique['countPrior']> = ['approved', 'pending_review', 'queued'];\nconst DEFAULT_REJECT_AT_PCT = 90;\nconst DEFAULT_REVIEW_AT_PCT = 50;\n/** One block per rubric, so one stable id — stable bytes keep the rubric's content hash honest. */\nconst DEFAULT_ID = 'no-duplicates';\n\n/** A date key entry's comparison coarseness (engine `UniqueBy`) — absent means the exact value. */\nexport type UniqueGranularity = NonNullable<Exclude<RubricUniqueBy, string>['granularity']>;\n\nexport interface UniqueState {\n on: boolean;\n /** The picked key refs (plain `$field` paths), in pick order. Empty = whole-body mode. */\n by: string[];\n /** Per-ref date coarseness (date-kind fields only get the control). Absent ⇒ the exact value. */\n granularity: Partial<Record<string, UniqueGranularity>>;\n /** The gray-zone AI judge (dup §7) — the ENGINE'S DEFAULT is on (T18): switching it off means weak matches pass with only a recorded score. Priced into the per-claim fee, never billed separately. */\n ai: boolean;\n /** Whole percent in the UI; bps only in the document. */\n rejectAtPct: number;\n reviewAtPct: number;\n}\n\nconst refOf = (entry: RubricUniqueBy): string => (typeof entry === 'string' ? entry : entry.ref);\n\nconst clampPct = (pct: number): number => Math.min(Math.max(Math.round(pct) || 0, 0), 100);\n\n/** Move the reject threshold; review follows down so `reject ≥ review` always holds. */\nexport function withRejectAt(state: UniqueState, pct: number): UniqueState {\n const rejectAtPct = clampPct(pct);\n return { ...state, rejectAtPct, reviewAtPct: Math.min(state.reviewAtPct, rejectAtPct) };\n}\n\n/** Move the review threshold; reject follows up — same bound, other direction. */\nexport function withReviewAt(state: UniqueState, pct: number): UniqueState {\n const reviewAtPct = clampPct(pct);\n return { ...state, reviewAtPct, rejectAtPct: Math.max(state.rejectAtPct, reviewAtPct) };\n}\n\n/** Set (or clear, with `undefined`) one date ref's coarseness — the picker's per-field select. */\nexport function withGranularity(state: UniqueState, ref: string, granularity: UniqueGranularity | undefined): UniqueState {\n const { [ref]: _prior, ...rest } = state.granularity;\n return { ...state, granularity: granularity ? { ...rest, [ref]: granularity } : rest };\n}\n\n/** The controls' state, derived from the document alone. A granularity entry reads as its ref + its coarseness. */\nexport function deriveUnique(body: RubricBody): UniqueState {\n const unique = body.unique;\n const granularity: UniqueState['granularity'] = {};\n for (const entry of unique?.by ?? []) {\n if (typeof entry !== 'string' && entry.granularity) granularity[entry.ref] = entry.granularity;\n }\n return {\n on: !!unique,\n by: (unique?.by ?? []).map(refOf),\n granularity,\n // Absent bytes mean the engine's default — ON. Only an explicit `enabled: false` reads back\n // as off, so a newly-enabled rule (no block yet) starts with the judge on, like the engine.\n ai: unique?.ai?.enabled !== false,\n rejectAtPct: unique?.thresholds ? Math.round(unique.thresholds.rejectAtBps / 100) : DEFAULT_REJECT_AT_PCT,\n reviewAtPct: unique?.thresholds ? Math.round(unique.thresholds.reviewAtBps / 100) : DEFAULT_REVIEW_AT_PCT,\n };\n}\n\n/**\n * Compile the controls back into the document. OFF strips the block; ON writes\n * the §6 grammar with `by` omitted entirely when nothing is picked (whole-body\n * mode). The AI judge is the ENGINE'S DEFAULT (T18): with the switch on, `ai`\n * is omitted — the bytes carry no key the engine would fill in anyway — and\n * opting out writes the one shape that means off, `{ enabled: false }`. An\n * unchanged switch keeps the prior `ai` bytes verbatim, so a hand-tuned\n * `maxPairs` (or a hand-written entry) survives a recompile, and a flip\n * carries the tuned `maxPairs` across.\n */\nexport function compileUnique(body: RubricBody, state: UniqueState): RubricBody {\n if (!state.on) {\n if (body.unique === undefined) return body;\n const { unique: _off, ...rest } = body;\n return rest;\n }\n const prior = body.unique;\n // An UNCHANGED select keeps the authored entry byte-for-byte (a `{ref}` object\n // with no granularity, an object on a field the picker offers no control for —\n // both survive verbatim, like an untouched `ai`). A CHANGED one writes the\n // minimal bytes: `{ref, granularity}` when coarse, the plain ref when exact.\n const priorByRef = new Map((prior?.by ?? []).map((entry) => [refOf(entry), entry]));\n const by = state.by.map((ref): RubricUniqueBy => {\n const authored = priorByRef.get(ref);\n const authoredGranularity = authored !== undefined && typeof authored !== 'string' ? authored.granularity : undefined;\n const picked = state.granularity[ref];\n if (picked === authoredGranularity && authored !== undefined) return authored;\n return picked ? { ref, granularity: picked } : ref;\n });\n const priorPairs = prior?.ai?.maxPairs;\n const ai =\n state.ai === (prior?.ai?.enabled !== false)\n ? prior?.ai\n : state.ai\n ? priorPairs !== undefined\n ? { enabled: true, maxPairs: priorPairs }\n : undefined\n : { enabled: false, ...(priorPairs !== undefined ? { maxPairs: priorPairs } : {}) };\n return {\n ...body,\n unique: {\n '@type': 'Unique',\n id: prior?.id ?? DEFAULT_ID,\n ...(prior?.label !== undefined ? { label: prior.label } : {}),\n ...(by.length > 0 ? { by } : {}),\n countPrior: prior?.countPrior ?? DEFAULT_COUNT_PRIOR,\n attachments: prior?.attachments ?? true,\n ...(ai !== undefined ? { ai } : {}),\n thresholds: { rejectAtBps: state.rejectAtPct * 100, reviewAtBps: state.reviewAtPct * 100 },\n },\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { extractRubricFieldCatalog } from '@/core/lib/actionRegistry/actions/evalRubric/fieldCatalog';\nimport { validateRubricShape } from '@/core/lib/actionRegistry/actions/evalRubric/schemaGate';\nimport { parsePublishedRubric, type RubricBody } from '@/core/lib/actionRegistry/actions/evalRubric/types';\nimport { validateRubric, type RubricProblem } from '@/core/lib/actionRegistry/actions/evalRubric/validate';\nimport { useBlocknoteHandlers, type ClaimCollection } from '@/mantine/context/BlocknoteContext';\nimport { getCollectionDisplayName } from '../../collectionLabel';\nimport { bindForm, indexCatalog, listLinkedRules, listRules } from './ruleModel';\nimport { parseEvalRubricInputs, serializeEvalRubricInputs, type EvalRubricActionInputs } from './types';\n\n/**\n * The protocol DID a collection is linked to. The portal returns it as either a\n * bare DID string (`collection.protocol`) or the hydrated entity node\n * (`collection.protocol.id`) — read whichever is a non-empty string (§A.3). A\n * rubric is published as the `#rub` LinkedResource ON this protocol entity, so\n * an empty result means the rules have nothing to attach to.\n */\nfunction protocolDidOf(collection: ClaimCollection | undefined): string {\n const protocol = collection?.protocol as string | { id?: string } | null | undefined;\n const did = typeof protocol === 'string' ? protocol : protocol?.id;\n return String(did ?? '').trim();\n}\n\n/**\n * The claim form's resource FRAGMENT. The host may hand back the full resource\n * id (`did:…#vct` or `{id}#vct`); the engine's `ClaimSchemaBinding` locks\n * `resource` to the literal `\"#vct\"` (§A.3), so we keep only the `#…` fragment\n * and fall back to `#vct`, the convention every protocol follows.\n */\nfunction resourceFragment(resourceId: string | undefined): string {\n const raw = String(resourceId ?? '');\n const hash = raw.indexOf('#');\n return hash >= 0 ? raw.slice(hash) : '#vct';\n}\n\n/**\n * The builder's state — rubric-spec §B.3/§B.4.\n *\n * It owns four things and nothing else: the block's inputs, the claim form the\n * rules are written against, the problems with them, and the writes that change\n * them. The screen is left to render.\n *\n * Two rules it exists to keep:\n * - **The catalog is the ONLY source of questions** (§B.4). It is fetched from\n * the live form, stored in the block as `claimSchemaSnapshot`, and every\n * picker on the screen reads from it — so the author can only ever click on\n * things that exist, and `run()` re-checks the rules against the same\n * catalog before publishing.\n * - **Validation is the core's, on every change.** `validateRubric` is the one\n * judge of whether these rules are sound; this hook never second-guesses it.\n */\n\nexport interface RubricDraft {\n local: EvalRubricActionInputs;\n update: (patch: Partial<EvalRubricActionInputs>) => void;\n /** Write the rules. */\n setRubric: (next: RubricBody) => void;\n\n collections: ClaimCollection[];\n loadingCollections: boolean;\n collectionsError: string | null;\n fetchCollections: () => Promise<void>;\n pickCollection: (collectionId: string) => void;\n\n formLoading: boolean;\n formError: string | null;\n reloadForm: () => void;\n\n /**\n * The rules on screen were read from the rubric this collection ALREADY has\n * published on chain, not authored here. The designer says so: what the\n * author edits is what is live, and signing replaces it.\n *\n * There is no matching error flag, because there is no error to report:\n * `getDeedRubric` returns `null` for \"nothing published\" and for its own\n * failures alike, so a blank designer means \"nothing was loaded\", which is\n * all this can honestly claim.\n */\n prefilledFromChain: boolean;\n\n /** A check of these rules is in flight (debounce + round trip). */\n checking: boolean;\n /**\n * The last check could not RUN — no engine answer and no schema to fall back\n * on, so `diagnostics` carries only the local checks. Advisory for the\n * builder (editing continues), a hard gate for a caller that signs.\n */\n checkError: string | null;\n\n /**\n * Re-read the LIVE claim form and compare it with the stored authoring\n * snapshot, WITHOUT persisting anything. Opt-in: only a caller that is about\n * to publish needs it, and template-mode authoring must not pay for it.\n */\n checkFormDrift: () => Promise<void>;\n /** A drift check is in flight. */\n driftChecking: boolean;\n /**\n * The result of the last drift check: `null` = never run (so a caller that\n * signs must treat it as unchecked, not as clean). Every problem the rules\n * have against the form AS IT IS NOW, with `RUB_SCHEMA_DRIFT` for a question\n * that moved or vanished since authoring.\n */\n driftProblems: RubricProblem[] | null;\n /** The live form could not be re-read at all — never \"no drift\". */\n driftError: string | null;\n\n /** Every addressable answer on the form, by path. */\n index: ReturnType<typeof indexCatalog>;\n diagnostics: RubricProblem[];\n errors: RubricProblem[];\n /** Every rule, grown (compound-gate) rules included — derived, never stored. */\n rules: ReturnType<typeof listRules>;\n /** The linked rules (case tables) — recognised from their gates, never stored. */\n linked: ReturnType<typeof listLinkedRules>;\n}\n\n/** Let an edit settle before asking the engine — the check is a network round trip. */\nconst ENGINE_CHECK_DEBOUNCE_MS = 600;\n\n/** The one wording for \"nothing could check these rules\" — the run's preflight says the same. */\nexport const RULES_UNCHECKED_MESSAGE = 'Couldn’t reach the rules service to check your rules — try again.';\n\nexport function useRubricDraft(\n inputs: string,\n onInputsChange: (json: string) => void,\n opts?: {\n /**\n * The engine settings the author INTENDS to enrol with, forwarded on every engine check so the\n * engine can judge AI rules truthfully before the collection is enrolled (§ engine\n * previewRubric doc). Absent = the engine falls back to its stored row, which is why the one\n * caller today (`EvalEngineFlowDetail`) always passes them: it authors rules for a collection\n * that is not enrolled yet, so there is no stored row to fall back on.\n *\n * This object sits in the debounced engine-check effect's dependency array below: the CALLER\n * must pass a stable (memoized) reference, or a fresh object literal each render re-fires the\n * effect on every render, not just on every edit.\n */\n settings?: { allowAiChecks: boolean; allowImageChecks: boolean; allowChainEvaluation: boolean };\n }\n): RubricDraft {\n const handlers = useBlocknoteHandlers();\n // The engine check below is DEBOUNCED, so it must not re-run on handler\n // identity churn: a host that rebuilds its handler object each render would\n // reset the timer on every render and the check would never fire at all —\n // silently, since it fails soft. A flow-mode signing gate that waits for its\n // verdict would then never unlock. Same ref pattern as the two FlowDetails.\n const handlersRef = useRef(handlers);\n useEffect(() => {\n handlersRef.current = handlers;\n }, [handlers]);\n\n // Async work started by an explicit call (not by an effect with a cleanup) has\n // no other way to know the screen went away.\n const mountedRef = useRef(true);\n useEffect(\n () => () => {\n mountedRef.current = false;\n },\n []\n );\n\n const [local, setLocal] = useState<EvalRubricActionInputs>(() => parseEvalRubricInputs(inputs));\n\n // `local` mirrors `block.props.inputs` for immediate feedback, but the mirror\n // is only allowed to be REHYDRATED from a genuinely EXTERNAL change to\n // `inputs` — never from the echo of our own write. `lastWrittenRef` holds the\n // exact JSON we last emitted; when `inputs` comes back equal to it, the effect\n // skips, so a stale round-trip can never clobber a fresher local (the drift\n // that used to wipe rules on close/reopen). `localRef` is the source the async\n // loaders read, always the newest value.\n const localRef = useRef(local);\n const lastWrittenRef = useRef<string | null>(null);\n useEffect(() => {\n if (inputs === lastWrittenRef.current) return; // our own echo — already applied\n const parsed = parseEvalRubricInputs(inputs);\n localRef.current = parsed;\n setLocal(parsed);\n }, [inputs]);\n\n const update = useCallback(\n (patch: Partial<EvalRubricActionInputs>) => {\n const next = { ...localRef.current, ...patch };\n localRef.current = next;\n setLocal(next);\n const json = serializeEvalRubricInputs(next);\n lastWrittenRef.current = json;\n onInputsChange(json);\n },\n [onInputsChange]\n );\n\n const setRubric = useCallback((next: RubricBody) => update({ rubric: next }), [update]);\n\n // ── the collection ───────────────────────────────────────────────────────\n const [collections, setCollections] = useState<ClaimCollection[]>([]);\n const [loadingCollections, setLoadingCollections] = useState(false);\n const [collectionsError, setCollectionsError] = useState<string | null>(null);\n\n const fetchCollections = useCallback(async () => {\n const deedDid = localRef.current.deedDid.trim();\n if (!deedDid) {\n setCollectionsError('Please enter a DID first');\n return;\n }\n update({ deedDid });\n setLoadingCollections(true);\n setCollectionsError(null);\n try {\n const response = await handlers.getClaimCollections(deedDid);\n const fetched = response?.collections || [];\n setCollections(fetched);\n if (fetched.length === 0) setCollectionsError('No claim collections found for this DID');\n if (localRef.current.collectionId && !fetched.some((collection) => collection.id === localRef.current.collectionId)) {\n // The saved collection is no longer on this DID — clear the SELECTION,\n // but keep the rules the author wrote. Re-picking a collection re-binds\n // them (`bindForm`), so a transient reopen re-fetch never discards work.\n update({ collectionId: '' });\n }\n } catch (error) {\n setCollections([]);\n setCollectionsError(error instanceof Error ? error.message : 'Failed to fetch claim collections');\n } finally {\n setLoadingCollections(false);\n }\n }, [handlers, update]);\n\n // ── the claim form → the field catalog (§B.4) ─────────────────────────────\n const [formLoading, setFormLoading] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n const fetchGenRef = useRef(0);\n // Describes the ONE prefill attempt that happened (see `loadForm`), so it is\n // not reset by a later load that never re-attempts it — a reopen with rules\n // already in the block must not silently drop the banner explaining where\n // those rules came from.\n const [prefilledFromChain, setPrefilledFromChain] = useState(false);\n\n const loadForm = useCallback(\n async (deedDid: string, collectionId: string, collection?: ClaimCollection) => {\n if (!deedDid || !collectionId) return;\n const generation = ++fetchGenRef.current;\n setFormLoading(true);\n setFormError(null);\n try {\n const result = await handlers.getDeedSurveyTemplate(deedDid, collectionId);\n if (generation !== fetchGenRef.current) return; // a newer pick won\n const surveyTemplate = result?.surveyTemplate;\n if (!surveyTemplate) {\n setFormError('This collection has no claim form yet. Add the form first — the rules are written against its questions.');\n update({ claimSchemaSnapshot: null });\n return;\n }\n // The `#vct` proof pins which form these rules were written against\n // (§A.3). Hosts that resolve the form from its LinkedResource hand it\n // back; those that don't leave the pin blank, which stays valid.\n const catalog = extractRubricFieldCatalog(surveyTemplate, result?.proof ?? '');\n if (catalog.fields.length === 0) {\n setFormError('None of this form’s questions can be checked automatically. Rules need questions with answers — text, numbers, dates, choices, files.');\n }\n const title = collection ? getCollectionDisplayName(collection) : '';\n const resource = resourceFragment(result?.resourceId);\n const current = localRef.current.rubric;\n // A rubric attaches to the protocol entity carrying `#vct` (§A.2/§A.3):\n // keep any protocol the rules were already bound to, else take the\n // collection's. If neither resolves, refuse to mint an invalid binding —\n // the engine's ClaimSchemaBinding requires a non-empty protocol DID.\n const protocol = protocolDidOf(collection) || current?.claimSchema.protocol || '';\n if (!protocol) {\n setFormError(\"This collection isn't linked to a protocol yet — the rules can't attach. Link a protocol to the collection, then reopen.\");\n update({ claimSchemaSnapshot: catalog });\n return;\n }\n // ── Nothing authored here yet? Open on the rules ALREADY published for\n // this form, not on a blank sheet. Publishing REPLACES `#rub` (delete +\n // add in ONE transaction — x/iid has no update), so a blank sheet is not\n // a neutral starting point: it is how a live rulebook gets wiped by an\n // author who was never shown it. Read through the host's existing\n // `getDeedRubric` — blocksync → the protocol entity → its `#rub` → the\n // resolved document.\n //\n // A rubric belongs to the PROTOCOL, not to a collection (§A.2: it is\n // anchored on the entity carrying `#vct`, and every collection on that\n // protocol shares it), so the collection the host happened to route\n // through is irrelevant — `claimSchema.protocol` is what says whether\n // this document is the one that governs the form just loaded. Checking\n // it costs nothing and refuses the one case that would matter: a deed\n // whose collections span DIFFERENT protocols, where the host's pick\n // could return another protocol's rulebook.\n //\n // Only ever on the FIRST load of a block with no rubric: once `current`\n // exists — whether the author wrote it or a previous open prefilled it —\n // the chain is not consulted again, so this can never overwrite work.\n let base = current;\n if (!base && typeof handlers.getDeedRubric === 'function') {\n // Never fatal: `getDeedRubric` answers `null` for \"nothing published\"\n // AND for its own internal failures, so the worst case here is the\n // blank sheet this block opened on before — never a broken designer.\n const published = await handlers.getDeedRubric(deedDid).catch((error: unknown) => {\n console.warn('[eval.rubric] step prefill — could not read the published rules', error);\n return null;\n });\n if (generation !== fetchGenRef.current) return; // a newer pick won\n const candidate = parsePublishedRubric(published?.rubric);\n const boundTo = String(candidate?.claimSchema?.protocol || '');\n const fetched = candidate && boundTo === protocol ? candidate : null;\n // Re-read rather than trusting `current`: a rubric that landed while\n // the chain read was in flight OWNS the block. The prefill is only\n // ever allowed to fill an absence, never to win a race.\n base = localRef.current.rubric ?? fetched;\n setPrefilledFromChain(!localRef.current.rubric && !!fetched);\n console.info(\n '[eval.rubric] step prefill —',\n fetched\n ? `opened on the rules already published for protocol ${protocol}`\n : candidate\n ? `skipped: the published rules are bound to protocol ${boundTo}, not ${protocol}`\n : 'no rules published yet; starting fresh'\n );\n }\n\n update({\n claimSchemaSnapshot: catalog,\n // Keep the rules the author already wrote (or the published ones just\n // read); re-pin them to the form that is actually loaded. `bindForm`\n // NEVER replaces an existing rubric with a blank one — only fills the\n // binding — so reopening cannot wipe work.\n rubric: bindForm(base, protocol, resource, catalog.proof, title),\n });\n } catch (error) {\n if (generation !== fetchGenRef.current) return;\n setFormError(error instanceof Error ? error.message : 'Failed to load the claim form');\n } finally {\n if (generation === fetchGenRef.current) setFormLoading(false);\n }\n },\n [handlers, update]\n );\n\n const pickCollection = useCallback(\n (collectionId: string) => {\n const collection = collections.find((entry) => entry.id === collectionId);\n update({ collectionId });\n void loadForm(localRef.current.deedDid.trim(), collectionId, collection);\n },\n [collections, loadForm, update]\n );\n\n const reloadForm = useCallback(() => {\n const collection = collections.find((entry) => entry.id === localRef.current.collectionId);\n void loadForm(localRef.current.deedDid.trim(), localRef.current.collectionId, collection);\n }, [collections, loadForm]);\n\n // Re-open with a collection already chosen: show its list, and its form.\n useEffect(() => {\n if (local.deedDid.trim() && local.collectionId && collections.length === 0 && !loadingCollections) void fetchCollections();\n }, [local.deedDid, local.collectionId]);\n\n useEffect(() => {\n if (!local.deedDid.trim() || !local.collectionId || local.claimSchemaSnapshot || formLoading) return;\n const collection = collections.find((entry) => entry.id === local.collectionId);\n // WAIT for the collection object. This effect and the fetch above run in the\n // SAME commit, so on a reopen `collections` is still empty here — and without\n // the collection `loadForm` resolves no protocol DID for the rules to attach\n // to, which it can only report as \"this collection isn't linked to a protocol\n // yet\": untrue, and recoverable only through a manual retry. Rules that\n // already carry a protocol have nothing to wait for. A collection that never\n // arrives surfaces as `collectionsError`, which is the honest message.\n //\n // The protocol is read through `localRef`, NOT from `local.rubric` as a\n // dependency: a caller whose write echoes back (the merged-blob writer in\n // `EvalEngineFlowDetail`) hands this hook a fresh `rubric` OBJECT on every\n // rehydrate, so depending on it would re-fire this effect after each write —\n // and on a form that fails to load, `loadForm` writes `claimSchemaSnapshot:\n // null`, which would make that an endless fetch loop.\n if (!collection && !localRef.current.rubric?.claimSchema.protocol) return;\n void loadForm(local.deedDid.trim(), local.collectionId, collection);\n }, [local.deedDid, local.collectionId, local.claimSchemaSnapshot, collections]);\n\n // ── Drift: the rules against the form AS IT IS NOW (§B.6) ─────────────────\n // The stored snapshot is the AUTHORING baseline and stays exactly that: this\n // reads the live form, compares, and persists NOTHING. That is the whole point\n // of keeping both — `validateRubric`'s third argument is what turns \"this rule\n // points at nothing\" into \"the form changed since these rules were written\",\n // two different problems with two different fixes. Overwriting the snapshot\n // with the live catalog (which `reloadForm` does, correctly, for authoring)\n // would destroy the comparison and, in flow mode, write the block's inputs on\n // open — reading is not editing.\n const [driftChecking, setDriftChecking] = useState(false);\n const [driftProblems, setDriftProblems] = useState<RubricProblem[] | null>(null);\n const [driftError, setDriftError] = useState<string | null>(null);\n const checkFormDrift = useCallback(async () => {\n const { deedDid, collectionId, rubric, claimSchemaSnapshot } = localRef.current;\n const entity = deedDid.trim();\n // Nothing authored, or nothing to author against: the caller's own gates\n // (no rules / no form) already cover this, and a \"clean\" verdict here would\n // be a lie about a check that never happened.\n if (!entity || !collectionId || !rubric || !claimSchemaSnapshot) return;\n setDriftChecking(true);\n setDriftError(null);\n try {\n const result = await handlersRef.current.getDeedSurveyTemplate(entity, collectionId);\n if (!mountedRef.current) return;\n const surveyTemplate = result?.surveyTemplate;\n if (!surveyTemplate) {\n setDriftProblems(null);\n setDriftError('This collection has no claim form any more, so these rules have nothing to judge.');\n return;\n }\n // The LIVE form's own pin when the host names it — it describes this\n // catalog, not the one the rules were authored against. A moved pin alone\n // is NOT drift: rewording a title changes the proof without touching a\n // single question a rule depends on.\n const live = extractRubricFieldCatalog(surveyTemplate, result?.proof ?? claimSchemaSnapshot.proof);\n // ONLY the drift findings survive. This run is a one-shot per mount, so\n // anything else it kept would go STALE: a rubric-content error captured\n // here (against the rubric as it was at mount) outlives the edit that\n // fixes it and holds the signing gate shut forever. Rubric-content\n // problems are `diagnostics`' job, recomputed on every change against the\n // authoring snapshot; drift is the one finding only this comparison can\n // make (§B.6).\n setDriftProblems(validateRubric(rubric, live, claimSchemaSnapshot).filter((d) => d.code === 'RUB_SCHEMA_DRIFT'));\n } catch (error) {\n if (!mountedRef.current) return;\n setDriftProblems(null);\n setDriftError(error instanceof Error ? error.message : 'Could not check these rules against the claim form');\n } finally {\n if (mountedRef.current) setDriftChecking(false);\n }\n }, []);\n\n // ── Shape backstop against the engine's served schema (§A.12) ─────────────\n // The publish path (run() + FlowDetail) hard-gates on this; here it is a live\n // heads-up that catches a shape the engine would reject while the author is\n // still editing. The schema is fetched once per session and cached. Fail SOFT:\n // if the rules service is unreachable during authoring we surface nothing\n // (publish is the hard gate), so a flaky engine never blocks editing.\n const [shapeProblems, setShapeProblems] = useState<{ code: string; severity: 'error' | 'warning'; path: string; message: string }[]>([]);\n // Two facts about the check itself, distinct from its findings: whether one is\n // in flight, and whether the last one could not RUN at all (no engine answer\n // AND no schema to fall back on, so `shapeProblems` is empty for lack of a\n // judge rather than for lack of problems).\n //\n // Reported, never thrown, because ONE caller wears both hats: the designer half\n // of `EvalEngineFlowDetail` has to stay editable while the rules service is down,\n // and its signing half has to fail closed on exactly the same fact — an empty\n // problem list from a check that never happened reads exactly like a clean one.\n // Only the caller can know which of the two it is doing. `checking` starts true\n // when there is already something to check, so a consumer reading it during the\n // first render awaits the verdict instead of assuming one.\n const [checking, setChecking] = useState(() => !!local.rubric && !!local.claimSchemaSnapshot);\n const [checkError, setCheckError] = useState<string | null>(null);\n useEffect(() => {\n let mounted = true;\n const body = local.rubric;\n if (!body || !local.claimSchemaSnapshot) {\n setShapeProblems([]);\n setChecking(false);\n setCheckError(null);\n return;\n }\n setChecking(true);\n // Debounced: this runs on EVERY edit, and the engine check is a network round trip (unlike the\n // local Ajv gate it replaces). Settle first, then ask once.\n const timer = setTimeout(() => {\n void (async () => {\n const host = handlersRef.current;\n try {\n const engineUrl = local.evalEngineUrl.trim() || undefined;\n // Prefer the ENGINE's answer: it also checks this collection's settings, which is the only\n // way the author sees \"these AI rules can't run — AI checks are off for this collection\"\n // while still editing.\n //\n // Silent FIRST so an already-unlocked session never sees a modal; only if that comes back\n // null (no cached signer yet) do we ask interactively. `getOrCreateSigner` caches the\n // signer, so that costs ONE PIN prompt per session and every later edit is silent again.\n if (host.previewRubric && local.collectionId) {\n const ask = (interactive: boolean) =>\n host\n .previewRubric?.({\n collectionId: local.collectionId,\n rubric: body,\n evalEngineUrl: engineUrl,\n interactive,\n ...(opts?.settings ? { settings: opts.settings } : {}),\n })\n .catch((error) => {\n console.warn('[eval.rubric] engine check failed; using the local shape gate', error);\n return null;\n }) ?? Promise.resolve(null);\n\n let preview = await ask(false);\n if (!mounted) return;\n if (!preview) {\n console.info('[eval.rubric] no cached signer — asking for the pin once so rules can be checked');\n preview = await ask(true);\n if (!mounted) return;\n }\n if (preview) {\n setShapeProblems(preview.problems);\n setCheckError(null);\n return;\n }\n console.info('[eval.rubric] engine check unavailable; using the local shape gate');\n } else if (!host.previewRubric) {\n console.info('[eval.rubric] host has no previewRubric handler; using the local shape gate');\n }\n const shape = await validateRubricShape(body, host.getRubricSchema, engineUrl);\n if (!mounted) return;\n // `ok: false` is \"could not check\", NOT \"nothing wrong\": no engine answer\n // and no schema to fall back on. Report it rather than publishing an\n // empty problem list that reads like a clean bill of health.\n if (shape.ok) {\n setShapeProblems(shape.problems);\n setCheckError(null);\n } else {\n console.warn('[eval.rubric] the rules could not be checked at all', shape.reason);\n setShapeProblems([]);\n setCheckError(RULES_UNCHECKED_MESSAGE);\n }\n } catch (error) {\n // Anything that escaped the per-call catches above — a host whose\n // `previewRubric` throws SYNCHRONOUSLY never gets a `.catch` attached, and\n // the rejection would otherwise leave the previous verdict standing while\n // nothing had actually been checked. Not checked is not clean.\n console.warn('[eval.rubric] the rules check threw', error);\n if (mounted) {\n setShapeProblems([]);\n setCheckError(RULES_UNCHECKED_MESSAGE);\n }\n } finally {\n // A superseded run must not clear the newer run's flag — it owns its own.\n if (mounted) setChecking(false);\n }\n })();\n }, ENGINE_CHECK_DEBOUNCE_MS);\n return () => {\n mounted = false;\n clearTimeout(timer);\n };\n // `handlers` is deliberately NOT a dependency — see `handlersRef` above.\n }, [local.rubric, local.claimSchemaSnapshot, local.collectionId, local.evalEngineUrl, opts?.settings]);\n\n // ── what the screen reads ────────────────────────────────────────────────\n const index = useMemo(() => indexCatalog(local.claimSchemaSnapshot), [local.claimSchemaSnapshot]);\n const rules = useMemo(() => listRules(local.rubric), [local.rubric]);\n const linked = useMemo(() => listLinkedRules(local.rubric), [local.rubric]);\n const diagnostics = useMemo(\n () => (local.rubric && local.claimSchemaSnapshot ? [...validateRubric(local.rubric, local.claimSchemaSnapshot), ...shapeProblems] : []),\n [local.rubric, local.claimSchemaSnapshot, shapeProblems]\n );\n const errors = useMemo(() => diagnostics.filter((diagnostic) => diagnostic.severity === 'error'), [diagnostics]);\n\n return {\n local,\n update,\n setRubric,\n collections,\n loadingCollections,\n collectionsError,\n fetchCollections,\n pickCollection,\n formLoading,\n formError,\n reloadForm,\n prefilledFromChain,\n checking,\n checkError,\n checkFormDrift,\n driftChecking,\n driftProblems,\n driftError,\n index,\n diagnostics,\n errors,\n rules,\n linked,\n };\n}\n"],"mappings":"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","names":["React","useCallback","useEffect","useMemo","useRef","useState","ActionIcon","Alert","Badge","Box","Button","Group","Loader","Paper","Stack","Text","IconAlertTriangle","IconCheck","IconTrash","React","Button","Group","Stack","gate","index","when","EXT_REF","AI_REF","parts","React","React","Stack","Group","Button","React","useMemo","useState","Button","Group","Paper","ScrollArea","Stack","Text","React","Group","SegmentedControl","Stack","Text","React","Group","Text","Stack","SegmentedControl","name","sendField","fieldTitle","gates","useState","useMemo","React","ScrollArea","Stack","Group","Text","Paper","Button","React","ActionIcon","Alert","Box","Button","Group","Paper","Stack","Text","IconAlertTriangle","IconPlus","IconTrash","React","Paper","Stack","Group","Text","Box","ActionIcon","IconTrash","Alert","IconAlertTriangle","Button","IconPlus","React","useMemo","useState","ActionIcon","Alert","Box","Button","Divider","Group","Modal","Paper","ScrollArea","Stack","Text","IconAlertTriangle","IconPlus","IconRobot","IconTrash","IconWorld","IconX","React","ActionIcon","Button","Group","Paper","Stack","Text","IconPlus","IconRobot","removeRule","React","Paper","Stack","Group","IconRobot","Text","ActionIcon","Button","IconPlus","React","useMemo","Group","Text","useMemo","React","Group","Text","React","useState","Alert","Box","Button","Code","Group","Paper","SegmentedControl","Stack","Text","IconAlertTriangle","useState","React","Paper","Stack","Group","Text","Button","SegmentedControl","Box","Alert","IconAlertTriangle","Code","React","useEffect","useState","ActionIcon","Group","Loader","Paper","SegmentedControl","Stack","TagsInput","Text","IconBan","IconX","IconBan","React","Stack","TagsInput","Text","Group","SegmentedControl","useState","useEffect","Loader","Paper","ActionIcon","IconX","useState","useMemo","React","Modal","ScrollArea","Stack","Text","Button","Divider","Paper","Group","Box","IconRobot","ActionIcon","IconTrash","IconPlus","IconWorld","IconX","Alert","IconAlertTriangle","React","useEffect","useRef","useState","Group","Paper","SegmentedControl","Stack","Text","useState","useRef","useEffect","React","Paper","Stack","Group","Text","SegmentedControl","React","useEffect","useMemo","useRef","useState","Alert","Group","Paper","Stack","Switch","Text","DEFAULT_ID","unique","useState","useRef","useEffect","useMemo","React","Paper","Stack","Group","Text","Switch","Alert","useEffect","useMemo","useRef","useState","useRef","useEffect","useState","useMemo","useRef","useEffect","useMemo","useState","useCallback","React","Stack","Text","Alert","Group","Loader","Paper","Box","ActionIcon","IconTrash","IconAlertTriangle","IconCheck","Button","Badge"]}