2026-08-16 18:12:50 +07:00
from __future__ import annotations
import json
2026-08-16 22:59:30 +07:00
import pytest
2026-08-16 18:12:50 +07:00
from agents . crypto_venture import CryptoVentureService
from control_plane . ventures . models import CompanyProposalStatus , CryptoJurisdictionPolicy , TokenNecessityClassification , TokenRedTeamFlag , VentureCohortMember , VentureTrack
from graph . bootstrap import champion_crypto_venture_cohort_graph_v1
from graph . crypto_venture_cohort import crypto_venture_cohort_registry
from graph . langgraph_runtime import LangGraphRuntime
from graph . models import GraphRun , GraphRunStatus
from model_router . router import ModelProvider , ModelRequestContract , ModelResponseContract , ModelRouter
class SolCryptoReviewProvider ( ModelProvider ) :
provider_name = " sol-test "
def complete ( self , request : ModelRequestContract ) - > ModelResponseContract :
prompt = request . prompt
2026-08-16 21:00:15 +07:00
if " PASS A - PROBLEM " in prompt :
payload = { " name " : " Machine Identity Credit Union " , " one_line_thesis " : " Autonomous agents build portable credit histories for machine services. " , " product_thesis " : " A pre-token API for machine credit and settlement risk scoring. " , " user " : " AI agent operators " , " participants " : [ " agents " , " service providers " , " risk observers " ] , " supply_side " : " providers publish measurable service outcomes " , " demand_side " : " agents need counterparties " , " coordination_failure " : " portable machine credit is not trusted across operators " , " trust_problem " : " operators can rewrite private reputation " , " why_neutral_network_may_help " : " neutral verifiable state lets agents carry economic identity across providers " , " pre_token_product " : " risk scoring API " , " pre_token_customer " : " agent operators " , " pre_token_value " : " lower counterparty default risk " , " pre_token_payment_method " : " Stripe or stablecoin usage credits " , " pre_token_revenue_model " : " $100 beta packages " , " revenue_1000_path " : " 10 beta packages " , " revenue_5000_path " : " 20 risk API packages " , " revenue_10000_path " : " 20 subscriptions " , " autonomous_operating_loop " : " machine demand -> discovery -> settlement -> verification -> reputation update " , " bootstrap_plan " : " local/testnet simulation " , " validation_experiment " : " simulate 100 agent jobs " , " major_risks " : [ " token not required " ] , " confidence " : 0.7 }
elif " PASS B - ONCHAIN " in prompt :
payload = { " onchain_necessity_score " : 86 , " why_onchain " : " public reputation and escrow materially degrade in private databases " , " offchain_substitute " : " single operator SaaS " , " pass_onchain " : True , " reasons " : [ " verifiable state " , " neutral settlement " , " machine-to-machine interaction " ] }
2026-08-16 21:56:09 +07:00
elif " PASS C - MINIMAL DECENTRALIZED " in prompt :
payload = { " protocol_architecture " : " onchain escrow and public machine credit registry " , " participant_model " : " agents, providers, risk observers " , " verification_model " : " objective settlement proofs " , " resource_allocation_model " : " risk-weighted access " , " dispute_model " : " automated evidence checks " }
elif " PASS D - NATIVE TOKEN " in prompt :
2026-08-16 21:00:15 +07:00
payload = { " token_thesis " : " Native bond represents protocol-specific machine default risk and is slashed for objective settlement failures. " , " token_utility " : [ " protocol-specific collateral " , " machine reputation-backed economic participation " ] , " token_demand_loop " : [ " agents earn credit " , " providers require bond " , " defaults slash bond " , " reliable agents receive access " ] , " value_capture " : " risk fees and slashing penalties " , " security_model " : " escrow, timelock, pause, oracle checks, key controls " , " regulatory_risks " : [ " legal review required " ] , " required_token_functions " : [ " protocol-specific risk collateral " ] , " weak_token_functions " : [ " payment " ] }
2026-08-16 21:56:09 +07:00
elif " CRYPTO_TOKEN_UTILITY_JUDGE " in prompt or " CRYPTO_TOKEN_COUNTERFACTUAL_JUDGE " in prompt or " Counterfactual token necessity " in prompt :
2026-08-16 22:59:30 +07:00
payload = { " token_classification " : " TOKEN_STRONGLY_JUSTIFIED " , " score " : 78 , " utility_scores " : { " SECURITY_UTILITY " : 82 , " COLLATERAL_UTILITY " : 84 , " MACHINE_ECONOMIC_UTILITY " : 86 , " SPECULATION_DEPENDENCE " : 10 } , " strong_structural_roles " : [ " SECURITY_BOND " , " SLASHABLE_COLLATERAL " ] , " weak_roles " : [ " DEMAND_SIDE_PAYMENT " ] , " counterfactual_analysis " : { " summary " : " USDC/ETH can operate but weakens protocol-specific risk pricing. " , " external_collateral_identical_security " : False , " stable_collateral_identical_security " : False } , " external_collateral_counterfactual " : { " breaks " : " external collateral misses protocol-specific risk " } , " material_improvements_over_USDC_ETH " : [ " protocol-specific default risk " , " portable machine economic identity " ] , " native_asset_costs_and_risks " : [ " volatility " , " legal complexity " ] , " argument_for_native_token " : " Native bond prices protocol-specific machine risk. " , " argument_against_native_token " : " ETH/USDC collateral is simpler and more liquid. " , " final_rationale " : " ETH/USDC/external collateral cannot reproduce the protocol-specific machine default-risk pricing economically enough, so the native bond benefit outweighs issuance costs. " , " native_token_removed_breaks " : [ " machine economic identity weakens " ] , " native_token_removed_degradation " : " MATERIAL " , " native_token_removed_explanation " : " USDC payments work, but protocol-specific bond/reputation is materially weaker. " }
2026-08-16 18:12:50 +07:00
elif " Independent Token Red Team " in prompt :
payload = { " flags " : [ " BOOTSTRAP_PROBLEM " ] , " severity " : " MEDIUM " , " critique " : " Provider supply bootstrap remains the main risk. " }
elif " Final Crypto IC " in prompt :
payload = { " score_adjustment " : 3 , " decision " : " PROTOCOL_VALIDATE " , " rationale " : " Token loop is plausible but needs testnet evidence. " }
else :
payload = { }
return ModelResponseContract ( " sol " , json . dumps ( payload ) , { } )
def health ( self ) - > str :
return " AVAILABLE "
def service ( router : ModelRouter | None = None ) - > CryptoVentureService :
return CryptoVentureService ( router , web_research_available = False , generation_model_hint = " qwen " , research_model_hint = " qwen " , final_ic_model_hint = " sol " )
2026-08-16 21:00:15 +07:00
def sol_service ( router : ModelRouter | None = None ) - > CryptoVentureService :
return CryptoVentureService ( router , web_research_available = False , generation_model_hint = " sol " , research_model_hint = " qwen " , final_ic_model_hint = " sol " )
2026-08-16 18:12:50 +07:00
def test_crypto_track_and_token_gate_remove_weak_then_regenerate ( ) - > None :
svc = service ( )
cohort = svc . prepare_cohort ( size = 2 , concurrency = 1 )
weak = svc . _create_proposal (
cohort . mandate ,
{ " name " : " Community Points SaaS " , " product_thesis " : " A normal SaaS dashboard. " , " protocol_thesis " : " A private database tracks points. " , " token_thesis " : " Community marketing token. " , " token_utility " : [ " community " ] , " token_demand_loop " : [ " more users equals more token demand " ] } ,
" test " ,
" OPEN_CRYPTO_CATEGORY " ,
)
VentureCohortMember . objects . create ( cohort = cohort , proposal = weak )
svc . token_necessity_gate ( cohort )
svc . regenerate_rejected_slots ( cohort )
weak . refresh_from_db ( )
assert weak . status == CompanyProposalStatus . REJECTED
2026-08-16 19:31:15 +07:00
assert weak . metadata [ " routed_to_saas " ] is False
assert cohort . members . count ( ) == 0
2026-08-16 21:56:09 +07:00
assert cohort . metrics [ " regeneration_policy " ] . startswith ( " V0.3.1 " )
2026-08-16 21:00:15 +07:00
def test_v03_sol_problem_first_generation_no_token_in_pass_a_and_onchain_gate ( ) - > None :
svc = sol_service ( ModelRouter ( { " sol " : SolCryptoReviewProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposals = svc . generate_protocols ( cohort )
proposal = proposals [ 0 ]
assessment = svc . onchain_necessity_gate ( cohort ) [ 0 ]
passes = proposal . metadata [ " crypto " ] [ " generation_passes " ]
assert proposal . metadata [ " generation_source " ] == " sol "
assert " token_thesis " not in passes [ " pass_a_problem_network " ]
assert proposal . metadata [ " crypto " ] [ " problem_first_pass_a_had_no_token " ] is True
assert assessment . onchain_necessity_score == 86
assert cohort . metrics [ " raw_sol_theses " ] == 1
2026-08-16 21:56:09 +07:00
assert cohort . metrics [ " sol_onchain_judge_requests " ] == 1
def test_v031_onchain_reject_skips_token_design ( ) - > None :
class RejectOnchainProvider ( SolCryptoReviewProvider ) :
def complete ( self , request : ModelRequestContract ) - > ModelResponseContract :
if " PASS B - ONCHAIN " in request . prompt :
return ModelResponseContract ( " sol " , json . dumps ( { " onchain_necessity_score " : 40 , " pass_onchain " : False , " why_onchain " : " database is fine " } ) , { } )
return super ( ) . complete ( request )
svc = sol_service ( ModelRouter ( { " sol " : RejectOnchainProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
svc . generate_protocols ( cohort )
svc . onchain_necessity_gate ( cohort )
svc . token_necessity_gate ( cohort )
assert cohort . metrics [ " onchain_passed " ] == 0
assert cohort . metrics [ " token_design_attempts " ] == 0
assert cohort . metrics [ " token_design_skipped_due_to_onchain_rejection " ] == 1
2026-08-16 18:12:50 +07:00
def test_sol_counterfactual_red_team_and_final_ic_are_used ( ) - > None :
svc = service ( ModelRouter ( { " sol " : SolCryptoReviewProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " PROOF_ATTESTATION_MARKETS " ) , " test " , " PROOF_ATTESTATION_MARKETS " )
VentureCohortMember . objects . create ( cohort = cohort , proposal = proposal )
token = svc . assess_token_necessity ( proposal )
red = svc . red_team_proposal ( proposal )
svc . tokenomics_simulation ( cohort )
review = svc . portfolio_crypto_ic ( cohort )
assert token . classification == TokenNecessityClassification . TOKEN_STRONGLY_JUSTIFIED
2026-08-16 21:56:09 +07:00
assert token . metadata [ " sol_token_utility_judge " ]
assert token . metadata [ " argument_for_native_token " ]
assert token . metadata [ " argument_against_native_token " ]
2026-08-16 18:12:50 +07:00
assert TokenRedTeamFlag . BOOTSTRAP_PROBLEM in red . flags
assert review . rankings [ 0 ] [ " sol_final_ic_review " ] [ " score_adjustment " ] == 3
def test_regulatory_negation_does_not_treat_disabled_sale_as_issuance_risk ( ) - > None :
svc = service ( )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " AGENT_TO_AGENT_PAYMENTS " ) , " test " , " AGENT_TO_AGENT_PAYMENTS " )
policy = svc . regulatory_policy ( proposal )
assert policy . regulatory_manageability_score == 72
assert policy . metadata [ " TOKEN_SALE_DISABLED " ] is True
assert CryptoJurisdictionPolicy . objects . get ( proposal = proposal ) . legal_review_required is True
def test_tokenomics_simulation_is_proposal_specific ( ) - > None :
svc = service ( )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
low = svc . _create_proposal ( cohort . mandate , { * * svc . _fallback_payload ( 0 , " AGENT_TO_AGENT_PAYMENTS " ) , " confidence " : 0.35 } , " test " , " AGENT_TO_AGENT_PAYMENTS " )
high = svc . _create_proposal ( cohort . mandate , { * * svc . _fallback_payload ( 1 , " DECENTRALIZED_AI_COMPUTE " ) , " confidence " : 0.9 } , " test " , " DECENTRALIZED_AI_COMPUTE " )
low_sim = svc . simulate_tokenomics ( low )
high_sim = svc . simulate_tokenomics ( high )
2026-08-16 21:56:09 +07:00
assert low_sim . scenarios [ " EXPECTED_USAGE " ] [ " users " ] != high_sim . scenarios [ " EXPECTED_USAGE " ] [ " users " ]
assert low_sim . scenarios [ " EXPECTED_USAGE " ] [ " token_demand " ] != high_sim . scenarios [ " EXPECTED_USAGE " ] [ " token_demand " ]
2026-08-16 19:31:15 +07:00
assert " NATIVE_TOKEN_REMOVED " in low_sim . scenarios
2026-08-16 21:56:09 +07:00
assert " ETH_COLLATERAL " in low_sim . scenarios
assert " USDC_COLLATERAL " in low_sim . scenarios
2026-08-16 21:00:15 +07:00
def test_v03_primary_source_quality_wrong_category_and_weak_coverage ( ) - > None :
svc = service ( )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " MACHINE_ECONOMIC_IDENTITY " ) , " test " , " MACHINE_ECONOMIC_IDENTITY " )
good = svc . crypto_source_quality ( proposal , { " url " : " https://ethereum.org/en/developers/docs/ " , " title " : " Ethereum developer docs " , " summary " : " onchain escrow settlement staking protocol " , " category " : " ONCHAIN_ALTERNATIVES " } )
wrong = svc . crypto_source_quality ( proposal , { " url " : " https://www.microsoft.com/windows " , " title " : " Windows help " , " summary " : " generic software " , " category " : " TOKEN_MODELS " } )
assert good [ " accepted " ] is True
assert good [ " source_tier " ] == " TIER_A "
assert wrong [ " accepted " ] is False
assert wrong [ " reason " ] . startswith ( " SOURCE_REJECT_ " )
assert svc . category_coverage_confidence ( [ { " quality " : " weak " , " url " : " https://example.com/a " } ] ) == " LOW "
def test_v03_search_engine_circuit_breaker ( monkeypatch ) - > None :
class CaptchaClient :
def search_payload ( self , query : str ) - > dict :
return { " unresponsive_engines " : [ ( " google " , " CAPTCHA required " ) ] , " results " : [ ] }
class EmptyFetcher :
def fetch_many ( self , sources , max_pages = 5 ) :
return [ ]
monkeypatch . setattr ( " agents.crypto_venture.SearxngSearchClient.from_resources " , staticmethod ( lambda : CaptchaClient ( ) ) )
monkeypatch . setattr ( " agents.crypto_venture.WebPageFetcher " , lambda : EmptyFetcher ( ) )
svc = service ( )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " MACHINE_ECONOMIC_IDENTITY " ) , " test " , " MACHINE_ECONOMIC_IDENTITY " )
research = svc . crypto_research ( proposal , depth = " light " )
assert research [ " queries_avoided_due_to_circuit_breaker " ] > 0
assert research [ " search_engine_health " ] [ " CAPTCHA " ] > = 4
2026-08-16 19:31:15 +07:00
def test_v02_pretoken_roles_security_and_launch_readiness ( ) - > None :
svc = service ( )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " DECENTRALIZED_AI_COMPUTE " ) , " test " , " DECENTRALIZED_AI_COMPUTE " )
VentureCohortMember . objects . create ( cohort = cohort , proposal = proposal )
pretoken = svc . assess_pretoken_monetization ( proposal )
roles = svc . token_role_decomposition ( proposal )
model = svc . token_economic_model ( proposal )
svc . protocol_security_gate ( cohort )
readiness = svc . token_launch_readiness ( proposal )
assert pretoken . pre_token_monetization_potential > 0
assert roles . stablecoin_counterfactual [ " MODEL_B_stablecoin_payment_native_bond " ]
assert model . average_fee > 0
assert proposal . protocol_security_assessment . decision in { " PASS_FOR_TESTNET_DESIGN " , " REVISE_SECURITY_MODEL " , " BLOCK_TESTNET " }
assert readiness . launch_readiness_status != " READY_FOR_HUMAN_LAUNCH_REVIEW "
2026-08-16 18:12:50 +07:00
2026-08-16 21:00:15 +07:00
def test_v03_independent_counterfactual_native_removed_fields ( ) - > None :
svc = service ( ModelRouter ( { " sol " : SolCryptoReviewProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " PROOF_MARKETS " ) , " test " , " PROOF_MARKETS " )
token = svc . assess_token_necessity ( proposal )
2026-08-16 21:56:09 +07:00
assert token . metadata [ " independent_token_utility_judge " ] == " CRYPTO_TOKEN_UTILITY_JUDGE "
2026-08-16 21:00:15 +07:00
assert token . metadata [ " native_token_removed_degradation " ] == " MATERIAL "
2026-08-16 21:56:09 +07:00
assert token . metadata [ " argument_for_native_token " ]
2026-08-16 23:32:55 +07:00
for field in [ " argument_for_native_token " , " argument_against_native_token " , " external_collateral_counterfactual " , " native_token_removed_breaks " , " native_token_removed_explanation " , " material_improvements_over_USDC_ETH " , " native_asset_costs_and_risks " , " final_rationale " ] :
2026-08-16 22:59:30 +07:00
assert token . metadata [ field ]
assert token . rationale
def test_v032b_incomplete_token_judge_retries_then_persists_complete_response ( ) - > None :
class RetryProvider ( SolCryptoReviewProvider ) :
def __init__ ( self ) - > None :
self . calls = 0
def complete ( self , request : ModelRequestContract ) - > ModelResponseContract :
if " CRYPTO_TOKEN_UTILITY_JUDGE " in request . prompt :
self . calls + = 1
if self . calls == 1 :
return ModelResponseContract ( " sol " , json . dumps ( { " token_classification " : " TOKEN_OPTIONAL " , " score " : 55 } ) , { } )
return super ( ) . complete ( request )
provider = RetryProvider ( )
svc = service ( ModelRouter ( { " sol " : provider } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " PROOF_MARKETS " ) , " test " , " PROOF_MARKETS " )
token = svc . assess_token_necessity ( proposal )
assert provider . calls == 2
assert token . metadata [ " external_collateral_counterfactual " ]
def test_v032b_incomplete_token_judge_fails_closed_without_fallback_classification ( ) - > None :
class IncompleteProvider ( SolCryptoReviewProvider ) :
def complete ( self , request : ModelRequestContract ) - > ModelResponseContract :
if " CRYPTO_TOKEN_UTILITY_JUDGE " in request . prompt :
return ModelResponseContract ( " sol " , json . dumps ( { " token_classification " : " TOKEN_OPTIONAL " , " score " : 55 , " final_rationale " : " too thin " } ) , { } )
return super ( ) . complete ( request )
svc = service ( ModelRouter ( { " sol " : IncompleteProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
proposal = svc . _create_proposal ( cohort . mandate , svc . _fallback_payload ( 0 , " PROOF_MARKETS " ) , " test " , " PROOF_MARKETS " )
with pytest . raises ( ValueError , match = " Incomplete Sol token utility judge response " ) :
svc . assess_token_necessity ( proposal )
assert not hasattr ( proposal , " token_utility_assessment " )
2026-08-16 21:56:09 +07:00
def test_v031_payment_governance_reward_only_rejected_but_structural_passes ( ) - > None :
svc = service ( ModelRouter ( { " sol " : SolCryptoReviewProvider ( ) } ) )
cohort = svc . prepare_cohort ( size = 1 , concurrency = 1 )
weak = svc . _create_proposal ( cohort . mandate , { " name " : " FeeGov Rewards " , " product_thesis " : " Useful SaaS " , " protocol_thesis " : " Onchain logs " , " token_thesis " : " Token is for payment governance and rewards " , " token_utility " : [ " payment " , " governance " , " rewards " ] , " token_roles " : { " DEMAND_SIDE_PAYMENT " : " REQUIRED " , " GOVERNANCE " : " REQUIRED " , " PROVIDER_REWARD " : " REQUIRED " } } , " test " , " OPEN_CRYPTO_CATEGORY " )
strong = svc . _create_proposal ( cohort . mandate , { * * svc . _fallback_payload ( 0 , " MACHINE_REPUTATION_WITH_ECONOMIC_STAKE " ) , " token_roles " : { " SECURITY_BOND " : " REQUIRED " , " SLASHABLE_COLLATERAL " : " REQUIRED " , " MACHINE_ECONOMIC_IDENTITY " : " STRONGLY_USEFUL " } } , " test " , " MACHINE_REPUTATION_WITH_ECONOMIC_STAKE " )
weak_token = svc . assess_token_necessity ( weak )
strong_token = svc . assess_token_necessity ( strong )
assert weak_token . classification in { TokenNecessityClassification . TOKEN_OPTIONAL , TokenNecessityClassification . TOKEN_UNNECESSARY }
assert strong_token . classification == TokenNecessityClassification . TOKEN_STRONGLY_JUSTIFIED
assert len ( strong_token . metadata [ " strong_token_roles " ] ) > = 2
2026-08-16 21:00:15 +07:00
2026-08-16 18:12:50 +07:00
def test_crypto_cohort_graph_real_gates_and_report ( ) - > None :
svc = service ( )
version = champion_crypto_venture_cohort_graph_v1 ( )
graph_run = GraphRun . objects . create ( execution_graph_version = version , current_node = version . graph_spec [ " entry " ] )
LangGraphRuntime ( crypto_venture_cohort_registry ( svc , cohort_size = 3 , concurrency = 1 ) ) . run_until_terminal_or_paused ( graph_run )
graph_run . refresh_from_db ( )
cohort = graph_run . venture_cohorts . get ( )
report = cohort . mandate . artifacts . get ( artifact_type = " CRYPTO_VENTURE_COHORT_REPORT " )
assert graph_run . status == GraphRunStatus . COMPLETE
assert cohort . metadata [ " venture_track " ] == VentureTrack . CRYPTO_PROTOCOL
2026-08-16 21:00:15 +07:00
assert cohort . members . count ( ) < = 3
2026-08-16 22:46:24 +07:00
if cohort . metrics . get ( " serious_crypto_survivors " , 0 ) > 0 :
assert cohort . metrics [ " protocol_security_gate_passed " ] > = 1
2026-08-16 21:00:15 +07:00
assert len ( report . content [ " ranking " ] ) < = 3
2026-08-16 18:12:50 +07:00
assert len ( report . content [ " top_3 " ] ) < = 3
2026-08-16 21:56:09 +07:00
assert report . content [ " title " ] == " CRYPTO VENTURE COHORT V0.3.1 "
if cohort . metrics . get ( " serious_crypto_survivors " , 0 ) > 0 :
assert cohort . metrics [ " sol_final_ic_requests " ] > 0