@agentsgot/agent-kit 0.0.0-stage → 1.0.1

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 (411) hide show
  1. package/ARCHITECTURE.md +5 -0
  2. package/README.md +13 -2
  3. package/dist/a2a.d.ts +35 -0
  4. package/dist/a2a.d.ts.map +1 -0
  5. package/dist/a2a.js +109 -0
  6. package/dist/a2a.js.map +1 -0
  7. package/dist/cli/binding.d.ts +24 -0
  8. package/dist/cli/binding.d.ts.map +1 -0
  9. package/dist/cli/binding.js +52 -0
  10. package/dist/cli/binding.js.map +1 -0
  11. package/dist/cli/commands.d.ts +18 -0
  12. package/dist/cli/commands.d.ts.map +1 -0
  13. package/dist/cli/commands.js +191 -0
  14. package/dist/cli/commands.js.map +1 -0
  15. package/dist/cli/context.d.ts +61 -0
  16. package/dist/cli/context.d.ts.map +1 -0
  17. package/dist/cli/context.js +147 -0
  18. package/dist/cli/context.js.map +1 -0
  19. package/dist/cli/doctor.d.ts +34 -0
  20. package/dist/cli/doctor.d.ts.map +1 -0
  21. package/dist/cli/doctor.js +109 -0
  22. package/dist/cli/doctor.js.map +1 -0
  23. package/dist/cli/home.d.ts +37 -0
  24. package/dist/cli/home.d.ts.map +1 -0
  25. package/dist/cli/home.js +77 -0
  26. package/dist/cli/home.js.map +1 -0
  27. package/dist/cli/index.d.ts +5 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +120 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/cli/install.d.ts +19 -0
  32. package/dist/cli/install.d.ts.map +1 -0
  33. package/dist/cli/install.js +64 -0
  34. package/dist/cli/install.js.map +1 -0
  35. package/dist/cli/keystore.d.ts +25 -0
  36. package/dist/cli/keystore.d.ts.map +1 -0
  37. package/dist/cli/keystore.js +57 -0
  38. package/dist/cli/keystore.js.map +1 -0
  39. package/dist/cli/mcp.d.ts +7 -0
  40. package/dist/cli/mcp.d.ts.map +1 -0
  41. package/dist/cli/mcp.js +28 -0
  42. package/dist/cli/mcp.js.map +1 -0
  43. package/dist/cli/prompt.d.ts +10 -0
  44. package/dist/cli/prompt.d.ts.map +1 -0
  45. package/dist/cli/prompt.js +71 -0
  46. package/dist/cli/prompt.js.map +1 -0
  47. package/dist/cli/reports.d.ts +42 -0
  48. package/dist/cli/reports.d.ts.map +1 -0
  49. package/dist/cli/reports.js +121 -0
  50. package/dist/cli/reports.js.map +1 -0
  51. package/dist/cli/run.d.ts +21 -0
  52. package/dist/cli/run.d.ts.map +1 -0
  53. package/dist/cli/run.js +125 -0
  54. package/dist/cli/run.js.map +1 -0
  55. package/dist/cli/wallet.d.ts +19 -0
  56. package/dist/cli/wallet.d.ts.map +1 -0
  57. package/dist/cli/wallet.js +58 -0
  58. package/dist/cli/wallet.js.map +1 -0
  59. package/dist/guides.d.ts +7 -0
  60. package/dist/guides.d.ts.map +1 -0
  61. package/dist/guides.js +94 -0
  62. package/dist/guides.js.map +1 -0
  63. package/dist/index.d.ts +20 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +23 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/llm.d.ts +16 -0
  68. package/dist/llm.d.ts.map +1 -0
  69. package/dist/llm.js +30 -0
  70. package/dist/llm.js.map +1 -0
  71. package/dist/mcp/cli.d.ts +3 -0
  72. package/dist/mcp/cli.d.ts.map +1 -0
  73. package/dist/mcp/cli.js +6 -0
  74. package/dist/mcp/cli.js.map +1 -0
  75. package/dist/mcp/server.d.ts +38 -0
  76. package/dist/mcp/server.d.ts.map +1 -0
  77. package/dist/mcp/server.js +693 -0
  78. package/dist/mcp/server.js.map +1 -0
  79. package/dist/ports.d.ts +123 -0
  80. package/dist/ports.d.ts.map +1 -0
  81. package/dist/ports.js +134 -0
  82. package/dist/ports.js.map +1 -0
  83. package/dist/roles.d.ts +16 -0
  84. package/dist/roles.d.ts.map +1 -0
  85. package/dist/roles.js +49 -0
  86. package/dist/roles.js.map +1 -0
  87. package/dist/runner.d.ts +126 -0
  88. package/dist/runner.d.ts.map +1 -0
  89. package/dist/runner.js +292 -0
  90. package/dist/runner.js.map +1 -0
  91. package/dist/schedules.d.ts +34 -0
  92. package/dist/schedules.d.ts.map +1 -0
  93. package/dist/schedules.js +116 -0
  94. package/dist/schedules.js.map +1 -0
  95. package/dist/sdk/base64.d.ts +4 -0
  96. package/dist/sdk/base64.d.ts.map +1 -0
  97. package/dist/sdk/base64.js +15 -0
  98. package/dist/sdk/base64.js.map +1 -0
  99. package/dist/sdk/client.d.ts +198 -0
  100. package/dist/sdk/client.d.ts.map +1 -0
  101. package/dist/sdk/client.js +413 -0
  102. package/dist/sdk/client.js.map +1 -0
  103. package/dist/security.d.ts +10 -0
  104. package/dist/security.d.ts.map +1 -0
  105. package/dist/security.js +24 -0
  106. package/dist/security.js.map +1 -0
  107. package/dist/skills.d.ts +21 -0
  108. package/dist/skills.d.ts.map +1 -0
  109. package/dist/skills.js +93 -0
  110. package/dist/skills.js.map +1 -0
  111. package/dist/workers.d.ts +64 -0
  112. package/dist/workers.d.ts.map +1 -0
  113. package/dist/workers.js +127 -0
  114. package/dist/workers.js.map +1 -0
  115. package/dist/zip.d.ts +8 -0
  116. package/dist/zip.d.ts.map +1 -0
  117. package/dist/zip.js +80 -0
  118. package/dist/zip.js.map +1 -0
  119. package/docs/README.md +25 -0
  120. package/docs/architecture.md +18 -0
  121. package/docs/deployment.md +35 -0
  122. package/docs/reference/01-RULES.md +822 -0
  123. package/docs/reference/02-INTERFACES.md +487 -0
  124. package/docs/reference/03-STAKING-PENALTY-SPEC.md +739 -0
  125. package/docs/updates.md +65 -0
  126. package/docs/verification.md +72 -0
  127. package/package.json +88 -4
  128. package/skills/dist/agent-skills.json +68 -0
  129. package/skills/dist/arbitrator/SKILL.md +186 -0
  130. package/skills/dist/executor/SKILL.md +219 -0
  131. package/skills/dist/publisher/SKILL.md +172 -0
  132. package/skills/dist/tester/SKILL.md +198 -0
  133. package/vendor/shared/ARCHITECTURE.md +97 -0
  134. package/vendor/shared/README.md +5 -0
  135. package/vendor/shared/abi/index.js +2 -0
  136. package/vendor/shared/abi/index.ts +2 -0
  137. package/vendor/shared/abi/protocol/AgentRegistry.js +1623 -0
  138. package/vendor/shared/abi/protocol/AgentRegistry.json +1623 -0
  139. package/vendor/shared/abi/protocol/AgentRegistry.ts +1623 -0
  140. package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.js +154 -0
  141. package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.json +154 -0
  142. package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.ts +154 -0
  143. package/vendor/shared/abi/protocol/ArbitrationCourt.js +1550 -0
  144. package/vendor/shared/abi/protocol/ArbitrationCourt.json +1550 -0
  145. package/vendor/shared/abi/protocol/ArbitrationCourt.ts +1550 -0
  146. package/vendor/shared/abi/protocol/ArbitrationPool.js +509 -0
  147. package/vendor/shared/abi/protocol/ArbitrationPool.json +509 -0
  148. package/vendor/shared/abi/protocol/ArbitrationPool.ts +509 -0
  149. package/vendor/shared/abi/protocol/ArbitrationProgressor.js +44 -0
  150. package/vendor/shared/abi/protocol/ArbitrationProgressor.json +44 -0
  151. package/vendor/shared/abi/protocol/ArbitrationProgressor.ts +44 -0
  152. package/vendor/shared/abi/protocol/ArbitrationSelection.js +1153 -0
  153. package/vendor/shared/abi/protocol/ArbitrationSelection.json +1153 -0
  154. package/vendor/shared/abi/protocol/ArbitrationSelection.ts +1153 -0
  155. package/vendor/shared/abi/protocol/ArbitrationSettlement.js +956 -0
  156. package/vendor/shared/abi/protocol/ArbitrationSettlement.json +956 -0
  157. package/vendor/shared/abi/protocol/ArbitrationSettlement.ts +956 -0
  158. package/vendor/shared/abi/protocol/ArbitrationStream.js +964 -0
  159. package/vendor/shared/abi/protocol/ArbitrationStream.json +964 -0
  160. package/vendor/shared/abi/protocol/ArbitrationStream.ts +964 -0
  161. package/vendor/shared/abi/protocol/EmissionController.js +1436 -0
  162. package/vendor/shared/abi/protocol/EmissionController.json +1436 -0
  163. package/vendor/shared/abi/protocol/EmissionController.ts +1436 -0
  164. package/vendor/shared/abi/protocol/HourlyAnchor.js +611 -0
  165. package/vendor/shared/abi/protocol/HourlyAnchor.json +611 -0
  166. package/vendor/shared/abi/protocol/HourlyAnchor.ts +611 -0
  167. package/vendor/shared/abi/protocol/IncentiveVault.js +480 -0
  168. package/vendor/shared/abi/protocol/IncentiveVault.json +480 -0
  169. package/vendor/shared/abi/protocol/IncentiveVault.ts +480 -0
  170. package/vendor/shared/abi/protocol/ParamRegistry.js +814 -0
  171. package/vendor/shared/abi/protocol/ParamRegistry.json +814 -0
  172. package/vendor/shared/abi/protocol/ParamRegistry.ts +814 -0
  173. package/vendor/shared/abi/protocol/PlatformTreasury.js +553 -0
  174. package/vendor/shared/abi/protocol/PlatformTreasury.json +553 -0
  175. package/vendor/shared/abi/protocol/PlatformTreasury.ts +553 -0
  176. package/vendor/shared/abi/protocol/ProtocolProof.js +1171 -0
  177. package/vendor/shared/abi/protocol/ProtocolProof.json +1171 -0
  178. package/vendor/shared/abi/protocol/ProtocolProof.ts +1171 -0
  179. package/vendor/shared/abi/protocol/PublisherStaking.js +1227 -0
  180. package/vendor/shared/abi/protocol/PublisherStaking.json +1227 -0
  181. package/vendor/shared/abi/protocol/PublisherStaking.ts +1227 -0
  182. package/vendor/shared/abi/protocol/RewardVesting.js +1027 -0
  183. package/vendor/shared/abi/protocol/RewardVesting.json +1027 -0
  184. package/vendor/shared/abi/protocol/RewardVesting.ts +1027 -0
  185. package/vendor/shared/abi/protocol/TaskEscrow.js +2219 -0
  186. package/vendor/shared/abi/protocol/TaskEscrow.json +2219 -0
  187. package/vendor/shared/abi/protocol/TaskEscrow.ts +2219 -0
  188. package/vendor/shared/abi/protocol/TesterAssignment.js +1375 -0
  189. package/vendor/shared/abi/protocol/TesterAssignment.json +1375 -0
  190. package/vendor/shared/abi/protocol/TesterAssignment.ts +1375 -0
  191. package/vendor/shared/abi/protocol/ValidatorStaking.js +1614 -0
  192. package/vendor/shared/abi/protocol/ValidatorStaking.json +1614 -0
  193. package/vendor/shared/abi/protocol/ValidatorStaking.ts +1614 -0
  194. package/vendor/shared/abi/protocol/index.js +19 -0
  195. package/vendor/shared/abi/protocol/index.ts +19 -0
  196. package/vendor/shared/abi/token/AGTToken.js +1018 -0
  197. package/vendor/shared/abi/token/AGTToken.json +1018 -0
  198. package/vendor/shared/abi/token/AGTToken.ts +1018 -0
  199. package/vendor/shared/abi/token/GenesisDistributor.js +242 -0
  200. package/vendor/shared/abi/token/GenesisDistributor.json +242 -0
  201. package/vendor/shared/abi/token/GenesisDistributor.ts +242 -0
  202. package/vendor/shared/abi/token/LPLocker.js +21 -0
  203. package/vendor/shared/abi/token/LPLocker.json +21 -0
  204. package/vendor/shared/abi/token/LPLocker.ts +21 -0
  205. package/vendor/shared/abi/token/LaunchLiquidity.js +335 -0
  206. package/vendor/shared/abi/token/LaunchLiquidity.json +335 -0
  207. package/vendor/shared/abi/token/LaunchLiquidity.ts +335 -0
  208. package/vendor/shared/abi/token/LiquidityAdder.js +228 -0
  209. package/vendor/shared/abi/token/LiquidityAdder.json +228 -0
  210. package/vendor/shared/abi/token/LiquidityAdder.ts +228 -0
  211. package/vendor/shared/abi/token/TaxDistributor.js +235 -0
  212. package/vendor/shared/abi/token/TaxDistributor.json +235 -0
  213. package/vendor/shared/abi/token/TaxDistributor.ts +235 -0
  214. package/vendor/shared/abi/token/TestFaucet.js +214 -0
  215. package/vendor/shared/abi/token/TestFaucet.json +214 -0
  216. package/vendor/shared/abi/token/TestFaucet.ts +214 -0
  217. package/vendor/shared/abi/token/index.js +7 -0
  218. package/vendor/shared/abi/token/index.ts +7 -0
  219. package/vendor/shared/dist/abi/index.d.ts +3 -0
  220. package/vendor/shared/dist/abi/index.d.ts.map +1 -0
  221. package/vendor/shared/dist/abi/index.js +3 -0
  222. package/vendor/shared/dist/abi/index.js.map +1 -0
  223. package/vendor/shared/dist/abi/protocol/AgentRegistry.d.ts +1249 -0
  224. package/vendor/shared/dist/abi/protocol/AgentRegistry.d.ts.map +1 -0
  225. package/vendor/shared/dist/abi/protocol/AgentRegistry.js +1624 -0
  226. package/vendor/shared/dist/abi/protocol/AgentRegistry.js.map +1 -0
  227. package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.d.ts +119 -0
  228. package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.d.ts.map +1 -0
  229. package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.js +155 -0
  230. package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.js.map +1 -0
  231. package/vendor/shared/dist/abi/protocol/ArbitrationCourt.d.ts +1205 -0
  232. package/vendor/shared/dist/abi/protocol/ArbitrationCourt.d.ts.map +1 -0
  233. package/vendor/shared/dist/abi/protocol/ArbitrationCourt.js +1551 -0
  234. package/vendor/shared/dist/abi/protocol/ArbitrationCourt.js.map +1 -0
  235. package/vendor/shared/dist/abi/protocol/ArbitrationPool.d.ts +391 -0
  236. package/vendor/shared/dist/abi/protocol/ArbitrationPool.d.ts.map +1 -0
  237. package/vendor/shared/dist/abi/protocol/ArbitrationPool.js +510 -0
  238. package/vendor/shared/dist/abi/protocol/ArbitrationPool.js.map +1 -0
  239. package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.d.ts +34 -0
  240. package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.d.ts.map +1 -0
  241. package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.js +45 -0
  242. package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.js.map +1 -0
  243. package/vendor/shared/dist/abi/protocol/ArbitrationSelection.d.ts +885 -0
  244. package/vendor/shared/dist/abi/protocol/ArbitrationSelection.d.ts.map +1 -0
  245. package/vendor/shared/dist/abi/protocol/ArbitrationSelection.js +1154 -0
  246. package/vendor/shared/dist/abi/protocol/ArbitrationSelection.js.map +1 -0
  247. package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.d.ts +742 -0
  248. package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.d.ts.map +1 -0
  249. package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.js +957 -0
  250. package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.js.map +1 -0
  251. package/vendor/shared/dist/abi/protocol/ArbitrationStream.d.ts +741 -0
  252. package/vendor/shared/dist/abi/protocol/ArbitrationStream.d.ts.map +1 -0
  253. package/vendor/shared/dist/abi/protocol/ArbitrationStream.js +965 -0
  254. package/vendor/shared/dist/abi/protocol/ArbitrationStream.js.map +1 -0
  255. package/vendor/shared/dist/abi/protocol/EmissionController.d.ts +1110 -0
  256. package/vendor/shared/dist/abi/protocol/EmissionController.d.ts.map +1 -0
  257. package/vendor/shared/dist/abi/protocol/EmissionController.js +1437 -0
  258. package/vendor/shared/dist/abi/protocol/EmissionController.js.map +1 -0
  259. package/vendor/shared/dist/abi/protocol/HourlyAnchor.d.ts +467 -0
  260. package/vendor/shared/dist/abi/protocol/HourlyAnchor.d.ts.map +1 -0
  261. package/vendor/shared/dist/abi/protocol/HourlyAnchor.js +612 -0
  262. package/vendor/shared/dist/abi/protocol/HourlyAnchor.js.map +1 -0
  263. package/vendor/shared/dist/abi/protocol/IncentiveVault.d.ts +369 -0
  264. package/vendor/shared/dist/abi/protocol/IncentiveVault.d.ts.map +1 -0
  265. package/vendor/shared/dist/abi/protocol/IncentiveVault.js +481 -0
  266. package/vendor/shared/dist/abi/protocol/IncentiveVault.js.map +1 -0
  267. package/vendor/shared/dist/abi/protocol/ParamRegistry.d.ts +628 -0
  268. package/vendor/shared/dist/abi/protocol/ParamRegistry.d.ts.map +1 -0
  269. package/vendor/shared/dist/abi/protocol/ParamRegistry.js +815 -0
  270. package/vendor/shared/dist/abi/protocol/ParamRegistry.js.map +1 -0
  271. package/vendor/shared/dist/abi/protocol/PlatformTreasury.d.ts +426 -0
  272. package/vendor/shared/dist/abi/protocol/PlatformTreasury.d.ts.map +1 -0
  273. package/vendor/shared/dist/abi/protocol/PlatformTreasury.js +554 -0
  274. package/vendor/shared/dist/abi/protocol/PlatformTreasury.js.map +1 -0
  275. package/vendor/shared/dist/abi/protocol/ProtocolProof.d.ts +903 -0
  276. package/vendor/shared/dist/abi/protocol/ProtocolProof.d.ts.map +1 -0
  277. package/vendor/shared/dist/abi/protocol/ProtocolProof.js +1172 -0
  278. package/vendor/shared/dist/abi/protocol/ProtocolProof.js.map +1 -0
  279. package/vendor/shared/dist/abi/protocol/PublisherStaking.d.ts +947 -0
  280. package/vendor/shared/dist/abi/protocol/PublisherStaking.d.ts.map +1 -0
  281. package/vendor/shared/dist/abi/protocol/PublisherStaking.js +1228 -0
  282. package/vendor/shared/dist/abi/protocol/PublisherStaking.js.map +1 -0
  283. package/vendor/shared/dist/abi/protocol/RewardVesting.d.ts +793 -0
  284. package/vendor/shared/dist/abi/protocol/RewardVesting.d.ts.map +1 -0
  285. package/vendor/shared/dist/abi/protocol/RewardVesting.js +1028 -0
  286. package/vendor/shared/dist/abi/protocol/RewardVesting.js.map +1 -0
  287. package/vendor/shared/dist/abi/protocol/TaskEscrow.d.ts +1725 -0
  288. package/vendor/shared/dist/abi/protocol/TaskEscrow.d.ts.map +1 -0
  289. package/vendor/shared/dist/abi/protocol/TaskEscrow.js +2220 -0
  290. package/vendor/shared/dist/abi/protocol/TaskEscrow.js.map +1 -0
  291. package/vendor/shared/dist/abi/protocol/TesterAssignment.d.ts +1058 -0
  292. package/vendor/shared/dist/abi/protocol/TesterAssignment.d.ts.map +1 -0
  293. package/vendor/shared/dist/abi/protocol/TesterAssignment.js +1376 -0
  294. package/vendor/shared/dist/abi/protocol/TesterAssignment.js.map +1 -0
  295. package/vendor/shared/dist/abi/protocol/ValidatorStaking.d.ts +1236 -0
  296. package/vendor/shared/dist/abi/protocol/ValidatorStaking.d.ts.map +1 -0
  297. package/vendor/shared/dist/abi/protocol/ValidatorStaking.js +1615 -0
  298. package/vendor/shared/dist/abi/protocol/ValidatorStaking.js.map +1 -0
  299. package/vendor/shared/dist/abi/protocol/index.d.ts +20 -0
  300. package/vendor/shared/dist/abi/protocol/index.d.ts.map +1 -0
  301. package/vendor/shared/dist/abi/protocol/index.js +20 -0
  302. package/vendor/shared/dist/abi/protocol/index.js.map +1 -0
  303. package/vendor/shared/dist/abi/token/AGTToken.d.ts +786 -0
  304. package/vendor/shared/dist/abi/token/AGTToken.d.ts.map +1 -0
  305. package/vendor/shared/dist/abi/token/AGTToken.js +1019 -0
  306. package/vendor/shared/dist/abi/token/AGTToken.js.map +1 -0
  307. package/vendor/shared/dist/abi/token/GenesisDistributor.d.ts +187 -0
  308. package/vendor/shared/dist/abi/token/GenesisDistributor.d.ts.map +1 -0
  309. package/vendor/shared/dist/abi/token/GenesisDistributor.js +243 -0
  310. package/vendor/shared/dist/abi/token/GenesisDistributor.js.map +1 -0
  311. package/vendor/shared/dist/abi/token/LPLocker.d.ts +16 -0
  312. package/vendor/shared/dist/abi/token/LPLocker.d.ts.map +1 -0
  313. package/vendor/shared/dist/abi/token/LPLocker.js +22 -0
  314. package/vendor/shared/dist/abi/token/LPLocker.js.map +1 -0
  315. package/vendor/shared/dist/abi/token/LaunchLiquidity.d.ts +260 -0
  316. package/vendor/shared/dist/abi/token/LaunchLiquidity.d.ts.map +1 -0
  317. package/vendor/shared/dist/abi/token/LaunchLiquidity.js +336 -0
  318. package/vendor/shared/dist/abi/token/LaunchLiquidity.js.map +1 -0
  319. package/vendor/shared/dist/abi/token/LiquidityAdder.d.ts +176 -0
  320. package/vendor/shared/dist/abi/token/LiquidityAdder.d.ts.map +1 -0
  321. package/vendor/shared/dist/abi/token/LiquidityAdder.js +229 -0
  322. package/vendor/shared/dist/abi/token/LiquidityAdder.js.map +1 -0
  323. package/vendor/shared/dist/abi/token/TaxDistributor.d.ts +182 -0
  324. package/vendor/shared/dist/abi/token/TaxDistributor.d.ts.map +1 -0
  325. package/vendor/shared/dist/abi/token/TaxDistributor.js +236 -0
  326. package/vendor/shared/dist/abi/token/TaxDistributor.js.map +1 -0
  327. package/vendor/shared/dist/abi/token/TestFaucet.d.ts +164 -0
  328. package/vendor/shared/dist/abi/token/TestFaucet.d.ts.map +1 -0
  329. package/vendor/shared/dist/abi/token/TestFaucet.js +215 -0
  330. package/vendor/shared/dist/abi/token/TestFaucet.js.map +1 -0
  331. package/vendor/shared/dist/abi/token/index.d.ts +8 -0
  332. package/vendor/shared/dist/abi/token/index.d.ts.map +1 -0
  333. package/vendor/shared/dist/abi/token/index.js +8 -0
  334. package/vendor/shared/dist/abi/token/index.js.map +1 -0
  335. package/vendor/shared/dist/emission-schedule.d.ts +51 -0
  336. package/vendor/shared/dist/emission-schedule.d.ts.map +1 -0
  337. package/vendor/shared/dist/emission-schedule.js +116 -0
  338. package/vendor/shared/dist/emission-schedule.js.map +1 -0
  339. package/vendor/shared/dist/index.d.ts +7 -0
  340. package/vendor/shared/dist/index.d.ts.map +1 -0
  341. package/vendor/shared/dist/index.js +7 -0
  342. package/vendor/shared/dist/index.js.map +1 -0
  343. package/vendor/shared/dist/params/index.d.ts +6 -0
  344. package/vendor/shared/dist/params/index.d.ts.map +1 -0
  345. package/vendor/shared/dist/params/index.js +84 -0
  346. package/vendor/shared/dist/params/index.js.map +1 -0
  347. package/vendor/shared/dist/protocol-proofs.d.ts +267 -0
  348. package/vendor/shared/dist/protocol-proofs.d.ts.map +1 -0
  349. package/vendor/shared/dist/protocol-proofs.js +205 -0
  350. package/vendor/shared/dist/protocol-proofs.js.map +1 -0
  351. package/vendor/shared/dist/rules/index.d.ts +204 -0
  352. package/vendor/shared/dist/rules/index.d.ts.map +1 -0
  353. package/vendor/shared/dist/rules/index.js +802 -0
  354. package/vendor/shared/dist/rules/index.js.map +1 -0
  355. package/vendor/shared/dist/rules/spec-content.d.ts +21 -0
  356. package/vendor/shared/dist/rules/spec-content.d.ts.map +1 -0
  357. package/vendor/shared/dist/rules/spec-content.js +90 -0
  358. package/vendor/shared/dist/rules/spec-content.js.map +1 -0
  359. package/vendor/shared/dist/rules/task-risk.d.ts +35 -0
  360. package/vendor/shared/dist/rules/task-risk.d.ts.map +1 -0
  361. package/vendor/shared/dist/rules/task-risk.js +438 -0
  362. package/vendor/shared/dist/rules/task-risk.js.map +1 -0
  363. package/vendor/shared/dist/schemas/domain.d.ts +195 -0
  364. package/vendor/shared/dist/schemas/domain.d.ts.map +1 -0
  365. package/vendor/shared/dist/schemas/domain.js +158 -0
  366. package/vendor/shared/dist/schemas/domain.js.map +1 -0
  367. package/vendor/shared/dist/schemas/draft.d.ts +730 -0
  368. package/vendor/shared/dist/schemas/draft.d.ts.map +1 -0
  369. package/vendor/shared/dist/schemas/draft.js +110 -0
  370. package/vendor/shared/dist/schemas/draft.js.map +1 -0
  371. package/vendor/shared/dist/schemas/enums.d.ts +130 -0
  372. package/vendor/shared/dist/schemas/enums.d.ts.map +1 -0
  373. package/vendor/shared/dist/schemas/enums.js +63 -0
  374. package/vendor/shared/dist/schemas/enums.js.map +1 -0
  375. package/vendor/shared/dist/schemas/index.d.ts +4 -0
  376. package/vendor/shared/dist/schemas/index.d.ts.map +1 -0
  377. package/vendor/shared/dist/schemas/index.js +4 -0
  378. package/vendor/shared/dist/schemas/index.js.map +1 -0
  379. package/vendor/shared/dist/units.d.ts +10 -0
  380. package/vendor/shared/dist/units.d.ts.map +1 -0
  381. package/vendor/shared/dist/units.js +44 -0
  382. package/vendor/shared/dist/units.js.map +1 -0
  383. package/vendor/shared/openapi.json +78754 -0
  384. package/vendor/shared/package.json +43 -0
  385. package/vendor/shared/params/params.json +152 -0
  386. package/vendor/shared/params/ranges.json +574 -0
  387. package/vendor/shared/src/emission-schedule.ts +151 -0
  388. package/vendor/shared/src/index.ts +6 -0
  389. package/vendor/shared/src/params/index.ts +139 -0
  390. package/vendor/shared/src/protocol-proofs.ts +235 -0
  391. package/vendor/shared/src/rules/index.ts +1081 -0
  392. package/vendor/shared/src/rules/spec-content.ts +120 -0
  393. package/vendor/shared/src/rules/task-risk.ts +550 -0
  394. package/vendor/shared/src/schemas/domain.ts +187 -0
  395. package/vendor/shared/src/schemas/draft.ts +141 -0
  396. package/vendor/shared/src/schemas/enums.ts +73 -0
  397. package/vendor/shared/src/schemas/index.ts +3 -0
  398. package/vendor/shared/src/units.ts +43 -0
  399. package/vendor/shared/test/emission-schedule.test.ts +115 -0
  400. package/vendor/shared/test/fixtures/emission-vectors.json +1055 -0
  401. package/vendor/shared/test/fixtures.ts +65 -0
  402. package/vendor/shared/test/params.test.ts +48 -0
  403. package/vendor/shared/test/properties.test.ts +136 -0
  404. package/vendor/shared/test/protocol-proofs.test.ts +88 -0
  405. package/vendor/shared/test/rules.test.ts +474 -0
  406. package/vendor/shared/test/schemas.test.ts +130 -0
  407. package/vendor/shared/test/task-risk.test.ts +489 -0
  408. package/vendor/shared/tsconfig.abi.json +11 -0
  409. package/vendor/shared/tsconfig.json +23 -0
  410. package/vendor/shared/types/api/index.d.ts +303 -0
  411. package/vendor/shared/vitest.config.ts +8 -0
@@ -0,0 +1,120 @@
1
+ import type {
2
+ Criterion,
3
+ MachineCheck,
4
+ RuleCheckResult,
5
+ TaskInput,
6
+ } from "../schemas/index.js";
7
+ import { checkTaskRisk } from "./task-risk.js";
8
+
9
+ /** Machine check kinds testers execute; any other kind cannot be verified and blocks publishing. */
10
+ export const MACHINE_CHECK_KINDS = [
11
+ "JSON_SCHEMA",
12
+ "REGEX",
13
+ "URL_CHECK",
14
+ ] as const;
15
+ export type MachineCheckKind = (typeof MACHINE_CHECK_KINDS)[number];
16
+
17
+ /** The executable parts of a specification; `null` marks a field that is not filled yet. */
18
+ export interface SpecContent {
19
+ title: string | null;
20
+ summary: string | null;
21
+ deliverables: readonly string[] | null;
22
+ constraints: readonly string[] | null;
23
+ inputs: readonly TaskInput[] | null;
24
+ criteria: readonly Criterion[] | null;
25
+ }
26
+
27
+ const PLACEHOLDER =
28
+ /待补充|待用户|待填写|待提供|\bTBD\b|\bTODO\b|\{\{[^}]*\}\}/iu;
29
+ const INPUT_REQUEST =
30
+ /请补充|请提供|请填写|please\s+(?:add|provide|supply|fill)/iu;
31
+
32
+ /** Returns why a machine check can never be executed as written, or null when it is runnable. */
33
+ export function machineCheckProblem(check: MachineCheck): string | null {
34
+ if (!(MACHINE_CHECK_KINDS as readonly string[]).includes(check.kind))
35
+ return `unsupported kind ${check.kind}`;
36
+ if (check.kind === "REGEX") {
37
+ try {
38
+ new RegExp(check.commandOrSchema, "gu");
39
+ } catch {
40
+ return "regex does not compile with flags gu";
41
+ }
42
+ }
43
+ if (check.kind === "JSON_SCHEMA") {
44
+ let schema: unknown;
45
+ try {
46
+ schema = JSON.parse(check.commandOrSchema);
47
+ } catch {
48
+ return "schema is not valid JSON";
49
+ }
50
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema))
51
+ return "schema must be a JSON object";
52
+ }
53
+ if (check.kind === "URL_CHECK" && check.expected.trim() !== "") {
54
+ const status = Number(check.expected);
55
+ if (!Number.isInteger(status) || status < 100 || status > 599)
56
+ return "expected must be an HTTP status code";
57
+ }
58
+ return null;
59
+ }
60
+
61
+ /**
62
+ * Deterministic executability checks: every machine check must be runnable by testers, no field
63
+ * may still carry a placeholder or a request addressed to the publisher, and risk control passes.
64
+ */
65
+ export function checkSpecContent(content: SpecContent): RuleCheckResult[] {
66
+ const criteria = content.criteria ?? [];
67
+ const problems = criteria.flatMap((criterion) => {
68
+ const problem = criterion.machineCheck
69
+ ? machineCheckProblem(criterion.machineCheck)
70
+ : null;
71
+ return problem ? [`${criterion.id}: ${problem}`] : [];
72
+ });
73
+ const needsJson = criteria.some(
74
+ ({ machineCheck }) => machineCheck?.kind === "JSON_SCHEMA",
75
+ );
76
+ if (
77
+ needsJson &&
78
+ !(content.deliverables ?? []).some((item) => /json/iu.test(item))
79
+ )
80
+ problems.push("JSON_SCHEMA checks need a JSON deliverable");
81
+ const offending = new Set<string>();
82
+ const scan = (
83
+ field: string,
84
+ texts: readonly string[],
85
+ pattern = PLACEHOLDER,
86
+ ) => {
87
+ if (texts.some((text) => pattern.test(text))) offending.add(field);
88
+ };
89
+ scan("title", content.title ? [content.title] : []);
90
+ scan("summary", content.summary ? [content.summary] : []);
91
+ scan("deliverables", content.deliverables ?? []);
92
+ scan("constraints", content.constraints ?? []);
93
+ scan(
94
+ "criteria",
95
+ criteria.map(({ description }) => description),
96
+ );
97
+ const inputs = (content.inputs ?? []).map(({ ref }) => ref);
98
+ scan("inputs", inputs);
99
+ scan("inputs", inputs, INPUT_REQUEST);
100
+ return [
101
+ {
102
+ id: "criteria.machineChecks",
103
+ level: problems.length ? "block" : "ok",
104
+ message: problems.length
105
+ ? `Machine checks cannot run: ${problems.join("; ")}`
106
+ : "Every machine check is runnable",
107
+ fields: ["criteria"],
108
+ ...(problems.length ? { params: { problems: problems.join("; ") } } : {}),
109
+ },
110
+ {
111
+ id: "content.placeholders",
112
+ level: offending.size ? "block" : "ok",
113
+ message: offending.size
114
+ ? `Fields still contain placeholders or requests for the publisher: ${[...offending].join(", ")}`
115
+ : "No unresolved placeholders",
116
+ fields: [...offending],
117
+ },
118
+ ...checkTaskRisk(content),
119
+ ];
120
+ }
@@ -0,0 +1,550 @@
1
+ import type { RuleCheckResult, TaskInput } from "../schemas/index.js";
2
+
3
+ /** The publisher-written text a task risk scan reads; `null` marks a field that is not filled yet. */
4
+ export interface TaskRiskContent {
5
+ title: string | null;
6
+ summary: string | null;
7
+ deliverables: readonly string[] | null;
8
+ constraints: readonly string[] | null;
9
+ inputs: readonly TaskInput[] | null;
10
+ criteria:
11
+ | readonly {
12
+ description: string;
13
+ machineCheck?:
14
+ | { expected: string; commandOrSchema?: string | undefined }
15
+ | null
16
+ | undefined;
17
+ }[]
18
+ | null;
19
+ }
20
+
21
+ export const TASK_RISK_CHECK_IDS = [
22
+ "risk.fundTransfer",
23
+ "risk.secretRequest",
24
+ "risk.prohibitedContent",
25
+ "risk.phishingLink",
26
+ ] as const;
27
+ export type TaskRiskCheckId = (typeof TASK_RISK_CHECK_IDS)[number];
28
+
29
+ interface Segment {
30
+ field: string;
31
+ text: string;
32
+ }
33
+
34
+ /** Sending value to someone; with an amount, address or recipient this is a direct transfer. */
35
+ const SEND_VERB =
36
+ /转账|转入|转出|转走|转给|转至|转到|转币|打款|打币|汇款|汇给|付给|\b(?:transfer(?:s|red|ring)?|send(?:s|ing)?)\b/giu;
37
+ /** Paying or giving, which also describes rewards; only an address or recipient makes it a transfer. */
38
+ const PAY_VERB =
39
+ /付款|支付|发送|发币|\b(?:pay(?:s|ing)?|donat(?:e|es|ing)|tip(?:s|ping)?)\b/giu;
40
+ /** Nouns that only mean a transfer; asking for its transaction hash asks for the transfer itself. */
41
+ const TRANSFER_NOUN =
42
+ /转账|汇款|打款|转币|打币|送金|振込|振り込み|송금|이체|virement|[üu]berweisung|перевод\s+(?:средств|токенов|монет)/giu;
43
+ /** Token transfer methods; next to a wallet address they spell out a transfer through the contract. */
44
+ const TOKEN_TRANSFER_METHOD =
45
+ /\b(?:safe)?transfer(?:From)?\b|\bsafeBatchTransferFrom\b|\btransferAndCall\b/giu;
46
+ /**
47
+ * Function selectors of ERC-20/721/1155 transfers and spending approvals, as raw calldata:
48
+ * transfer, transferFrom, safeTransferFrom (×2), safeBatchTransferFrom, approve, setApprovalForAll,
49
+ * increaseAllowance, permit.
50
+ */
51
+ const TRANSFER_SELECTOR =
52
+ /0x(?:a9059cbb|23b872dd|42842e0e|b88d4fde|2eb2c2d6|095ea7b3|a22cb465|39509351|d505accf)/iu;
53
+ /** An approval call whose spender argument is a literal address: it hands spending to that address. */
54
+ const APPROVE_TO_ADDRESS =
55
+ /\b(?:approve|increaseAllowance|setApprovalForAll|permit)\s*\(\s*["'`]?0x[0-9a-fA-F]{40}/giu;
56
+ /**
57
+ * Moving value through a protocol with the executor's own wallet (swap, bridge, deposit, approve).
58
+ * Legitimate testnet tasks do this, so it only warns.
59
+ */
60
+ const PROTOCOL_VERB =
61
+ /充值|充币|提币|提现|授权|兑换|跨链|存入|空投|\b(?:deposit(?:s|ing)?|withdraw(?:s|ing)?|swap(?:s|ping)?|bridg(?:e|es|ing)|approv(?:e|es|ing)|airdrop(?:s|ping)?)\b/giu;
62
+ const WALLET_ADDRESS =
63
+ /0x[0-9a-fA-F]{40}(?![0-9a-fA-F])|\b[a-z0-9-]{3,}\.eth\b|\bT[1-9A-HJ-NP-Za-km-z]{33}\b|\bbc1[02-9ac-hj-np-z]{11,71}\b/u;
64
+ const TOKEN_AMOUNT =
65
+ /\d+(?:\.\d+)?\s*(?:AGT|t?BNB|ETH|USDT|USDC|BUSD|DAI|BTC|WBNB|WETH|TRX|SOL|MATIC|POL|wei|gwei|个?代币|个?币)(?![A-Za-z])/iu;
66
+ /**
67
+ * Send/transfer verbs in other languages. Scripts without spaces get no boundary; Latin and
68
+ * Cyrillic stems must not continue a longer word on the left.
69
+ */
70
+ const INTL_SEND_VERB =
71
+ /送金|振込|振り込|送付|송금|이체|전송|보내|تحويل|حوّل|أرسل|ارسل|โอน|भेज|ट्रांसफर|(?<![\p{L}])(?:transfi[eé]r\p{L}*|transferi\p{L}*|transfira|transf[eé]r\p{L}*|virement|env[ií]a\p{L}*|envi[ae]\p{L}*|envoy\p{L}*|[üu]berweis\p{L}*|[üu]bertr[äa]g\p{L}*|sende\p{L}*|chuyển|gửi|kirim\p{L}*|g[öo]nder\p{L}*|перев[еоa]\p{L}*|отправ\p{L}*|переказ\p{L}*|надіш\p{L}*)/iu;
72
+ /** Deposit/withdraw verbs in other languages; like `PROTOCOL_VERB` they only warn. */
73
+ const INTL_PROTOCOL_VERB =
74
+ /入金|出金|입금|출금|إيداع|سحب|ฝาก|ถอน|जमा\s*कर|(?<![\p{L}])(?:deposit[ae]\p{L}*|d[ée]pos\p{L}*|retir[ae]\p{L}*|sacar|saque|einzahl\p{L}*|auszahl\p{L}*|nạp|rút|setor\p{L}*|tarik\p{L}*|yat[ıi]r\p{L}*|пополн\p{L}*|вывед\p{L}*|вывод\p{L}*)/iu;
75
+ const RECIPIENT =
76
+ /收款地址|收款人|收款钱包|接收地址|目标地址|受取アドレス|受取人|宛先|送金先|수신\s*주소|받는\s*주소|수취인|\b(?:recipient|beneficiary|payee)\b|destinatari\p{L}*|b[ée]n[ée]ficiaire|empf[äa]nger|получател\p{L}*|địa\s+chỉ\s+nhận|người\s+nhận|penerima|al[ıi]c[ıi]|المستلم|ผู้รับ/iu;
77
+ const TX_PROOF =
78
+ /交易哈希|交易\s*hash|转账截图|转账记录|转账凭证|取引ハッシュ|トランザクションハッシュ|트랜잭션\s*해시|거래\s*해시|\btx\s*hash\b|\btxid\b|\btransaction\s+hash\b|hash\s+de\s+(?:la\s+)?transac\p{L}*|transaktions-?hash|х[еэ]ш\s+транзакци\p{L}*|mã\s+giao\s+dịch|hash\s+giao\s+dịch|hash\s+transaksi|i[şs]lem\s+hash|\btx[._-]?(?:hash|id)?\.txt\b/iu;
79
+ /** A machine check that only accepts a 32-byte transaction hash, whatever language the task uses. */
80
+ const TX_HASH_CHECK = /0x[^\n]{0,24}\{64\}|\[0-9a-f[^\]]*\]\{64\}/iu;
81
+ /** A short gap inside one clause: no sentence punctuation or line break. */
82
+ const GAP = "[^,。、,.;;!!??।\\n]{0,14}?";
83
+ const SHORT_GAP = "[^,。、,.;;!!??।\\n]{0,6}?";
84
+ const WIDE_GAP = "[^,。、,.;;!!??।\\n]{0,24}?";
85
+ /** Calling a value-moving method; only risky when the task is about a live chain or wallet. */
86
+ const CONTRACT_CALL = new RegExp(
87
+ `(?:调用|执行|发起|签名|签署|\\bcall\\b|\\binvoke\\b|\\bexecute\\b|\\bsign\\b)${SHORT_GAP}\\b(?:transferFrom|safeTransferFrom|transfer|approve|permit|setApprovalForAll|increaseAllowance|sendTransaction|eth_sendTransaction|eth_sign|personal_sign|signTypedData(?:_v4)?)\\b`,
88
+ "giu",
89
+ );
90
+ /**
91
+ * Calling a contract on chain. Even without a recipient in the text the contract may hard-code one,
92
+ * so this warns whenever the task is about a live chain.
93
+ */
94
+ const CONTRACT_WORD =
95
+ /合约|\bcontracts?\b|コントラクト|컨트랙트|contrato|\bcontrat\b|vertrag|контракт|hợp\s+đồng|kontrak|sözleşme|عقد\s+ذكي|สัญญาอัจฉริยะ|कॉन्ट्रैक्ट/iu;
96
+ const CALL_WORD =
97
+ /调用|执行|交互|触发|领取|铸造|\b(?:call|calls|calling|invoke|execute|interact|trigger|mint|claim)\b|呼び出|호출|llam[ae]\p{L}*|cham[ae]\p{L}*|appel\p{L}*|aufruf\p{L}*|вызов\p{L}*|вызв\p{L}*|gọi|panggil|çağır\p{L}*|استدعاء|เรียก|कॉल/iu;
98
+ const CHAIN_CONTEXT =
99
+ /链上|主网|测试网|钱包|テストネット|メインネット|ウォレット|테스트넷|메인넷|지갑|bscscan|etherscan|0x[0-9a-fA-F]{40}|\b(?:on-?chain|mainnet|testnet|bsc|bnb\s*chain|wallet|metamask)\b/iu;
100
+ /** Signing with the executor's own wallet, or producing a permit-style approval signature. */
101
+ const SIGN_REQUEST = new RegExp(
102
+ `(?:钱包|小狐狸|\\bwallet\\b|\\bmetamask\\b)${GAP}(?:签名|签署|\\bsign\\b)|(?:签名|签署|\\bsign\\b)${GAP}(?:钱包|\\bwallet\\b)|(?:签名|签署|\\bsign\\b)${SHORT_GAP}(?:许可|\\bpermit\\b|\\btyped\\s*data\\b|\\beth_sign\\b)`,
103
+ "giu",
104
+ );
105
+
106
+ const SECRET =
107
+ "(?:私钥|助记词|种子短语|恢复短语|钱包密码|keystore\\s*(?:文件|密码|file|password)|private\\s*keys?|mnemonic|seed\\s*phrase|recovery\\s*phrase|secret\\s*recovery|wallet\\s*password)";
108
+ const SECRET_VERB =
109
+ "(?:提交|提供|发送|上传|填写|导出|粘贴|输入|附上|交出|\\bsubmit\\b|\\bprovide\\b|\\bsend\\b|\\bupload\\b|\\bpaste\\b|\\benter\\b|\\bexport\\b|\\bshare\\b|\\binclude\\b)";
110
+ const SECRET_REQUEST = new RegExp(
111
+ `${SECRET_VERB}${GAP}${SECRET}|${SECRET}${GAP}${SECRET_VERB}`,
112
+ "giu",
113
+ );
114
+ /**
115
+ * Wallet secrets in other languages. Without a reliable negation for every language any mention
116
+ * blocks; defensive wording belongs in `outOfScope`, which is not scanned.
117
+ */
118
+ const INTL_SECRET =
119
+ /秘密鍵|シードフレーズ|ニーモニック|復元フレーズ|개인\s*키|비밀\s*키|시드\s*구문|니모닉|복구\s*구문|clave\s+privada|frase\s+(?:semilla|de\s+recupera\p{L}*)|chave\s+privada|frase\s+de\s+recupera\p{L}*|cl[ée]\s+priv[ée]e|phrase\s+(?:de\s+r[ée]cup[ée]ration|secr[èe]te)|privat(?:er|en)?\s+schl[üu]ssel|seed-?phrase|wiederherstellungs\p{L}*|приватн\p{L}*\s+ключ|секретн\p{L}*\s+ключ|сид-?фраз\p{L}*|мнемоні?\p{L}*|khóa\s+riêng|cụm\s+từ\s+khôi\s+phục|kunci\s+pribadi|frasa\s+pemulihan|özel\s+anahtar|المفتاح\s+الخاص|عبارة\s+الاسترداد|คีย์ส่วนตัว|निजी\s+कुंजी/iu;
120
+ const INTL_WALLET =
121
+ "(?:ウォレット|지갑|billetera|cartera|carteira|portefeuille|brieftasche|кошел\\p{L}*|гаманц\\p{L}*|ví\\s+(?:điện\\s+tử|tiền|crypto)|dompet|c[üu]zdan|محفظة|กระเป๋าเงิน|वॉलेट)";
122
+ const INTL_SIGN =
123
+ "(?:署名|서명|firm[ae]\\p{L}*|assin\\p{L}*|sign(?:ez|er|ieren)\\p{L}*|unterschreib\\p{L}*|подпи\\p{L}*|ký\\s+(?:tên|giao\\s+dịch|tin\\s+nhắn|thông\\s+điệp)|tanda\\s*tangan|imzala\\p{L}*|توقيع|وقّع|ลงนาม|हस्ताक्षर)";
124
+ /** Wallet signing requests in other languages: a wallet word and a signing word in one clause. */
125
+ const INTL_SIGN_REQUEST = new RegExp(
126
+ `${INTL_WALLET}${WIDE_GAP}${INTL_SIGN}|${INTL_SIGN}${WIDE_GAP}${INTL_WALLET}`,
127
+ "iu",
128
+ );
129
+
130
+ /** Defensive wording ("不提交私钥", "never send funds") directly before a match keeps it harmless. */
131
+ const NEGATION_CN =
132
+ /(?:不|勿|禁止|严禁|不得|不要|不能|无需|不需要|避免|切勿|请勿)[^,。,.;;!!??\s]{0,3}$/u;
133
+ const NEGATION_EN =
134
+ /\b(?:never|not|no|don't|do\s+not|must\s+not|without)\s+(?:\w+\s+){0,2}$/iu;
135
+
136
+ function negated(text: string, index: number): boolean {
137
+ const prefix = text.slice(Math.max(0, index - 16), index);
138
+ return NEGATION_CN.test(prefix) || NEGATION_EN.test(prefix);
139
+ }
140
+
141
+ /** Whether `pattern` (a global regex) matches somewhere that is not negated. */
142
+ function affirmed(text: string, pattern: RegExp): boolean {
143
+ for (const match of text.matchAll(pattern)) {
144
+ if (!negated(text, match.index ?? 0)) return true;
145
+ }
146
+ return false;
147
+ }
148
+
149
+ // ---------------------------------------------------------------------------
150
+ // Prohibited content
151
+ // ---------------------------------------------------------------------------
152
+
153
+ export const PROHIBITED_CONTENT_CATEGORIES = [
154
+ "sexual",
155
+ "gambling",
156
+ "drugs",
157
+ "violence",
158
+ "political",
159
+ ] as const;
160
+ export type ProhibitedContentCategory =
161
+ (typeof PROHIBITED_CONTENT_CATEGORIES)[number];
162
+
163
+ /** Left boundary for Latin/Cyrillic stems; CJK and Thai have no word spaces and need none. */
164
+ const L = "(?<![\\p{L}\\p{N}])";
165
+ /** Right boundary for Latin/Cyrillic words. */
166
+ const R = "(?![\\p{L}\\p{N}])";
167
+ const words = (source: string) => new RegExp(source, "giu");
168
+
169
+ /**
170
+ * Prohibited task subjects, in the languages the platform sees most. Terms are specific enough to
171
+ * name the subject itself (not "drug", "kill", "policy" or "leader election"); paraphrases and
172
+ * other languages are left to the AI review, which applies the same policy.
173
+ */
174
+ const PROHIBITED: Readonly<Record<ProhibitedContentCategory, RegExp>> = {
175
+ sexual: words(
176
+ [
177
+ "色情|淫秽|淫穢|黄色(?:网站|網站|视频|視頻|小说|小說|图片|圖片)|成人(?:视频|視頻|网站|網站|影片|内容|內容)|裸聊|约炮|約炮|卖淫|賣淫|嫖娼|援交|性服务|性服務|一夜情",
178
+ "アダルト(?:動画|サイト|コンテンツ)|ポルノ|エロ動画|援助交際|風俗店|야동|포르노|성인\\s*(?:영상|사이트|콘텐츠)|성매매|음란물",
179
+ `${L}(?:porn\\p{L}*|hentai|onlyfans|camgirls?|prostitut\\p{L}*|escort\\s+services?|sex\\s+(?:chat|cams?|services?|videos?|work(?:ers?)?)|nude\\s+(?:photos?|pics?|images?|videos?)|naked\\s+(?:photos?|pics?|images?|videos?)|erotic\\s+(?:content|stories|videos?))${R}`,
180
+ `${L}(?:pornogra\\p{L}*|prostitu\\p{L}*|порн\\p{L}*|проститу\\p{L}*|эротическ\\p{L}*|khiêu\\s+dâm|mại\\s+dâm|fuhuş|müstehcen)${R}`,
181
+ "إباحي|إباحية|دعارة|ลามก|โสเภณี|อนาจาร|अश्लील|वेश्यावृत्ति",
182
+ ].join("|"),
183
+ ),
184
+ gambling: words(
185
+ [
186
+ "赌博|賭博|赌场|賭場|博彩|网赌|網賭|赌球|賭球|六合彩|百家乐|百家樂|老虎机|老虎機|菠菜(?:网|網|站|平台)|下注(?:网站|網站|平台)|时时彩|時時彩",
187
+ "ギャンブル|カジノ|パチンコ|スロット(?:マシン|サイト)|オンライン賭博|도박|카지노|스포츠\\s*토토|불법\\s*토토|바카라",
188
+ `${L}(?:gambl\\p{L}*|casinos?|sportsbooks?|bookmakers?|baccarat|roulette|online\\s+slots?|slot\\s+machines?|betting\\s+(?:sites?|platforms?|odds|tips|apps?)|sports\\s+betting|poker\\s+(?:sites?|rooms?|bots?))${R}`,
189
+ `${L}(?:apuestas|juegos?\\s+de\\s+azar|apostas|jogos?\\s+de\\s+azar|jeux\\s+d'argent|paris\\s+sportifs|glücksspiel\\p{L}*|sportwetten|spielbank|азартн\\p{L}*|казино|букмекер\\p{L}*|ставки\\s+на\\s+спорт|cờ\\s+bạc|cá\\s+cược|sòng\\s+bạc|perjudian|judi\\s+(?:online|bola|slot)|taruhan|kasino|kumarhane|kumar\\s+oyun\\p{L}*|bahis)${R}`,
190
+ "قمار|مراهنات|كازينو|การพนัน|พนันออนไลน์|คาสิโน|जुआ|सट्टेबाजी|कैसीनो",
191
+ ].join("|"),
192
+ ),
193
+ drugs: words(
194
+ [
195
+ "毒品|吸毒|贩毒|販毒|制毒|製毒|冰毒|海洛因|可卡因|大麻|摇头丸|搖頭丸|芬太尼|K粉|麻古|迷幻药|迷幻藥",
196
+ "麻薬|覚醒剤|覚せい剤|大麻|コカイン|ヘロイン|危険ドラッグ|마약|필로폰|대마초|코카인|헤로인",
197
+ `${L}(?:cocaine|heroin|methamphetamine|crystal\\s+meth|fentanyl|mdma|ecstasy\\s+pills?|lsd|cannabis|marijuana|narcotics?|drug\\s+(?:dealing|dealers?|trafficking|smuggling|cartels?)|darknet\\s+markets?|weed\\s+(?:shops?|delivery|dealers?))${R}`,
198
+ `${L}(?:cocaína|heroína|marihuana|maconha|narcotráfico|cocaïne|héroïne|stupéfiants|kokain|rauschgift\\p{L}*|drogenhandel|наркот\\p{L}*|кокаин\\p{L}*|героин\\p{L}*|марихуан\\p{L}*|ma\\s+túy|narkoba|ganja|sabu-sabu|uyuşturucu)${R}`,
199
+ "مخدرات|كوكايين|هيروين|حشيش|ยาเสพติด|ยาบ้า|नशीले\\s+पदार्थ|ड्रग्स\\s+तस्करी|गांजा|हेरोइन",
200
+ ].join("|"),
201
+ ),
202
+ violence: words(
203
+ [
204
+ "(?:制造|製造|制作|製作|自制|自製)(?:炸弹|炸彈|炸药|炸藥|爆炸物|枪支|槍支|枪械|槍械)|炸药配方|炸藥配方|枪支(?:买卖|買賣|改装|改裝)|恐怖(?:袭击|襲擊|主义|主義|组织|組織)|暗杀|暗殺|雇凶|买凶|買兇|杀人(?!游戏)|殺人(?!遊戲)|自杀(?:方法|教程)|自殺(?:方法|教程)|自残|自殘|儿童色情|兒童色情|拐卖|拐賣|人口贩卖|人口販賣",
205
+ "爆弾の作り方|爆発物の製造|テロ(?:攻撃|組織|リスト)|殺人|暗殺|自殺の方法|児童ポルノ|人身売買|폭탄\\s*제조|테러\\s*(?:공격|조직)|살인|암살|자살\\s*방법|아동\\s*포르노|인신매매",
206
+ `${L}(?:bomb[- ]making|(?:make|making|build|building)\\s+(?:a\\s+|an\\s+)?(?:bombs?|explosives?|pipe\\s+bombs?)|explosives?\\s+(?:recipes?|tutorials?)|ghost\\s+guns?|3d[- ]printed\\s+(?:guns?|firearms?)|terroris[mt]s?|terror\\s+attacks?|assassinat\\p{L}*|murder(?:s|ing)?|hitm[ae]n|contract\\s+killing|mass\\s+shootings?|suicide\\s+(?:methods?|guides?)|self[- ]harm|child\\s+(?:abuse|pornography|sexual\\s+abuse)|csam|human\\s+trafficking)${R}`,
207
+ `${L}(?:fabricar\\s+(?:una\\s+)?bomba|terroris\\p{L}*|asesinat\\p{L}*|fabriquer\\s+une\\s+bombe|assassinat|bombe\\s+bauen|mord(?:e|en)?|изготов\\p{L}*\\s+бомб\\p{L}*|террор\\p{L}*|убийств\\p{L}*|chế\\s+tạo\\s+bom|khủng\\s+bố|giết\\s+người|merakit\\s+bom|teroris\\p{L}*|pembunuhan|bomba\\s+yapımı|terör\\p{L}*|cinayet)${R}`,
208
+ "صنع\\s+قنبلة|إرهاب|اغتيال|ทำระเบิด|ก่อการร้าย|ฆาตกรรม|बम\\s+बनाना|आतंकवाद|हत्या",
209
+ ].join("|"),
210
+ ),
211
+ political: words(
212
+ [
213
+ "政治|政党|政黨|(?<!领导者|領導者|leader\\s?)选举|(?<!领导者|領導者|leader\\s?)選舉|竞选|競選|总统|總統|国家领导人|國家領導人|共产党|共產黨|国民党|國民黨|民进党|民進黨|台独|台獨|港独|港獨|藏独|藏獨|疆独|疆獨|法轮功|法輪功|六四事件|天安门事件|天安門事件|习近平|習近平|示威游行|示威遊行|颜色革命|顏色革命",
214
+ "政治|選挙|政党|デモ活動|정치|선거|정당|대통령",
215
+ `${L}(?:politic(?:s|al|ally|ians?)|(?<!leader\\s)elections?|electoral|political\\s+propaganda|presidential|parliament(?:ary)?|referendums?|political\\s+parties|democratic\\s+party|republican\\s+party|communist\\s+party|regime\\s+change|dictators?(?:hip)?|geopolitic\\p{L}*|donald\\s+trump|joe\\s+biden|xi\\s+jinping|vladimir\\s+putin|putin|zelensk\\p{L}*)${R}`,
216
+ `${L}(?:partidos?\\s+polític\\p{L}*|campaña\\s+electoral|elecciones|propaganda\\s+política|campanha\\s+eleitoral|eleições|parti\\s+politique|campagne\\s+électorale|élections?|propagande|wahlkampf|bundestagswahl|политическ\\p{L}*\\s+(?:парти\\p{L}*|пропаганд\\p{L}*|агитаци\\p{L}*)|предвыборн\\p{L}*|выбор(?:ы|ах)\\s+президента|chính\\s+trị|bầu\\s+cử|politik|pemilu|partai\\s+politik|siyaset\\p{L}*|siyasi|seçim\\s+kampanyası|cumhurbaşkanlığı\\s+seçimi)${R}`,
217
+ "سياسي|سياسية|انتخابات|حزب\\s+سياسي|การเมือง|เลือกตั้ง|राजनीति|राजनीतिक|चुनाव",
218
+ ].join("|"),
219
+ ),
220
+ };
221
+
222
+ /**
223
+ * A prohibition earlier in the same clause ("内容不得涉及色情、赌博", "no gambling or adult
224
+ * content") keeps the match harmless. Other languages belong in `outOfScope`, which is not scanned.
225
+ */
226
+ const PROHIBITION_IN_CLAUSE =
227
+ /不得|不要|不能|不可|不允许|不允許|不涉及|不包含|不含|禁止|严禁|嚴禁|切勿|请勿|請勿|杜绝|杜絕|避免|拒绝|拒絕|排除|\b(?:no|not|never|without|avoid(?:s|ing)?|exclud(?:e|es|ing)|prohibit(?:s|ed)?|forbid(?:s|den)?|ban(?:s|ned)?|free\s+of)\b/iu;
228
+
229
+ function prohibitedInClause(text: string, index: number): boolean {
230
+ const clause =
231
+ text
232
+ .slice(0, index)
233
+ .split(/[。..!!??;;\n]/u)
234
+ .at(-1) ?? "";
235
+ return PROHIBITION_IN_CLAUSE.test(clause);
236
+ }
237
+
238
+ function prohibitedCategories(
239
+ items: readonly Segment[],
240
+ ): Map<ProhibitedContentCategory, Set<string>> {
241
+ const found = new Map<ProhibitedContentCategory, Set<string>>();
242
+ for (const { field, text } of items) {
243
+ for (const category of PROHIBITED_CONTENT_CATEGORIES) {
244
+ for (const match of text.matchAll(PROHIBITED[category])) {
245
+ if (prohibitedInClause(text, match.index ?? 0)) continue;
246
+ const fields = found.get(category) ?? new Set<string>();
247
+ fields.add(field);
248
+ found.set(category, fields);
249
+ break;
250
+ }
251
+ }
252
+ }
253
+ return found;
254
+ }
255
+
256
+ // ---------------------------------------------------------------------------
257
+ // Phishing links
258
+ // ---------------------------------------------------------------------------
259
+
260
+ const URL_PATTERN =
261
+ /\b[a-z][a-z0-9+.-]{1,15}:\/\/[^\s<>"'`))】\],。]+|\b(?:javascript|data|vbscript|ethereum|wc|metamask|trust|tronlink):[^\s<>"'`))】\],。]+/giu;
262
+ const SAFE_SCHEMES = new Set([
263
+ "http:",
264
+ "https:",
265
+ "ipfs:",
266
+ "ipns:",
267
+ "ar:",
268
+ "git:",
269
+ "ssh:",
270
+ "git+ssh:",
271
+ ]);
272
+ const LOCAL_HOSTS = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
273
+ const SHORTENERS = new Set([
274
+ "bit.ly",
275
+ "t.co",
276
+ "tinyurl.com",
277
+ "goo.gl",
278
+ "is.gd",
279
+ "ow.ly",
280
+ "cutt.ly",
281
+ "t.ly",
282
+ "rebrand.ly",
283
+ "shorturl.at",
284
+ "s.id",
285
+ "tiny.cc",
286
+ "rb.gy",
287
+ "buff.ly",
288
+ "lnkd.in",
289
+ "dub.sh",
290
+ ]);
291
+ /** Brand token → official registrable domains; a host carrying the token elsewhere is a lookalike. */
292
+ const BRANDS: Readonly<Record<string, readonly string[]>> = {
293
+ metamask: ["metamask.io"],
294
+ binance: ["binance.com", "binance.org", "bnbchain.org"],
295
+ bscscan: ["bscscan.com"],
296
+ etherscan: ["etherscan.io"],
297
+ pancakeswap: ["pancakeswap.finance"],
298
+ uniswap: ["uniswap.org"],
299
+ trustwallet: ["trustwallet.com"],
300
+ coinbase: ["coinbase.com"],
301
+ okx: ["okx.com"],
302
+ walletconnect: [
303
+ "walletconnect.com",
304
+ "walletconnect.network",
305
+ "walletconnect.org",
306
+ ],
307
+ opensea: ["opensea.io"],
308
+ ledger: ["ledger.com"],
309
+ trezor: ["trezor.io"],
310
+ agentsgot: ["agentsgot.network"],
311
+ github: ["github.com", "githubusercontent.com", "github.io"],
312
+ };
313
+ const WALLET_PHISH =
314
+ /connect-?wallet|wallet-?connect|verify-?wallet|validate-?wallet|sync-?wallet|restore-?wallet|unlock-?wallet|rectif(?:y|ication)|claim-?(?:airdrop|reward|token)s?|airdrop-?claim|free-?(?:bnb|eth|usdt|crypto|tokens?)|giveaway|double-?your/iu;
315
+ const RISKY_TLDS = new Set([
316
+ "zip",
317
+ "mov",
318
+ "top",
319
+ "click",
320
+ "country",
321
+ "gq",
322
+ "tk",
323
+ "ml",
324
+ "cf",
325
+ "ga",
326
+ "cyou",
327
+ "rest",
328
+ "monster",
329
+ ]);
330
+
331
+ /** Host spellings with common digit homoglyphs undone; `1` may stand for either `i` or `l`. */
332
+ function homoglyphVariants(host: string): string[] {
333
+ const base = host.replace(/0/gu, "o").replace(/3/gu, "e").replace(/5/gu, "s");
334
+ return [base.replace(/1/gu, "i"), base.replace(/1/gu, "l")].map((value) =>
335
+ value.replace(/[^a-z]/gu, ""),
336
+ );
337
+ }
338
+
339
+ function hostMatches(host: string, domain: string): boolean {
340
+ return host === domain || host.endsWith(`.${domain}`);
341
+ }
342
+
343
+ /** Why a URL looks like phishing (`block`) or merely unsafe (`warn`); `null` when it looks fine. */
344
+ export function linkRisk(
345
+ raw: string,
346
+ ): { level: "block" | "warn"; reason: string } | null {
347
+ let url: URL;
348
+ try {
349
+ url = new URL(raw);
350
+ } catch {
351
+ return null;
352
+ }
353
+ if (!SAFE_SCHEMES.has(url.protocol))
354
+ return { level: "block", reason: `unsafe scheme ${url.protocol}` };
355
+ if (url.username || url.password)
356
+ return { level: "block", reason: "credentials in URL" };
357
+ const host = url.hostname.toLowerCase();
358
+ if (!host) return null;
359
+ if (LOCAL_HOSTS.has(host)) return null;
360
+ if (/^\d{1,3}(?:\.\d{1,3}){3}$/u.test(host) || host.startsWith("["))
361
+ return { level: "block", reason: "raw IP host" };
362
+ if (host.split(".").some((label) => label.startsWith("xn--")))
363
+ return { level: "block", reason: "punycode host" };
364
+ if (SHORTENERS.has(host)) return { level: "block", reason: "URL shortener" };
365
+ const variants = homoglyphVariants(host);
366
+ for (const [brand, domains] of Object.entries(BRANDS)) {
367
+ if (!variants.some((variant) => variant.includes(brand))) continue;
368
+ if (domains.some((domain) => hostMatches(host, domain))) continue;
369
+ return { level: "block", reason: `lookalike of ${domains[0]}` };
370
+ }
371
+ if (WALLET_PHISH.test(`${host}${url.pathname}`))
372
+ return { level: "block", reason: "wallet-drainer wording" };
373
+ const tld = host.split(".").at(-1) ?? "";
374
+ if (RISKY_TLDS.has(tld))
375
+ return { level: "warn", reason: `high-risk TLD .${tld}` };
376
+ if (url.protocol === "http:")
377
+ return { level: "warn", reason: "unencrypted http" };
378
+ return null;
379
+ }
380
+
381
+ export function extractLinks(text: string): string[] {
382
+ return [...text.matchAll(URL_PATTERN)].map(([match]) =>
383
+ match.replace(/[.,;:!?]+$/u, ""),
384
+ );
385
+ }
386
+
387
+ // ---------------------------------------------------------------------------
388
+ // Checks
389
+ // ---------------------------------------------------------------------------
390
+
391
+ function segments(content: TaskRiskContent): Segment[] {
392
+ const items: Segment[] = [];
393
+ const push = (field: string, text: string | null | undefined) => {
394
+ if (text) items.push({ field, text });
395
+ };
396
+ push("title", content.title);
397
+ push("summary", content.summary);
398
+ for (const item of content.deliverables ?? []) push("deliverables", item);
399
+ for (const item of content.constraints ?? []) push("constraints", item);
400
+ for (const input of content.inputs ?? []) push("inputs", input.ref);
401
+ for (const criterion of content.criteria ?? []) {
402
+ push("criteria", criterion.description);
403
+ push("criteria", criterion.machineCheck?.expected);
404
+ }
405
+ return items;
406
+ }
407
+
408
+ function fundTransferFields(
409
+ items: readonly Segment[],
410
+ content: TaskRiskContent,
411
+ ): { direct: Set<string>; other: Set<string> } {
412
+ const direct = new Set<string>();
413
+ const other = new Set<string>();
414
+ const transferNounAnywhere = items.some(({ text }) =>
415
+ affirmed(text, TRANSFER_NOUN),
416
+ );
417
+ const onChain = items.some(({ text }) => CHAIN_CONTEXT.test(text));
418
+ for (const { field, text } of items) {
419
+ const target = WALLET_ADDRESS.test(text) || RECIPIENT.test(text);
420
+ const amount = TOKEN_AMOUNT.test(text);
421
+ const send = affirmed(text, SEND_VERB) || INTL_SEND_VERB.test(text);
422
+ const directTransfer =
423
+ (send && (target || amount)) ||
424
+ (affirmed(text, PAY_VERB) && target) ||
425
+ (transferNounAnywhere && TX_PROOF.test(text)) ||
426
+ (affirmed(text, TOKEN_TRANSFER_METHOD) && WALLET_ADDRESS.test(text)) ||
427
+ TRANSFER_SELECTOR.test(text) ||
428
+ affirmed(text, APPROVE_TO_ADDRESS);
429
+ if (directTransfer) {
430
+ direct.add(field);
431
+ continue;
432
+ }
433
+ const protocol =
434
+ (affirmed(text, PROTOCOL_VERB) || INTL_PROTOCOL_VERB.test(text)) &&
435
+ (target || amount);
436
+ const call =
437
+ onChain &&
438
+ (affirmed(text, CONTRACT_CALL) ||
439
+ affirmed(text, TOKEN_TRANSFER_METHOD) ||
440
+ (CONTRACT_WORD.test(text) && CALL_WORD.test(text)));
441
+ const sign = affirmed(text, SIGN_REQUEST) || INTL_SIGN_REQUEST.test(text);
442
+ if (protocol || call || sign) other.add(field);
443
+ }
444
+
445
+ // Language-independent hint: a wallet address next to a token amount or a required transaction
446
+ // hash may be a transfer in a language the verbs above miss. Swaps look the same, so it warns.
447
+ const txHashCheck = (content.criteria ?? []).some(({ machineCheck }) =>
448
+ TX_HASH_CHECK.test(machineCheck?.commandOrSchema ?? ""),
449
+ );
450
+ const addressFields = items.filter(({ text }) => WALLET_ADDRESS.test(text));
451
+ const valueFields = items.filter(
452
+ ({ text }) => TOKEN_AMOUNT.test(text) || TX_PROOF.test(text),
453
+ );
454
+ if (addressFields.length && (valueFields.length || txHashCheck)) {
455
+ for (const { field } of [...addressFields, ...valueFields])
456
+ other.add(field);
457
+ if (txHashCheck) other.add("criteria");
458
+ }
459
+ for (const field of direct) other.delete(field);
460
+ return { direct, other };
461
+ }
462
+
463
+ /**
464
+ * Deterministic task risk control. Direct transfers to an address or recipient and wallet-secret
465
+ * requests block publishing and claiming; other wallet actions and suspicious links only warn and
466
+ * are left to the publisher and the executor.
467
+ */
468
+ export function checkTaskRisk(content: TaskRiskContent): RuleCheckResult[] {
469
+ const items = segments(content);
470
+ const transfer = fundTransferFields(items, content);
471
+ const secret = new Set(
472
+ items
473
+ .filter(
474
+ ({ text }) => affirmed(text, SECRET_REQUEST) || INTL_SECRET.test(text),
475
+ )
476
+ .map(({ field }) => field),
477
+ );
478
+ const prohibited = prohibitedCategories(items);
479
+ const prohibitedFields = new Set(
480
+ [...prohibited.values()].flatMap((fields) => [...fields]),
481
+ );
482
+ const blockedLinks: string[] = [];
483
+ const warnedLinks: string[] = [];
484
+ const linkFields = new Set<string>();
485
+ for (const { field, text } of items) {
486
+ for (const link of extractLinks(text)) {
487
+ const risk = linkRisk(link);
488
+ if (!risk) continue;
489
+ linkFields.add(field);
490
+ (risk.level === "block" ? blockedLinks : warnedLinks).push(
491
+ `${link} (${risk.reason})`,
492
+ );
493
+ }
494
+ }
495
+ const links = [...blockedLinks, ...warnedLinks];
496
+ const { direct, other } = transfer;
497
+ return [
498
+ {
499
+ id: "risk.fundTransfer",
500
+ level: direct.size ? "block" : other.size ? "warn" : "ok",
501
+ message: direct.size
502
+ ? `Tasks may not ask the executor to transfer funds to an address or recipient: ${[...direct].join(", ")}`
503
+ : other.size
504
+ ? `Wallet or contract action requested; the contract may hard-code a recipient, so publisher and executor must check it: ${[...other].join(", ")}`
505
+ : "No fund transfer or wallet action requested",
506
+ fields: [...(direct.size ? direct : other)],
507
+ },
508
+ {
509
+ id: "risk.secretRequest",
510
+ level: secret.size ? "block" : "ok",
511
+ message: secret.size
512
+ ? `Tasks may not request private keys, mnemonics, or wallet passwords: ${[...secret].join(", ")}`
513
+ : "No wallet secret requested",
514
+ fields: [...secret],
515
+ },
516
+ {
517
+ id: "risk.prohibitedContent",
518
+ level: prohibited.size ? "block" : "ok",
519
+ message: prohibited.size
520
+ ? `Tasks may not involve sexual content, gambling, drugs, violence or other illegal acts, or politics (${[...prohibited.keys()].join(", ")}): ${[...prohibitedFields].join(", ")}`
521
+ : "No prohibited content",
522
+ fields: [...prohibitedFields],
523
+ ...(prohibited.size
524
+ ? { params: { categories: [...prohibited.keys()].join(",") } }
525
+ : {}),
526
+ },
527
+ {
528
+ // Links are judged by the publisher and the executor; this only points them out.
529
+ id: "risk.phishingLink",
530
+ level: links.length ? "warn" : "ok",
531
+ message: links.length
532
+ ? `Suspicious links: ${links.join("; ")}`
533
+ : "No suspicious links",
534
+ fields: [...linkFields],
535
+ ...(links.length
536
+ ? {
537
+ params: {
538
+ links: links.slice(0, 5).join("; "),
539
+ suspected: blockedLinks.length ? "phishing" : "risky",
540
+ },
541
+ }
542
+ : {}),
543
+ },
544
+ ];
545
+ }
546
+
547
+ /** True when a published specification would fail risk control; claims on it are refused. */
548
+ export function taskRiskBlocked(content: TaskRiskContent): boolean {
549
+ return checkTaskRisk(content).some(({ level }) => level === "block");
550
+ }