@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.
- package/ARCHITECTURE.md +5 -0
- package/README.md +13 -2
- package/dist/a2a.d.ts +35 -0
- package/dist/a2a.d.ts.map +1 -0
- package/dist/a2a.js +109 -0
- package/dist/a2a.js.map +1 -0
- package/dist/cli/binding.d.ts +24 -0
- package/dist/cli/binding.d.ts.map +1 -0
- package/dist/cli/binding.js +52 -0
- package/dist/cli/binding.js.map +1 -0
- package/dist/cli/commands.d.ts +18 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +191 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/context.d.ts +61 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +147 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/doctor.d.ts +34 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +109 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/home.d.ts +37 -0
- package/dist/cli/home.d.ts.map +1 -0
- package/dist/cli/home.js +77 -0
- package/dist/cli/home.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +120 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/install.d.ts +19 -0
- package/dist/cli/install.d.ts.map +1 -0
- package/dist/cli/install.js +64 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/keystore.d.ts +25 -0
- package/dist/cli/keystore.d.ts.map +1 -0
- package/dist/cli/keystore.js +57 -0
- package/dist/cli/keystore.js.map +1 -0
- package/dist/cli/mcp.d.ts +7 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +28 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +71 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/reports.d.ts +42 -0
- package/dist/cli/reports.d.ts.map +1 -0
- package/dist/cli/reports.js +121 -0
- package/dist/cli/reports.js.map +1 -0
- package/dist/cli/run.d.ts +21 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +125 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/wallet.d.ts +19 -0
- package/dist/cli/wallet.d.ts.map +1 -0
- package/dist/cli/wallet.js +58 -0
- package/dist/cli/wallet.js.map +1 -0
- package/dist/guides.d.ts +7 -0
- package/dist/guides.d.ts.map +1 -0
- package/dist/guides.js +94 -0
- package/dist/guides.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +16 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +30 -0
- package/dist/llm.js.map +1 -0
- package/dist/mcp/cli.d.ts +3 -0
- package/dist/mcp/cli.d.ts.map +1 -0
- package/dist/mcp/cli.js +6 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/mcp/server.d.ts +38 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +693 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/ports.d.ts +123 -0
- package/dist/ports.d.ts.map +1 -0
- package/dist/ports.js +134 -0
- package/dist/ports.js.map +1 -0
- package/dist/roles.d.ts +16 -0
- package/dist/roles.d.ts.map +1 -0
- package/dist/roles.js +49 -0
- package/dist/roles.js.map +1 -0
- package/dist/runner.d.ts +126 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +292 -0
- package/dist/runner.js.map +1 -0
- package/dist/schedules.d.ts +34 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +116 -0
- package/dist/schedules.js.map +1 -0
- package/dist/sdk/base64.d.ts +4 -0
- package/dist/sdk/base64.d.ts.map +1 -0
- package/dist/sdk/base64.js +15 -0
- package/dist/sdk/base64.js.map +1 -0
- package/dist/sdk/client.d.ts +198 -0
- package/dist/sdk/client.d.ts.map +1 -0
- package/dist/sdk/client.js +413 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/security.d.ts +10 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +24 -0
- package/dist/security.js.map +1 -0
- package/dist/skills.d.ts +21 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +93 -0
- package/dist/skills.js.map +1 -0
- package/dist/workers.d.ts +64 -0
- package/dist/workers.d.ts.map +1 -0
- package/dist/workers.js +127 -0
- package/dist/workers.js.map +1 -0
- package/dist/zip.d.ts +8 -0
- package/dist/zip.d.ts.map +1 -0
- package/dist/zip.js +80 -0
- package/dist/zip.js.map +1 -0
- package/docs/README.md +25 -0
- package/docs/architecture.md +18 -0
- package/docs/deployment.md +35 -0
- package/docs/reference/01-RULES.md +822 -0
- package/docs/reference/02-INTERFACES.md +487 -0
- package/docs/reference/03-STAKING-PENALTY-SPEC.md +739 -0
- package/docs/updates.md +65 -0
- package/docs/verification.md +72 -0
- package/package.json +88 -4
- package/skills/dist/agent-skills.json +68 -0
- package/skills/dist/arbitrator/SKILL.md +186 -0
- package/skills/dist/executor/SKILL.md +219 -0
- package/skills/dist/publisher/SKILL.md +172 -0
- package/skills/dist/tester/SKILL.md +198 -0
- package/vendor/shared/ARCHITECTURE.md +97 -0
- package/vendor/shared/README.md +5 -0
- package/vendor/shared/abi/index.js +2 -0
- package/vendor/shared/abi/index.ts +2 -0
- package/vendor/shared/abi/protocol/AgentRegistry.js +1623 -0
- package/vendor/shared/abi/protocol/AgentRegistry.json +1623 -0
- package/vendor/shared/abi/protocol/AgentRegistry.ts +1623 -0
- package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.js +154 -0
- package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.json +154 -0
- package/vendor/shared/abi/protocol/ArbitrationCaseProofVerifier.ts +154 -0
- package/vendor/shared/abi/protocol/ArbitrationCourt.js +1550 -0
- package/vendor/shared/abi/protocol/ArbitrationCourt.json +1550 -0
- package/vendor/shared/abi/protocol/ArbitrationCourt.ts +1550 -0
- package/vendor/shared/abi/protocol/ArbitrationPool.js +509 -0
- package/vendor/shared/abi/protocol/ArbitrationPool.json +509 -0
- package/vendor/shared/abi/protocol/ArbitrationPool.ts +509 -0
- package/vendor/shared/abi/protocol/ArbitrationProgressor.js +44 -0
- package/vendor/shared/abi/protocol/ArbitrationProgressor.json +44 -0
- package/vendor/shared/abi/protocol/ArbitrationProgressor.ts +44 -0
- package/vendor/shared/abi/protocol/ArbitrationSelection.js +1153 -0
- package/vendor/shared/abi/protocol/ArbitrationSelection.json +1153 -0
- package/vendor/shared/abi/protocol/ArbitrationSelection.ts +1153 -0
- package/vendor/shared/abi/protocol/ArbitrationSettlement.js +956 -0
- package/vendor/shared/abi/protocol/ArbitrationSettlement.json +956 -0
- package/vendor/shared/abi/protocol/ArbitrationSettlement.ts +956 -0
- package/vendor/shared/abi/protocol/ArbitrationStream.js +964 -0
- package/vendor/shared/abi/protocol/ArbitrationStream.json +964 -0
- package/vendor/shared/abi/protocol/ArbitrationStream.ts +964 -0
- package/vendor/shared/abi/protocol/EmissionController.js +1436 -0
- package/vendor/shared/abi/protocol/EmissionController.json +1436 -0
- package/vendor/shared/abi/protocol/EmissionController.ts +1436 -0
- package/vendor/shared/abi/protocol/HourlyAnchor.js +611 -0
- package/vendor/shared/abi/protocol/HourlyAnchor.json +611 -0
- package/vendor/shared/abi/protocol/HourlyAnchor.ts +611 -0
- package/vendor/shared/abi/protocol/IncentiveVault.js +480 -0
- package/vendor/shared/abi/protocol/IncentiveVault.json +480 -0
- package/vendor/shared/abi/protocol/IncentiveVault.ts +480 -0
- package/vendor/shared/abi/protocol/ParamRegistry.js +814 -0
- package/vendor/shared/abi/protocol/ParamRegistry.json +814 -0
- package/vendor/shared/abi/protocol/ParamRegistry.ts +814 -0
- package/vendor/shared/abi/protocol/PlatformTreasury.js +553 -0
- package/vendor/shared/abi/protocol/PlatformTreasury.json +553 -0
- package/vendor/shared/abi/protocol/PlatformTreasury.ts +553 -0
- package/vendor/shared/abi/protocol/ProtocolProof.js +1171 -0
- package/vendor/shared/abi/protocol/ProtocolProof.json +1171 -0
- package/vendor/shared/abi/protocol/ProtocolProof.ts +1171 -0
- package/vendor/shared/abi/protocol/PublisherStaking.js +1227 -0
- package/vendor/shared/abi/protocol/PublisherStaking.json +1227 -0
- package/vendor/shared/abi/protocol/PublisherStaking.ts +1227 -0
- package/vendor/shared/abi/protocol/RewardVesting.js +1027 -0
- package/vendor/shared/abi/protocol/RewardVesting.json +1027 -0
- package/vendor/shared/abi/protocol/RewardVesting.ts +1027 -0
- package/vendor/shared/abi/protocol/TaskEscrow.js +2219 -0
- package/vendor/shared/abi/protocol/TaskEscrow.json +2219 -0
- package/vendor/shared/abi/protocol/TaskEscrow.ts +2219 -0
- package/vendor/shared/abi/protocol/TesterAssignment.js +1375 -0
- package/vendor/shared/abi/protocol/TesterAssignment.json +1375 -0
- package/vendor/shared/abi/protocol/TesterAssignment.ts +1375 -0
- package/vendor/shared/abi/protocol/ValidatorStaking.js +1614 -0
- package/vendor/shared/abi/protocol/ValidatorStaking.json +1614 -0
- package/vendor/shared/abi/protocol/ValidatorStaking.ts +1614 -0
- package/vendor/shared/abi/protocol/index.js +19 -0
- package/vendor/shared/abi/protocol/index.ts +19 -0
- package/vendor/shared/abi/token/AGTToken.js +1018 -0
- package/vendor/shared/abi/token/AGTToken.json +1018 -0
- package/vendor/shared/abi/token/AGTToken.ts +1018 -0
- package/vendor/shared/abi/token/GenesisDistributor.js +242 -0
- package/vendor/shared/abi/token/GenesisDistributor.json +242 -0
- package/vendor/shared/abi/token/GenesisDistributor.ts +242 -0
- package/vendor/shared/abi/token/LPLocker.js +21 -0
- package/vendor/shared/abi/token/LPLocker.json +21 -0
- package/vendor/shared/abi/token/LPLocker.ts +21 -0
- package/vendor/shared/abi/token/LaunchLiquidity.js +335 -0
- package/vendor/shared/abi/token/LaunchLiquidity.json +335 -0
- package/vendor/shared/abi/token/LaunchLiquidity.ts +335 -0
- package/vendor/shared/abi/token/LiquidityAdder.js +228 -0
- package/vendor/shared/abi/token/LiquidityAdder.json +228 -0
- package/vendor/shared/abi/token/LiquidityAdder.ts +228 -0
- package/vendor/shared/abi/token/TaxDistributor.js +235 -0
- package/vendor/shared/abi/token/TaxDistributor.json +235 -0
- package/vendor/shared/abi/token/TaxDistributor.ts +235 -0
- package/vendor/shared/abi/token/TestFaucet.js +214 -0
- package/vendor/shared/abi/token/TestFaucet.json +214 -0
- package/vendor/shared/abi/token/TestFaucet.ts +214 -0
- package/vendor/shared/abi/token/index.js +7 -0
- package/vendor/shared/abi/token/index.ts +7 -0
- package/vendor/shared/dist/abi/index.d.ts +3 -0
- package/vendor/shared/dist/abi/index.d.ts.map +1 -0
- package/vendor/shared/dist/abi/index.js +3 -0
- package/vendor/shared/dist/abi/index.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/AgentRegistry.d.ts +1249 -0
- package/vendor/shared/dist/abi/protocol/AgentRegistry.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/AgentRegistry.js +1624 -0
- package/vendor/shared/dist/abi/protocol/AgentRegistry.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.d.ts +119 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.js +155 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCaseProofVerifier.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCourt.d.ts +1205 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCourt.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCourt.js +1551 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationCourt.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationPool.d.ts +391 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationPool.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationPool.js +510 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationPool.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.d.ts +34 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.js +45 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationProgressor.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSelection.d.ts +885 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSelection.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSelection.js +1154 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSelection.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.d.ts +742 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.js +957 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationSettlement.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationStream.d.ts +741 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationStream.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationStream.js +965 -0
- package/vendor/shared/dist/abi/protocol/ArbitrationStream.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/EmissionController.d.ts +1110 -0
- package/vendor/shared/dist/abi/protocol/EmissionController.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/EmissionController.js +1437 -0
- package/vendor/shared/dist/abi/protocol/EmissionController.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/HourlyAnchor.d.ts +467 -0
- package/vendor/shared/dist/abi/protocol/HourlyAnchor.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/HourlyAnchor.js +612 -0
- package/vendor/shared/dist/abi/protocol/HourlyAnchor.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/IncentiveVault.d.ts +369 -0
- package/vendor/shared/dist/abi/protocol/IncentiveVault.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/IncentiveVault.js +481 -0
- package/vendor/shared/dist/abi/protocol/IncentiveVault.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ParamRegistry.d.ts +628 -0
- package/vendor/shared/dist/abi/protocol/ParamRegistry.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ParamRegistry.js +815 -0
- package/vendor/shared/dist/abi/protocol/ParamRegistry.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/PlatformTreasury.d.ts +426 -0
- package/vendor/shared/dist/abi/protocol/PlatformTreasury.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/PlatformTreasury.js +554 -0
- package/vendor/shared/dist/abi/protocol/PlatformTreasury.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ProtocolProof.d.ts +903 -0
- package/vendor/shared/dist/abi/protocol/ProtocolProof.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ProtocolProof.js +1172 -0
- package/vendor/shared/dist/abi/protocol/ProtocolProof.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/PublisherStaking.d.ts +947 -0
- package/vendor/shared/dist/abi/protocol/PublisherStaking.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/PublisherStaking.js +1228 -0
- package/vendor/shared/dist/abi/protocol/PublisherStaking.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/RewardVesting.d.ts +793 -0
- package/vendor/shared/dist/abi/protocol/RewardVesting.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/RewardVesting.js +1028 -0
- package/vendor/shared/dist/abi/protocol/RewardVesting.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/TaskEscrow.d.ts +1725 -0
- package/vendor/shared/dist/abi/protocol/TaskEscrow.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/TaskEscrow.js +2220 -0
- package/vendor/shared/dist/abi/protocol/TaskEscrow.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/TesterAssignment.d.ts +1058 -0
- package/vendor/shared/dist/abi/protocol/TesterAssignment.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/TesterAssignment.js +1376 -0
- package/vendor/shared/dist/abi/protocol/TesterAssignment.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/ValidatorStaking.d.ts +1236 -0
- package/vendor/shared/dist/abi/protocol/ValidatorStaking.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/ValidatorStaking.js +1615 -0
- package/vendor/shared/dist/abi/protocol/ValidatorStaking.js.map +1 -0
- package/vendor/shared/dist/abi/protocol/index.d.ts +20 -0
- package/vendor/shared/dist/abi/protocol/index.d.ts.map +1 -0
- package/vendor/shared/dist/abi/protocol/index.js +20 -0
- package/vendor/shared/dist/abi/protocol/index.js.map +1 -0
- package/vendor/shared/dist/abi/token/AGTToken.d.ts +786 -0
- package/vendor/shared/dist/abi/token/AGTToken.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/AGTToken.js +1019 -0
- package/vendor/shared/dist/abi/token/AGTToken.js.map +1 -0
- package/vendor/shared/dist/abi/token/GenesisDistributor.d.ts +187 -0
- package/vendor/shared/dist/abi/token/GenesisDistributor.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/GenesisDistributor.js +243 -0
- package/vendor/shared/dist/abi/token/GenesisDistributor.js.map +1 -0
- package/vendor/shared/dist/abi/token/LPLocker.d.ts +16 -0
- package/vendor/shared/dist/abi/token/LPLocker.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/LPLocker.js +22 -0
- package/vendor/shared/dist/abi/token/LPLocker.js.map +1 -0
- package/vendor/shared/dist/abi/token/LaunchLiquidity.d.ts +260 -0
- package/vendor/shared/dist/abi/token/LaunchLiquidity.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/LaunchLiquidity.js +336 -0
- package/vendor/shared/dist/abi/token/LaunchLiquidity.js.map +1 -0
- package/vendor/shared/dist/abi/token/LiquidityAdder.d.ts +176 -0
- package/vendor/shared/dist/abi/token/LiquidityAdder.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/LiquidityAdder.js +229 -0
- package/vendor/shared/dist/abi/token/LiquidityAdder.js.map +1 -0
- package/vendor/shared/dist/abi/token/TaxDistributor.d.ts +182 -0
- package/vendor/shared/dist/abi/token/TaxDistributor.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/TaxDistributor.js +236 -0
- package/vendor/shared/dist/abi/token/TaxDistributor.js.map +1 -0
- package/vendor/shared/dist/abi/token/TestFaucet.d.ts +164 -0
- package/vendor/shared/dist/abi/token/TestFaucet.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/TestFaucet.js +215 -0
- package/vendor/shared/dist/abi/token/TestFaucet.js.map +1 -0
- package/vendor/shared/dist/abi/token/index.d.ts +8 -0
- package/vendor/shared/dist/abi/token/index.d.ts.map +1 -0
- package/vendor/shared/dist/abi/token/index.js +8 -0
- package/vendor/shared/dist/abi/token/index.js.map +1 -0
- package/vendor/shared/dist/emission-schedule.d.ts +51 -0
- package/vendor/shared/dist/emission-schedule.d.ts.map +1 -0
- package/vendor/shared/dist/emission-schedule.js +116 -0
- package/vendor/shared/dist/emission-schedule.js.map +1 -0
- package/vendor/shared/dist/index.d.ts +7 -0
- package/vendor/shared/dist/index.d.ts.map +1 -0
- package/vendor/shared/dist/index.js +7 -0
- package/vendor/shared/dist/index.js.map +1 -0
- package/vendor/shared/dist/params/index.d.ts +6 -0
- package/vendor/shared/dist/params/index.d.ts.map +1 -0
- package/vendor/shared/dist/params/index.js +84 -0
- package/vendor/shared/dist/params/index.js.map +1 -0
- package/vendor/shared/dist/protocol-proofs.d.ts +267 -0
- package/vendor/shared/dist/protocol-proofs.d.ts.map +1 -0
- package/vendor/shared/dist/protocol-proofs.js +205 -0
- package/vendor/shared/dist/protocol-proofs.js.map +1 -0
- package/vendor/shared/dist/rules/index.d.ts +204 -0
- package/vendor/shared/dist/rules/index.d.ts.map +1 -0
- package/vendor/shared/dist/rules/index.js +802 -0
- package/vendor/shared/dist/rules/index.js.map +1 -0
- package/vendor/shared/dist/rules/spec-content.d.ts +21 -0
- package/vendor/shared/dist/rules/spec-content.d.ts.map +1 -0
- package/vendor/shared/dist/rules/spec-content.js +90 -0
- package/vendor/shared/dist/rules/spec-content.js.map +1 -0
- package/vendor/shared/dist/rules/task-risk.d.ts +35 -0
- package/vendor/shared/dist/rules/task-risk.d.ts.map +1 -0
- package/vendor/shared/dist/rules/task-risk.js +438 -0
- package/vendor/shared/dist/rules/task-risk.js.map +1 -0
- package/vendor/shared/dist/schemas/domain.d.ts +195 -0
- package/vendor/shared/dist/schemas/domain.d.ts.map +1 -0
- package/vendor/shared/dist/schemas/domain.js +158 -0
- package/vendor/shared/dist/schemas/domain.js.map +1 -0
- package/vendor/shared/dist/schemas/draft.d.ts +730 -0
- package/vendor/shared/dist/schemas/draft.d.ts.map +1 -0
- package/vendor/shared/dist/schemas/draft.js +110 -0
- package/vendor/shared/dist/schemas/draft.js.map +1 -0
- package/vendor/shared/dist/schemas/enums.d.ts +130 -0
- package/vendor/shared/dist/schemas/enums.d.ts.map +1 -0
- package/vendor/shared/dist/schemas/enums.js +63 -0
- package/vendor/shared/dist/schemas/enums.js.map +1 -0
- package/vendor/shared/dist/schemas/index.d.ts +4 -0
- package/vendor/shared/dist/schemas/index.d.ts.map +1 -0
- package/vendor/shared/dist/schemas/index.js +4 -0
- package/vendor/shared/dist/schemas/index.js.map +1 -0
- package/vendor/shared/dist/units.d.ts +10 -0
- package/vendor/shared/dist/units.d.ts.map +1 -0
- package/vendor/shared/dist/units.js +44 -0
- package/vendor/shared/dist/units.js.map +1 -0
- package/vendor/shared/openapi.json +78754 -0
- package/vendor/shared/package.json +43 -0
- package/vendor/shared/params/params.json +152 -0
- package/vendor/shared/params/ranges.json +574 -0
- package/vendor/shared/src/emission-schedule.ts +151 -0
- package/vendor/shared/src/index.ts +6 -0
- package/vendor/shared/src/params/index.ts +139 -0
- package/vendor/shared/src/protocol-proofs.ts +235 -0
- package/vendor/shared/src/rules/index.ts +1081 -0
- package/vendor/shared/src/rules/spec-content.ts +120 -0
- package/vendor/shared/src/rules/task-risk.ts +550 -0
- package/vendor/shared/src/schemas/domain.ts +187 -0
- package/vendor/shared/src/schemas/draft.ts +141 -0
- package/vendor/shared/src/schemas/enums.ts +73 -0
- package/vendor/shared/src/schemas/index.ts +3 -0
- package/vendor/shared/src/units.ts +43 -0
- package/vendor/shared/test/emission-schedule.test.ts +115 -0
- package/vendor/shared/test/fixtures/emission-vectors.json +1055 -0
- package/vendor/shared/test/fixtures.ts +65 -0
- package/vendor/shared/test/params.test.ts +48 -0
- package/vendor/shared/test/properties.test.ts +136 -0
- package/vendor/shared/test/protocol-proofs.test.ts +88 -0
- package/vendor/shared/test/rules.test.ts +474 -0
- package/vendor/shared/test/schemas.test.ts +130 -0
- package/vendor/shared/test/task-risk.test.ts +489 -0
- package/vendor/shared/tsconfig.abi.json +11 -0
- package/vendor/shared/tsconfig.json +23 -0
- package/vendor/shared/types/api/index.d.ts +303 -0
- package/vendor/shared/vitest.config.ts +8 -0
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
import { AcceptanceGrade, AllocationMode, ArbitrationRound, TaskTemplate, Tier, } from "../schemas/index.js";
|
|
2
|
+
import { agtToWei } from "../units.js";
|
|
3
|
+
import { checkSpecContent } from "./spec-content.js";
|
|
4
|
+
export * from "./spec-content.js";
|
|
5
|
+
export * from "./task-risk.js";
|
|
6
|
+
const BPS = 10_000;
|
|
7
|
+
const SECONDS_PER_DAY = 86_400;
|
|
8
|
+
/** ParamRegistry stores fees as whole AGT; we scale to 18-decimal wei for ERC-20 compatibility. */
|
|
9
|
+
const AGT_UNIT = 10n ** 18n;
|
|
10
|
+
const tierRank = { T1: 1, T2: 2, T3: 3, T4: 4, T5: 5 };
|
|
11
|
+
const tiers = [Tier.T1, Tier.T2, Tier.T3, Tier.T4, Tier.T5];
|
|
12
|
+
function parameter(params, key) {
|
|
13
|
+
const value = params[key];
|
|
14
|
+
if (value === null)
|
|
15
|
+
throw new Error(`Parameter ${key} has no numeric value`);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function nonnegative(value, name) {
|
|
19
|
+
if (value < 0n)
|
|
20
|
+
throw new RangeError(`${name} must be nonnegative`);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function bpsDown(value, bps) {
|
|
24
|
+
if (!Number.isInteger(bps) || bps < 0)
|
|
25
|
+
throw new RangeError("bps must be a nonnegative integer");
|
|
26
|
+
return (value * BigInt(bps)) / BigInt(BPS);
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Tier helpers
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/** Returns the tier daily fee in 18-decimal wei (params stores whole AGT). */
|
|
32
|
+
export function tierDailyFee(tier, params) {
|
|
33
|
+
return BigInt(parameter(params, `tierDailyFee.${tier}`)) * AGT_UNIT;
|
|
34
|
+
}
|
|
35
|
+
export function snapshotDailyFees(params) {
|
|
36
|
+
return Object.fromEntries(tiers.map((tier) => [tier, tierDailyFee(tier, params)]));
|
|
37
|
+
}
|
|
38
|
+
/** A task's snapshot fee when known, otherwise the current parameter (only valid before creation). */
|
|
39
|
+
function dailyFee(tier, params, fees) {
|
|
40
|
+
return fees?.[tier] ?? tierDailyFee(tier, params);
|
|
41
|
+
}
|
|
42
|
+
export function tierDaysRange(tier, params) {
|
|
43
|
+
return {
|
|
44
|
+
min: parameter(params, `tierDaysMin.${tier}`),
|
|
45
|
+
max: parameter(params, `tierDaysMax.${tier}`),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function tierBaseQuota(tier, params) {
|
|
49
|
+
if (tierRank[tier] >= 3)
|
|
50
|
+
return parameter(params, "tierBaseQuota.T3");
|
|
51
|
+
return parameter(params, `tierBaseQuota.${tier}`);
|
|
52
|
+
}
|
|
53
|
+
export function tierSubmissionLimit(tier, params) {
|
|
54
|
+
return tierBaseQuota(tier, params) * parameter(params, "submissionMultiplier");
|
|
55
|
+
}
|
|
56
|
+
export function participantLimits(params) {
|
|
57
|
+
return {
|
|
58
|
+
min: parameter(params, "participantsMin"),
|
|
59
|
+
default: parameter(params, "participantsDefault"),
|
|
60
|
+
warning: parameter(params, "participantsWarning"),
|
|
61
|
+
max: parameter(params, "participantsMax"),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** `maxParticipants` value that removes the cap; the task then closes only by deadline or early close. */
|
|
65
|
+
export const UNLIMITED_PARTICIPANTS = 0;
|
|
66
|
+
/** Resolves the publisher's cap independently of task tier; `null` means unlimited. */
|
|
67
|
+
export function resolveParticipantLimit(value, params) {
|
|
68
|
+
const limits = participantLimits(params);
|
|
69
|
+
const resolved = value ?? limits.default;
|
|
70
|
+
if (resolved === UNLIMITED_PARTICIPANTS)
|
|
71
|
+
return null;
|
|
72
|
+
if (!Number.isInteger(resolved) || resolved < limits.min || resolved > limits.max) {
|
|
73
|
+
throw new RangeError(`maxParticipants must be ${UNLIMITED_PARTICIPANTS} (unlimited) or an integer in [${limits.min}, ${limits.max}]`);
|
|
74
|
+
}
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
export function reviewerCount(tier, params) {
|
|
78
|
+
if (tierRank[tier] >= 3)
|
|
79
|
+
return parameter(params, "reviewerCount.T3");
|
|
80
|
+
return parameter(params, `reviewerCount.${tier}`);
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Minimum tier calculation (§3.4)
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
function criteriaTier(criteria) {
|
|
86
|
+
const cCount = criteria.filter(({ grade }) => grade === AcceptanceGrade.C).length;
|
|
87
|
+
const bCount = criteria.filter(({ grade }) => grade === AcceptanceGrade.B).length;
|
|
88
|
+
const total = criteria.length;
|
|
89
|
+
if (total === 0)
|
|
90
|
+
return Tier.T1;
|
|
91
|
+
const cPct = (cCount / total) * 100;
|
|
92
|
+
const bPct = (bCount / total) * 100;
|
|
93
|
+
if (cPct > 30)
|
|
94
|
+
return Tier.T3;
|
|
95
|
+
if (cPct > 0 || bPct > 30)
|
|
96
|
+
return Tier.T2;
|
|
97
|
+
return Tier.T1;
|
|
98
|
+
}
|
|
99
|
+
function hoursTier(hours) {
|
|
100
|
+
if (hours <= 1)
|
|
101
|
+
return Tier.T1;
|
|
102
|
+
if (hours <= 6)
|
|
103
|
+
return Tier.T2;
|
|
104
|
+
if (hours <= 72)
|
|
105
|
+
return Tier.T3;
|
|
106
|
+
if (hours <= 168)
|
|
107
|
+
return Tier.T4;
|
|
108
|
+
return Tier.T5;
|
|
109
|
+
}
|
|
110
|
+
function templateBaseline(template) {
|
|
111
|
+
if (template === TaskTemplate.Translation || template === TaskTemplate.DataProcessing)
|
|
112
|
+
return Tier.T1;
|
|
113
|
+
if (template === TaskTemplate.Research)
|
|
114
|
+
return Tier.T2;
|
|
115
|
+
if (template === TaskTemplate.CodeFix)
|
|
116
|
+
return Tier.T3;
|
|
117
|
+
return Tier.T1;
|
|
118
|
+
}
|
|
119
|
+
function maxTier(...levels) {
|
|
120
|
+
return levels.reduce((highest, level) => (tierRank[level] > tierRank[highest] ? level : highest));
|
|
121
|
+
}
|
|
122
|
+
export function computeMinimumTier(input) {
|
|
123
|
+
return maxTier(criteriaTier(input.criteria), hoursTier(input.estimatedHours), templateBaseline(input.template));
|
|
124
|
+
}
|
|
125
|
+
export function computeTierRangeMax(minimumTier, params) {
|
|
126
|
+
const offset = parameter(params, "tierRangeOffset");
|
|
127
|
+
const maxRank = Math.min(tierRank[minimumTier] + offset, 5);
|
|
128
|
+
return tiers[maxRank - 1];
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Reserve & deduction (§4.1–4.3)
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
export function computeReserve(maxTier, runDays, params) {
|
|
134
|
+
if (runDays <= 0)
|
|
135
|
+
throw new RangeError("runDays must be positive");
|
|
136
|
+
return tierDailyFee(maxTier, params) * BigInt(runDays);
|
|
137
|
+
}
|
|
138
|
+
export function computeDeduction(lockedTier, billedSeconds, params, fees) {
|
|
139
|
+
nonnegative(billedSeconds, "billedSeconds");
|
|
140
|
+
const fee = dailyFee(lockedTier, params, fees);
|
|
141
|
+
return (fee * billedSeconds) / BigInt(SECONDS_PER_DAY);
|
|
142
|
+
}
|
|
143
|
+
export function computeSegmentedDeduction(segments, params, fees) {
|
|
144
|
+
let total = 0n;
|
|
145
|
+
for (const seg of segments) {
|
|
146
|
+
nonnegative(seg.seconds, "segment.seconds");
|
|
147
|
+
total += (dailyFee(seg.tier, params, fees) * seg.seconds) / BigInt(SECONDS_PER_DAY);
|
|
148
|
+
}
|
|
149
|
+
return total;
|
|
150
|
+
}
|
|
151
|
+
export function computeSubmissionScore(criterionScores, passingThreshold, params) {
|
|
152
|
+
let weighted = 0;
|
|
153
|
+
let allAPass = true;
|
|
154
|
+
for (const cs of criterionScores) {
|
|
155
|
+
weighted += cs.weightBps * cs.score;
|
|
156
|
+
if (cs.grade === AcceptanceGrade.A && cs.score < 1)
|
|
157
|
+
allAPass = false;
|
|
158
|
+
}
|
|
159
|
+
const total = weighted / BPS;
|
|
160
|
+
const junk = parameter(params, "junkThreshold");
|
|
161
|
+
const isJunk = total < junk;
|
|
162
|
+
return {
|
|
163
|
+
total,
|
|
164
|
+
passes: allAPass && total >= passingThreshold,
|
|
165
|
+
isJunk,
|
|
166
|
+
rewardEligible: allAPass && !isJunk,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function allocateExecutorPool(pool, scores, mode, topK) {
|
|
170
|
+
nonnegative(pool, "pool");
|
|
171
|
+
const passing = scores.filter((s) => s.passes).sort((a, b) => b.score - a.score);
|
|
172
|
+
if (passing.length === 0)
|
|
173
|
+
return [];
|
|
174
|
+
let weights;
|
|
175
|
+
if (mode === AllocationMode.WinnerTakesAll) {
|
|
176
|
+
const maxScore = passing[0].score;
|
|
177
|
+
const winners = passing.filter((s) => s.score === maxScore);
|
|
178
|
+
const w = 1 / winners.length;
|
|
179
|
+
weights = winners.map((s) => ({ submissionIndex: s.submissionIndex, weight: w }));
|
|
180
|
+
}
|
|
181
|
+
else if (mode === AllocationMode.TopK) {
|
|
182
|
+
const k = topK ?? 1;
|
|
183
|
+
const selected = passing.slice(0, k);
|
|
184
|
+
if (selected.length < k) {
|
|
185
|
+
const w = 1 / selected.length;
|
|
186
|
+
weights = selected.map((s) => ({ submissionIndex: s.submissionIndex, weight: w }));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const lastScore = selected[selected.length - 1].score;
|
|
190
|
+
const beforeLast = selected.filter((s) => s.score > lastScore);
|
|
191
|
+
const tied = passing.filter((s) => s.score === lastScore);
|
|
192
|
+
const remainingSlots = k - beforeLast.length;
|
|
193
|
+
const wBefore = 1 / k;
|
|
194
|
+
const wTied = remainingSlots / (k * tied.length);
|
|
195
|
+
weights = [
|
|
196
|
+
...beforeLast.map((s) => ({ submissionIndex: s.submissionIndex, weight: wBefore })),
|
|
197
|
+
...tied.map((s) => ({ submissionIndex: s.submissionIndex, weight: wTied })),
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
const totalScore = passing.reduce((sum, s) => sum + s.score, 0);
|
|
203
|
+
if (totalScore === 0) {
|
|
204
|
+
const w = 1 / passing.length;
|
|
205
|
+
weights = passing.map((s) => ({ submissionIndex: s.submissionIndex, weight: w }));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
weights = passing.map((s) => ({
|
|
209
|
+
submissionIndex: s.submissionIndex,
|
|
210
|
+
weight: s.score / totalScore,
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
let allocated = 0n;
|
|
215
|
+
const results = weights.map((w, i) => {
|
|
216
|
+
const amount = i === weights.length - 1
|
|
217
|
+
? pool - allocated
|
|
218
|
+
: (pool * BigInt(Math.floor(w.weight * 1_000_000_000))) / 1000000000n;
|
|
219
|
+
allocated += amount;
|
|
220
|
+
return { submissionIndex: w.submissionIndex, weight: w.weight, amount };
|
|
221
|
+
});
|
|
222
|
+
return results;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* V4 executor allocation. Every valid, non-junk result participates and receives a
|
|
226
|
+
* score-proportional share; the final item absorbs integer division dust.
|
|
227
|
+
*/
|
|
228
|
+
export function allocateProRataExecutorPool(pool, scores) {
|
|
229
|
+
nonnegative(pool, "pool");
|
|
230
|
+
const eligible = scores
|
|
231
|
+
.filter(({ rewardEligible }) => rewardEligible)
|
|
232
|
+
.sort((left, right) => right.score - left.score || left.submissionIndex - right.submissionIndex);
|
|
233
|
+
if (eligible.length === 0)
|
|
234
|
+
return [];
|
|
235
|
+
const scaled = eligible.map((entry) => ({
|
|
236
|
+
...entry,
|
|
237
|
+
units: BigInt(Math.max(1, Math.round(entry.score * 1_000_000))),
|
|
238
|
+
}));
|
|
239
|
+
const participantCount = BigInt(scaled.length);
|
|
240
|
+
if (pool < participantCount)
|
|
241
|
+
return [];
|
|
242
|
+
const distributable = pool - participantCount;
|
|
243
|
+
const totalUnits = scaled.reduce((sum, entry) => sum + entry.units, 0n);
|
|
244
|
+
let distributed = 0n;
|
|
245
|
+
return scaled.map((entry, index) => {
|
|
246
|
+
const proportional = index === scaled.length - 1
|
|
247
|
+
? distributable - distributed
|
|
248
|
+
: (distributable * entry.units) / totalUnits;
|
|
249
|
+
distributed += proportional;
|
|
250
|
+
return {
|
|
251
|
+
submissionIndex: entry.submissionIndex,
|
|
252
|
+
weight: Number(entry.units) / Number(totalUnits),
|
|
253
|
+
amount: 1n + proportional,
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Vesting (§4.10)
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
export function vestingSchedule(amount, acceptedAtSeconds, params) {
|
|
261
|
+
nonnegative(amount, "amount");
|
|
262
|
+
if (!Number.isInteger(acceptedAtSeconds) || acceptedAtSeconds < 0)
|
|
263
|
+
throw new RangeError("acceptedAtSeconds must be a nonneg integer");
|
|
264
|
+
const t0Bps = parameter(params, "vestingT0Bps");
|
|
265
|
+
const t1Bps = parameter(params, "vestingT1Bps");
|
|
266
|
+
const t0 = bpsDown(amount, t0Bps);
|
|
267
|
+
const t1 = bpsDown(amount, t1Bps);
|
|
268
|
+
const t2 = amount - t0 - t1;
|
|
269
|
+
return [
|
|
270
|
+
{ amount: t0, releaseAtSeconds: acceptedAtSeconds },
|
|
271
|
+
{
|
|
272
|
+
amount: t1,
|
|
273
|
+
releaseAtSeconds: acceptedAtSeconds + parameter(params, "vestingT1Days") * SECONDS_PER_DAY,
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
amount: t2,
|
|
277
|
+
releaseAtSeconds: acceptedAtSeconds + parameter(params, "vestingT2Days") * SECONDS_PER_DAY,
|
|
278
|
+
},
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
/** Split an arbitrary emission amount by frozen (or params) bps; arb is remainder. */
|
|
282
|
+
export function splitEmission(amount, params) {
|
|
283
|
+
nonnegative(amount, "amount");
|
|
284
|
+
const platform = bpsDown(amount, parameter(params, "emissionPlatformBps"));
|
|
285
|
+
const executor = bpsDown(amount, parameter(params, "emissionExecBps"));
|
|
286
|
+
const tester = bpsDown(amount, parameter(params, "emissionTestBps"));
|
|
287
|
+
const arbitrator = amount - platform - executor - tester;
|
|
288
|
+
return { platform, executor, tester, arbitrator, total: amount };
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Task share of an hour's executor emission, proportional to fee weight.
|
|
292
|
+
* `P_i = hourExec · fee / Σ fee` (floor). Window-second weighting is applied by the caller.
|
|
293
|
+
*/
|
|
294
|
+
export function executorPoolShare(hourExec, taskFeeWei, totalRunningFeesWei) {
|
|
295
|
+
nonnegative(hourExec, "hourExec");
|
|
296
|
+
nonnegative(taskFeeWei, "taskFeeWei");
|
|
297
|
+
nonnegative(totalRunningFeesWei, "totalRunningFeesWei");
|
|
298
|
+
if (totalRunningFeesWei === 0n || taskFeeWei === 0n)
|
|
299
|
+
return 0n;
|
|
300
|
+
return (hourExec * taskFeeWei) / totalRunningFeesWei;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Seat share of an hour's tester emission, proportional to seat weight.
|
|
304
|
+
* `T_s = hourTest · seatWeight / Σ seatWeight` (floor).
|
|
305
|
+
*/
|
|
306
|
+
export function testerSeatShare(hourTest, seatWeight, totalSeatWeight) {
|
|
307
|
+
nonnegative(hourTest, "hourTest");
|
|
308
|
+
nonnegative(seatWeight, "seatWeight");
|
|
309
|
+
nonnegative(totalSeatWeight, "totalSeatWeight");
|
|
310
|
+
if (totalSeatWeight === 0n || seatWeight === 0n)
|
|
311
|
+
return 0n;
|
|
312
|
+
return (hourTest * seatWeight) / totalSeatWeight;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Allocate a task executor pool by score using largest-remainder method (§4.4 / §4.7.1).
|
|
316
|
+
* Eligible set E: rewardEligible submissions. Empty E → empty allocation (caller burns pool).
|
|
317
|
+
*/
|
|
318
|
+
export function allocateByScore(pool, scores) {
|
|
319
|
+
nonnegative(pool, "pool");
|
|
320
|
+
const set = scores
|
|
321
|
+
.filter(({ rewardEligible }) => rewardEligible)
|
|
322
|
+
.sort((a, b) => b.score - a.score || a.submissionIndex - b.submissionIndex);
|
|
323
|
+
if (set.length === 0)
|
|
324
|
+
return [];
|
|
325
|
+
const totalScore = set.reduce((sum, entry) => sum + entry.score, 0);
|
|
326
|
+
if (totalScore <= 0) {
|
|
327
|
+
const even = pool / BigInt(set.length);
|
|
328
|
+
let distributed = 0n;
|
|
329
|
+
return set.map((entry, index) => {
|
|
330
|
+
const amount = index === set.length - 1 ? pool - distributed : even;
|
|
331
|
+
distributed += amount;
|
|
332
|
+
return { submissionIndex: entry.submissionIndex, weight: 1 / set.length, amount };
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
// Largest-remainder: floor shares then distribute remainder by fractional part.
|
|
336
|
+
const SCALE = 1000000n;
|
|
337
|
+
const units = set.map((entry) => ({
|
|
338
|
+
...entry,
|
|
339
|
+
units: BigInt(Math.max(0, Math.round(entry.score * Number(SCALE)))),
|
|
340
|
+
}));
|
|
341
|
+
const totalUnits = units.reduce((sum, entry) => sum + entry.units, 0n);
|
|
342
|
+
if (totalUnits === 0n)
|
|
343
|
+
return [];
|
|
344
|
+
const floors = units.map((entry) => {
|
|
345
|
+
const raw = (pool * entry.units) / totalUnits;
|
|
346
|
+
const remainder = (pool * entry.units) % totalUnits;
|
|
347
|
+
return { ...entry, amount: raw, remainder, weight: Number(entry.units) / Number(totalUnits) };
|
|
348
|
+
});
|
|
349
|
+
let remaining = pool - floors.reduce((sum, entry) => sum + entry.amount, 0n);
|
|
350
|
+
for (const entry of floors
|
|
351
|
+
.slice()
|
|
352
|
+
.sort((a, b) => b.remainder > a.remainder
|
|
353
|
+
? 1
|
|
354
|
+
: b.remainder < a.remainder
|
|
355
|
+
? -1
|
|
356
|
+
: a.submissionIndex - b.submissionIndex)) {
|
|
357
|
+
if (remaining <= 0n)
|
|
358
|
+
break;
|
|
359
|
+
entry.amount += 1n;
|
|
360
|
+
remaining -= 1n;
|
|
361
|
+
}
|
|
362
|
+
return floors.map(({ submissionIndex, weight, amount }) => ({ submissionIndex, weight, amount }));
|
|
363
|
+
}
|
|
364
|
+
/** Vesting tranches for executor mining share (§4.10): 60% / 25% / 15% at T0 / +7d / +30d. */
|
|
365
|
+
export function vestingTranches(amount, t0Seconds, params) {
|
|
366
|
+
return vestingSchedule(amount, t0Seconds, params);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Arbitrator weight (§4.7.3):
|
|
370
|
+
* min(stake, cap) × responseRate + Σ arbitratorMinStake × arbCaseBonusBps[tier] / 10000
|
|
371
|
+
* responseRateBps is 0–10000.
|
|
372
|
+
*/
|
|
373
|
+
export function computeArbitratorWeight(stakeWei, responseRateBps, activeSeats, params) {
|
|
374
|
+
nonnegative(stakeWei, "stakeWei");
|
|
375
|
+
if (!Number.isInteger(responseRateBps) || responseRateBps < 0 || responseRateBps > BPS) {
|
|
376
|
+
throw new RangeError("responseRateBps must be an integer in [0, 10000]");
|
|
377
|
+
}
|
|
378
|
+
const cap = agtToWei(parameter(params, "arbitratorWeightCapAgt"));
|
|
379
|
+
const capped = stakeWei < cap ? stakeWei : cap;
|
|
380
|
+
const base = (capped * BigInt(responseRateBps)) / BigInt(BPS);
|
|
381
|
+
const minStake = agtToWei(parameter(params, "arbitratorMinStakeAgt"));
|
|
382
|
+
let bonus = 0n;
|
|
383
|
+
for (const seat of activeSeats) {
|
|
384
|
+
const bps = parameter(params, `arbCaseBonusBps.${seat.tier}`);
|
|
385
|
+
bonus += bpsDown(minStake, bps);
|
|
386
|
+
}
|
|
387
|
+
return base + bonus;
|
|
388
|
+
}
|
|
389
|
+
export function computeTaskDailyEmission(taskBilledToday, totalBilledToday, dailyEmission, taskCumulativeEmission, taskCumulativeDeduction, params) {
|
|
390
|
+
nonnegative(taskBilledToday, "taskBilledToday");
|
|
391
|
+
nonnegative(totalBilledToday, "totalBilledToday");
|
|
392
|
+
nonnegative(dailyEmission, "dailyEmission");
|
|
393
|
+
nonnegative(taskCumulativeEmission, "taskCumulativeEmission");
|
|
394
|
+
nonnegative(taskCumulativeDeduction, "taskCumulativeDeduction");
|
|
395
|
+
const rhoBps = 8000;
|
|
396
|
+
const uBps = parameter(params, "unrecoverableCostBps");
|
|
397
|
+
const rho = rhoBps / BPS;
|
|
398
|
+
const u = uBps / BPS;
|
|
399
|
+
if (totalBilledToday === 0n) {
|
|
400
|
+
return {
|
|
401
|
+
taskBilled: taskBilledToday,
|
|
402
|
+
totalBilled: totalBilledToday,
|
|
403
|
+
dailyEmission,
|
|
404
|
+
rho,
|
|
405
|
+
u,
|
|
406
|
+
taskEmission: 0n,
|
|
407
|
+
capped: false,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const rateNumerator = dailyEmission;
|
|
411
|
+
const rateDenominator = totalBilledToday;
|
|
412
|
+
const rhoU = BigInt(Math.floor(rho * u * BPS));
|
|
413
|
+
const maxRate = rhoU;
|
|
414
|
+
let rate;
|
|
415
|
+
if (rateNumerator * BigInt(BPS) <= maxRate * rateDenominator) {
|
|
416
|
+
rate = rateNumerator;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
rate = (maxRate * rateDenominator) / BigInt(BPS);
|
|
420
|
+
}
|
|
421
|
+
let taskEm = (rate * taskBilledToday) / rateDenominator;
|
|
422
|
+
const hardCap = bpsDown(taskCumulativeDeduction, Math.floor(rho * u * BPS));
|
|
423
|
+
let capped = false;
|
|
424
|
+
if (taskCumulativeEmission + taskEm > hardCap) {
|
|
425
|
+
taskEm = hardCap > taskCumulativeEmission ? hardCap - taskCumulativeEmission : 0n;
|
|
426
|
+
capped = true;
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
taskBilled: taskBilledToday,
|
|
430
|
+
totalBilled: totalBilledToday,
|
|
431
|
+
dailyEmission,
|
|
432
|
+
rho,
|
|
433
|
+
u,
|
|
434
|
+
taskEmission: taskEm,
|
|
435
|
+
capped,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
// Escalation (§3.4)
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
export function computeEscalationStep(runDays, params) {
|
|
442
|
+
const pctBps = parameter(params, "escalationStepPctBps");
|
|
443
|
+
const minHours = parameter(params, "escalationStepMinHours");
|
|
444
|
+
const stepHours = Math.max(minHours, (runDays * 24 * pctBps) / BPS);
|
|
445
|
+
return stepHours * 3600;
|
|
446
|
+
}
|
|
447
|
+
export function computeCurrentTier(startTier, maxTier, publishedAtSeconds, nowSeconds, escalationStepSeconds) {
|
|
448
|
+
if (escalationStepSeconds <= 0)
|
|
449
|
+
throw new RangeError("step must be positive");
|
|
450
|
+
const elapsed = nowSeconds - publishedAtSeconds;
|
|
451
|
+
if (elapsed < 0)
|
|
452
|
+
return startTier;
|
|
453
|
+
const steps = Math.floor(elapsed / escalationStepSeconds);
|
|
454
|
+
const rank = Math.min(tierRank[startTier] + steps, tierRank[maxTier]);
|
|
455
|
+
return tiers[rank - 1];
|
|
456
|
+
}
|
|
457
|
+
export function computeEarliestSubmitSeconds(runDays, params) {
|
|
458
|
+
const pctBps = parameter(params, "earliestSubmitPctBps");
|
|
459
|
+
const hours = (runDays * 24 * pctBps) / BPS;
|
|
460
|
+
const minH = parameter(params, "earliestSubmitMinHours");
|
|
461
|
+
const maxH = parameter(params, "earliestSubmitMaxHours");
|
|
462
|
+
return Math.max(minH, Math.min(maxH, hours)) * 3600;
|
|
463
|
+
}
|
|
464
|
+
// ---------------------------------------------------------------------------
|
|
465
|
+
// Publisher stake (§5.2)
|
|
466
|
+
// ---------------------------------------------------------------------------
|
|
467
|
+
/** Amounts in wei. Mirrors PublisherStaking.reserve: base + ⌈β·(in-flight + next)⌉, and the balance must cover the reserve. */
|
|
468
|
+
export function checkPublisherStake(input, params) {
|
|
469
|
+
nonnegative(input.actualStake, "actualStake");
|
|
470
|
+
nonnegative(input.inFlightReserves, "inFlightReserves");
|
|
471
|
+
nonnegative(input.nextReserve, "nextReserve");
|
|
472
|
+
const beta = BigInt(parameter(params, "publisherExposureBps"));
|
|
473
|
+
const exposure = input.inFlightReserves + input.nextReserve;
|
|
474
|
+
const minStake = agtToWei(parameter(params, "publisherBaseStakeAgt")) +
|
|
475
|
+
(exposure * beta + BigInt(BPS) - 1n) / BigInt(BPS);
|
|
476
|
+
const required = minStake > input.nextReserve ? minStake : input.nextReserve;
|
|
477
|
+
return { required, available: input.actualStake, ok: input.actualStake >= required };
|
|
478
|
+
}
|
|
479
|
+
/** Fixed role threshold in wei; matches ValidatorStaking.minimumStake(role). */
|
|
480
|
+
export function validatorRoleMinimum(role, params) {
|
|
481
|
+
return agtToWei(parameter(params, role === "TESTER" ? "testerMinStakeAgt" : "arbitratorMinStakeAgt"));
|
|
482
|
+
}
|
|
483
|
+
/** Roles the stake currently qualifies for; matches ValidatorStaking.meetsMinimum (ignoring exit/ban). */
|
|
484
|
+
export function qualifiedValidatorRoles(stake, params) {
|
|
485
|
+
nonnegative(stake, "stake");
|
|
486
|
+
if (stake === 0n)
|
|
487
|
+
return [];
|
|
488
|
+
const roles = [];
|
|
489
|
+
if (stake >= validatorRoleMinimum("TESTER", params))
|
|
490
|
+
roles.push("TESTER");
|
|
491
|
+
if (stake >= validatorRoleMinimum("ARBITRATOR", params))
|
|
492
|
+
roles.push("ARBITRATOR");
|
|
493
|
+
return roles;
|
|
494
|
+
}
|
|
495
|
+
/** Linear draw weight before response/activity factors: min(stake, role cap). */
|
|
496
|
+
export function validatorDrawWeight(stake, role, params) {
|
|
497
|
+
nonnegative(stake, "stake");
|
|
498
|
+
const cap = agtToWei(parameter(params, role === "TESTER" ? "testerWeightCapAgt" : "arbitratorWeightCapAgt"));
|
|
499
|
+
return stake < cap ? stake : cap;
|
|
500
|
+
}
|
|
501
|
+
/** §7.6 missed report: min(multiple × reward, stakeCapBps × stake), all wei. */
|
|
502
|
+
export function computeTesterMissReportSlash(testerReward, testerStake, params) {
|
|
503
|
+
nonnegative(testerReward, "testerReward");
|
|
504
|
+
nonnegative(testerStake, "testerStake");
|
|
505
|
+
const byReward = testerReward * BigInt(parameter(params, "testerMissReportSlashMultiple"));
|
|
506
|
+
const byStake = bpsDown(testerStake, parameter(params, "testerSlashStakeCapBps"));
|
|
507
|
+
return byReward < byStake ? byReward : byStake;
|
|
508
|
+
}
|
|
509
|
+
// ---------------------------------------------------------------------------
|
|
510
|
+
// Arbitration capacity (03-STAKING-PENALTY-SPEC §5)
|
|
511
|
+
// ---------------------------------------------------------------------------
|
|
512
|
+
/** Largest dispute a task can produce: the executor pool share of its reserve (wei). */
|
|
513
|
+
export function computeDisputeBound(reserve, params) {
|
|
514
|
+
nonnegative(reserve, "reserve");
|
|
515
|
+
return bpsDown(reserve, parameter(params, "deductionExecBps"));
|
|
516
|
+
}
|
|
517
|
+
/** Matches CourtRules.maxDisputeValue: fallback ceiling below the pool minimum, else threshold × mode multiplier. */
|
|
518
|
+
export function computeMaxDisputeValue(pool, params) {
|
|
519
|
+
if (pool.eligibleArbitrators < parameter(params, "arbMinimumPoolSize")) {
|
|
520
|
+
return agtToWei(parameter(params, "arbFallbackMaxDisputeValueAgt"));
|
|
521
|
+
}
|
|
522
|
+
const multiplier = parameter(params, pool.fullScale ? "arbExposureMultiplierBps.Full" : "arbExposureMultiplierBps.Degraded");
|
|
523
|
+
return bpsDown(validatorRoleMinimum("ARBITRATOR", params), multiplier);
|
|
524
|
+
}
|
|
525
|
+
// ---------------------------------------------------------------------------
|
|
526
|
+
// Arbitration panel (§7.1)
|
|
527
|
+
// ---------------------------------------------------------------------------
|
|
528
|
+
export function arbitrationPanel(eligibleArbitrators, round, params) {
|
|
529
|
+
if (!Number.isInteger(eligibleArbitrators) || eligibleArbitrators < 0)
|
|
530
|
+
throw new RangeError("eligibleArbitrators must be nonnegative");
|
|
531
|
+
if (eligibleArbitrators < parameter(params, "arbMinimumPoolSize")) {
|
|
532
|
+
return { enabled: false, panelSize: 0, majority: 0, minReveal: 0 };
|
|
533
|
+
}
|
|
534
|
+
const full = eligibleArbitrators >= parameter(params, "arbFullPanelThreshold");
|
|
535
|
+
const panelSize = (full
|
|
536
|
+
? round === ArbitrationRound.First
|
|
537
|
+
? parameter(params, "arbPanelSize.FullFirst")
|
|
538
|
+
: parameter(params, "arbPanelSize.FullFinal")
|
|
539
|
+
: round === ArbitrationRound.First
|
|
540
|
+
? parameter(params, "arbPanelSize.DegradedFirst")
|
|
541
|
+
: parameter(params, "arbPanelSize.DegradedFinal"));
|
|
542
|
+
return {
|
|
543
|
+
enabled: true,
|
|
544
|
+
panelSize,
|
|
545
|
+
majority: Math.floor(panelSize / 2) + 1,
|
|
546
|
+
minReveal: Math.ceil((parameter(params, "arbMinRevealBps") * panelSize) / BPS),
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
export function t1FallbackPanel(params) {
|
|
550
|
+
return {
|
|
551
|
+
panelSize: parameter(params, "arbFallbackTesterCount"),
|
|
552
|
+
approvalCount: parameter(params, "arbFallbackApprovalCount"),
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
// ---------------------------------------------------------------------------
|
|
556
|
+
// Case fee & bond
|
|
557
|
+
// ---------------------------------------------------------------------------
|
|
558
|
+
/** Dispute value in wei → case fee in wei; matches ArbitrationCourt.quoteCaseFee. */
|
|
559
|
+
export function computeCaseFee(disputeValue, params) {
|
|
560
|
+
const proportional = bpsDown(disputeValue, parameter(params, "caseFeeBps"));
|
|
561
|
+
const minimum = agtToWei(parameter(params, "caseFeeMinAgt"));
|
|
562
|
+
return proportional > minimum ? proportional : minimum;
|
|
563
|
+
}
|
|
564
|
+
/** Appeal bond in wei: caseFee × appealBondMultiplierBps / 10000; matches ArbitrationCourt.appealBondOf. */
|
|
565
|
+
export function computeAppealBond(caseFee, params) {
|
|
566
|
+
nonnegative(caseFee, "caseFee");
|
|
567
|
+
return bpsDown(caseFee, parameter(params, "appealBondMultiplierBps"));
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Economic model v3 appeal fee (§7.3): min(appealFeeBps · F_t* / 10000, appealFeeCapAgt).
|
|
571
|
+
* Charged per appealed submission; paid entirely to revealed arbitrators.
|
|
572
|
+
*/
|
|
573
|
+
export function computeAppealFee(lockedTier, params, fees) {
|
|
574
|
+
const proportional = bpsDown(dailyFee(lockedTier, params, fees), parameter(params, "appealFeeBps"));
|
|
575
|
+
const cap = agtToWei(parameter(params, "appealFeeCapAgt"));
|
|
576
|
+
return proportional < cap ? proportional : cap;
|
|
577
|
+
}
|
|
578
|
+
/** Final appeal fee is 2× the first-round appeal fee. */
|
|
579
|
+
export function computeFinalAppealFee(lockedTier, params, fees) {
|
|
580
|
+
return computeAppealFee(lockedTier, params, fees) * 2n;
|
|
581
|
+
}
|
|
582
|
+
export function computeCaseLock(disputeValue, validatorStake, params) {
|
|
583
|
+
const proportional = bpsDown(disputeValue, parameter(params, "caseLockBps"));
|
|
584
|
+
const minimum = agtToWei(parameter(params, "caseLockMinAgt"));
|
|
585
|
+
const capped = bpsDown(validatorStake, parameter(params, "caseLockStakeCapBps"));
|
|
586
|
+
const desired = proportional > minimum ? proportional : minimum;
|
|
587
|
+
return desired < capped ? desired : capped;
|
|
588
|
+
}
|
|
589
|
+
/** The remainder after majority and winner shares goes to the platform treasury (nothing is burned). */
|
|
590
|
+
export function splitCaseFee(caseFee, params) {
|
|
591
|
+
nonnegative(caseFee, "caseFee");
|
|
592
|
+
const majority = bpsDown(caseFee, parameter(params, "caseFeeMajorityShareBps"));
|
|
593
|
+
const winner = bpsDown(caseFee, parameter(params, "caseFeeWinnerShareBps"));
|
|
594
|
+
return { majority, winner, platform: caseFee - majority - winner };
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* §7.3 overturn: the first-round majority's confiscated locks `Z` pay the challenger
|
|
598
|
+
* min(challengerRewardMultiple × R, Z) with R = caseFee × majority share ÷ final majority count;
|
|
599
|
+
* the rest splits platform / righteous jurors. Matches ArbitrationSettlement._slashOverturned.
|
|
600
|
+
*/
|
|
601
|
+
export function splitOverturnPenalty(confiscated, caseFee, finalMajorityCount, params) {
|
|
602
|
+
nonnegative(confiscated, "confiscated");
|
|
603
|
+
nonnegative(caseFee, "caseFee");
|
|
604
|
+
if (!Number.isInteger(finalMajorityCount) || finalMajorityCount < 1)
|
|
605
|
+
throw new RangeError("finalMajorityCount must be positive");
|
|
606
|
+
const perSeat = bpsDown(caseFee, parameter(params, "caseFeeMajorityShareBps")) / BigInt(finalMajorityCount);
|
|
607
|
+
const multiple = perSeat * BigInt(parameter(params, "challengerRewardMultiple"));
|
|
608
|
+
const challenger = multiple < confiscated ? multiple : confiscated;
|
|
609
|
+
const rest = confiscated - challenger;
|
|
610
|
+
const platform = bpsDown(rest, parameter(params, "overturnPlatformShareBps"));
|
|
611
|
+
return { challenger, platform, righteous: rest - platform };
|
|
612
|
+
}
|
|
613
|
+
export function testerPairDecay(encounterCount, params) {
|
|
614
|
+
if (!Number.isInteger(encounterCount) || encounterCount < 1)
|
|
615
|
+
throw new RangeError("encounterCount must be positive");
|
|
616
|
+
const position = Math.min(encounterCount, 5);
|
|
617
|
+
return parameter(params, `testerPairDecayBps.${position}`);
|
|
618
|
+
}
|
|
619
|
+
// ---------------------------------------------------------------------------
|
|
620
|
+
// Anti-wash proof (§4.8)
|
|
621
|
+
// ---------------------------------------------------------------------------
|
|
622
|
+
/** @deprecated Safety-coeff anti-wash gate removed with continuous emission; kept for callers. */
|
|
623
|
+
export function antiWashCheck(params) {
|
|
624
|
+
const u = parameter(params, "unrecoverableCostBps");
|
|
625
|
+
return { unrecoverableBps: u, maxEmissionBps: 0, ok: true };
|
|
626
|
+
}
|
|
627
|
+
// ---------------------------------------------------------------------------
|
|
628
|
+
// Draft check (§3.2)
|
|
629
|
+
// ---------------------------------------------------------------------------
|
|
630
|
+
export function checkDraft(draft, params) {
|
|
631
|
+
const results = [];
|
|
632
|
+
const required = [
|
|
633
|
+
"title",
|
|
634
|
+
"summary",
|
|
635
|
+
"template",
|
|
636
|
+
"deliverables",
|
|
637
|
+
"criteria",
|
|
638
|
+
"estimatedHours",
|
|
639
|
+
"startTier",
|
|
640
|
+
"maxTier",
|
|
641
|
+
"runDays",
|
|
642
|
+
"maxParticipants",
|
|
643
|
+
"passingThreshold",
|
|
644
|
+
];
|
|
645
|
+
const missing = required.filter((name) => draft.fields[name].value === null || draft.fields[name].confirmation !== "confirmed");
|
|
646
|
+
results.push({
|
|
647
|
+
id: "draft.completeness",
|
|
648
|
+
level: missing.length === 0 ? "ok" : "block",
|
|
649
|
+
message: missing.length === 0
|
|
650
|
+
? "Required fields are confirmed"
|
|
651
|
+
: `Unconfirmed fields: ${missing.join(", ")}`,
|
|
652
|
+
fields: [...missing],
|
|
653
|
+
});
|
|
654
|
+
const draftCriteria = draft.fields.criteria.value;
|
|
655
|
+
const criteria = draftCriteria?.flatMap((criterion) => (criterion.value === null ? [] : [criterion.value])) ??
|
|
656
|
+
null;
|
|
657
|
+
const criteriaConfirmed = draftCriteria?.every((criterion) => criterion.value !== null && criterion.confirmation === "confirmed") ?? false;
|
|
658
|
+
results.push({
|
|
659
|
+
id: "criteria.confirmed",
|
|
660
|
+
level: criteriaConfirmed ? "ok" : "block",
|
|
661
|
+
message: criteriaConfirmed
|
|
662
|
+
? "Every criterion is confirmed"
|
|
663
|
+
: "Every criterion must be present and confirmed",
|
|
664
|
+
fields: ["criteria"],
|
|
665
|
+
});
|
|
666
|
+
results.push(...checkSpecContent({
|
|
667
|
+
title: draft.fields.title.value,
|
|
668
|
+
summary: draft.fields.summary.value,
|
|
669
|
+
deliverables: draft.fields.deliverables.value,
|
|
670
|
+
constraints: draft.fields.constraints.value,
|
|
671
|
+
inputs: draft.fields.inputs.value,
|
|
672
|
+
criteria,
|
|
673
|
+
}));
|
|
674
|
+
const ruleFieldsValid = ["minimumTier", "cost", "allocationMode"].every((name) => draft.fields[name].source === "rule" && draft.fields[name].value !== null);
|
|
675
|
+
results.push({
|
|
676
|
+
id: "rule.sources",
|
|
677
|
+
level: ruleFieldsValid ? "ok" : "block",
|
|
678
|
+
message: ruleFieldsValid
|
|
679
|
+
? "Derived fields are present and rule-sourced"
|
|
680
|
+
: "Derived fields must be present and rule-sourced",
|
|
681
|
+
fields: ["minimumTier", "cost", "allocationMode"],
|
|
682
|
+
});
|
|
683
|
+
const weights = criteria?.reduce((sum, criterion) => sum + criterion.weightBps, 0) ?? 0;
|
|
684
|
+
results.push({
|
|
685
|
+
id: "criteria.weights",
|
|
686
|
+
level: weights === 10_000 ? "ok" : "block",
|
|
687
|
+
message: weights === 10_000
|
|
688
|
+
? "Criterion weights total 10000 bps"
|
|
689
|
+
: "Criterion weights must total 10000 bps",
|
|
690
|
+
fields: ["criteria"],
|
|
691
|
+
});
|
|
692
|
+
const idsUnique = criteria !== null && new Set(criteria.map(({ id }) => id)).size === criteria.length;
|
|
693
|
+
results.push({
|
|
694
|
+
id: "criteria.ids",
|
|
695
|
+
level: idsUnique ? "ok" : "block",
|
|
696
|
+
message: idsUnique ? "Criterion IDs are unique" : "Criterion IDs must be unique",
|
|
697
|
+
fields: ["criteria"],
|
|
698
|
+
});
|
|
699
|
+
if (criteria !== null &&
|
|
700
|
+
draft.fields.estimatedHours.value !== null &&
|
|
701
|
+
draft.fields.template.value !== null &&
|
|
702
|
+
draft.fields.startTier.value !== null &&
|
|
703
|
+
draft.fields.maxTier.value !== null &&
|
|
704
|
+
draft.fields.runDays.value !== null) {
|
|
705
|
+
const minimum = computeMinimumTier({
|
|
706
|
+
criteria,
|
|
707
|
+
estimatedHours: draft.fields.estimatedHours.value,
|
|
708
|
+
template: draft.fields.template.value,
|
|
709
|
+
});
|
|
710
|
+
const rangeMax = computeTierRangeMax(minimum, params);
|
|
711
|
+
const startTier = draft.fields.startTier.value;
|
|
712
|
+
const maxTierVal = draft.fields.maxTier.value;
|
|
713
|
+
const startOk = tierRank[startTier] >= tierRank[minimum] && tierRank[startTier] <= tierRank[rangeMax];
|
|
714
|
+
results.push({
|
|
715
|
+
id: "tier.start",
|
|
716
|
+
level: startOk ? "ok" : "block",
|
|
717
|
+
message: startOk
|
|
718
|
+
? "Start tier is within rule range"
|
|
719
|
+
: `Start tier must be between ${minimum} and ${rangeMax}`,
|
|
720
|
+
fields: ["startTier"],
|
|
721
|
+
params: { minimum, rangeMax },
|
|
722
|
+
});
|
|
723
|
+
const maxOk = tierRank[maxTierVal] >= tierRank[startTier] && tierRank[maxTierVal] <= tierRank[rangeMax];
|
|
724
|
+
results.push({
|
|
725
|
+
id: "tier.max",
|
|
726
|
+
level: maxOk ? "ok" : "block",
|
|
727
|
+
message: maxOk
|
|
728
|
+
? "Max tier is within rule range"
|
|
729
|
+
: `Max tier must be between ${startTier} and ${rangeMax}`,
|
|
730
|
+
fields: ["maxTier"],
|
|
731
|
+
params: { minimum: startTier, rangeMax },
|
|
732
|
+
});
|
|
733
|
+
const runDays = draft.fields.runDays.value;
|
|
734
|
+
const startRange = tierDaysRange(startTier, params);
|
|
735
|
+
const maxRange = tierDaysRange(maxTierVal, params);
|
|
736
|
+
const effectiveMin = Math.max(startRange.min, maxRange.min);
|
|
737
|
+
const effectiveMax = Math.min(startRange.max, maxRange.max);
|
|
738
|
+
const daysOk = runDays >= effectiveMin && runDays <= effectiveMax;
|
|
739
|
+
results.push({
|
|
740
|
+
id: "runDays.range",
|
|
741
|
+
level: daysOk ? "ok" : "block",
|
|
742
|
+
message: daysOk
|
|
743
|
+
? "Run days within tier range"
|
|
744
|
+
: "Run days must be within both start and max tier ranges",
|
|
745
|
+
fields: ["runDays"],
|
|
746
|
+
params: {
|
|
747
|
+
minimum: String(effectiveMin),
|
|
748
|
+
maximum: String(effectiveMax),
|
|
749
|
+
startTier,
|
|
750
|
+
maxTier: maxTierVal,
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
const minimumTierOk = draft.fields.minimumTier.value === minimum;
|
|
754
|
+
results.push({
|
|
755
|
+
id: "tier.computed",
|
|
756
|
+
level: minimumTierOk ? "ok" : "block",
|
|
757
|
+
message: minimumTierOk
|
|
758
|
+
? "Recorded minimum tier matches rule"
|
|
759
|
+
: "Recorded minimum tier is stale",
|
|
760
|
+
fields: ["minimumTier"],
|
|
761
|
+
});
|
|
762
|
+
const reserve = computeReserve(maxTierVal, runDays, params);
|
|
763
|
+
const expectedCost = {
|
|
764
|
+
reserve: reserve.toString(),
|
|
765
|
+
dailyFee: tierDailyFee(startTier, params).toString(),
|
|
766
|
+
};
|
|
767
|
+
const costOk = JSON.stringify(draft.fields.cost.value) === JSON.stringify(expectedCost);
|
|
768
|
+
results.push({
|
|
769
|
+
id: "cost.computed",
|
|
770
|
+
level: costOk ? "ok" : "block",
|
|
771
|
+
message: costOk ? "Recorded cost matches rule" : "Recorded cost is stale",
|
|
772
|
+
fields: ["cost"],
|
|
773
|
+
});
|
|
774
|
+
const limits = participantLimits(params);
|
|
775
|
+
const participantLimit = draft.fields.maxParticipants.value;
|
|
776
|
+
const unlimited = participantLimit === UNLIMITED_PARTICIPANTS;
|
|
777
|
+
const participantLimitOk = participantLimit !== null &&
|
|
778
|
+
Number.isInteger(participantLimit) &&
|
|
779
|
+
(unlimited || (participantLimit >= limits.min && participantLimit <= limits.max));
|
|
780
|
+
const heavy = unlimited || (participantLimit ?? 0) > limits.warning;
|
|
781
|
+
results.push({
|
|
782
|
+
id: "participants.range",
|
|
783
|
+
level: participantLimitOk ? (heavy ? "warn" : "ok") : "block",
|
|
784
|
+
message: participantLimitOk
|
|
785
|
+
? unlimited
|
|
786
|
+
? "Participant cap is unlimited; testing cost grows with every delivery"
|
|
787
|
+
: heavy
|
|
788
|
+
? `Participant cap ${participantLimit} may increase testing cost and latency`
|
|
789
|
+
: `Participant cap ${participantLimit} is supported`
|
|
790
|
+
: `Participant cap must be ${UNLIMITED_PARTICIPANTS} (unlimited) or between ${limits.min} and ${limits.max}`,
|
|
791
|
+
fields: ["maxParticipants"],
|
|
792
|
+
params: {
|
|
793
|
+
default: String(limits.default),
|
|
794
|
+
warning: String(limits.warning),
|
|
795
|
+
maximum: String(limits.max),
|
|
796
|
+
unlimited: String(unlimited),
|
|
797
|
+
},
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
return results;
|
|
801
|
+
}
|
|
802
|
+
//# sourceMappingURL=index.js.map
|