axis-synome 0.1.0.dev62__tar.gz → 0.1.0.dev64__tar.gz
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.
- {axis_synome-0.1.0.dev62/src/axis_synome.egg-info → axis_synome-0.1.0.dev64}/PKG-INFO +22 -1
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/README.md +21 -0
- axis_synome-0.1.0.dev64/examples/01_prime_basics.py +31 -0
- axis_synome-0.1.0.dev64/examples/02_assets_and_tokens_of_a_prime.py +77 -0
- axis_synome-0.1.0.dev64/examples/03_inverse_lookups.py +85 -0
- axis_synome-0.1.0.dev64/examples/04_atlas_provenance.py +36 -0
- axis_synome-0.1.0.dev64/examples/05_feeding_a_formula.py +91 -0
- axis_synome-0.1.0.dev64/examples/README.md +58 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/pyproject.toml +1 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/_version.py +2 -2
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/tokens.py +1 -6
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/asc_collateral_ratio.py +6 -4
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/asc_incentive.py +8 -5
- axis_synome-0.1.0.dev64/src/axis_synome/spec/asc/formulas/dab.py +25 -0
- axis_synome-0.1.0.dev64/src/axis_synome/spec_inspect/__init__.py +12 -0
- axis_synome-0.1.0.dev64/src/axis_synome/spec_inspect/__main__.py +6 -0
- axis_synome-0.1.0.dev64/src/axis_synome/spec_inspect/cli.py +346 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/references/graph.py +253 -55
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64/src/axis_synome.egg-info}/PKG-INFO +22 -1
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome.egg-info/SOURCES.txt +12 -1
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome.egg-info/entry_points.txt +1 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/conftest.py +2 -2
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/mocks.py +6 -6
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_asc_collateral_ratio.py +15 -2
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_asc_incentive.py +11 -6
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_dab.py +4 -3
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_latent_asc.py +3 -3
- axis_synome-0.1.0.dev64/tests/axis_synome/spec_inspect/test_cli.py +305 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_support/references/test_graph.py +233 -0
- axis_synome-0.1.0.dev64/tests/axis_synome/suraf/suraf_client/__init__.py +0 -0
- axis_synome-0.1.0.dev64/tests/axis_synome/test_examples.py +41 -0
- axis_synome-0.1.0.dev62/src/axis_synome/spec/asc/README.md +0 -419
- axis_synome-0.1.0.dev62/src/axis_synome/spec/asc/formulas/dab.py +0 -24
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/.flake8 +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/AGENTS.md +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/CLAUDE.md +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/WRITING_SPECS.md +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/setup.cfg +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/export_entities.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/all_entities/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/all_entities/lending_markets.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/alm_proxies.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/asset_categories.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/assets.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/assets_by_prime.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/networks.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/primes.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/protocol_sets.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/types.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/latent_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/ratio_latent_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/formulas/resting_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/codegen_test/entities/agents.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/crypto_lending/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/crypto_lending/formulas/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/crypto_lending/formulas/lif.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/entities/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/entities/audit_firms.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/entities/protocol_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/entities/smart_contract_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/administrative_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/administrative_rrc/administrative_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/audit_factor.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/entities/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/entities/lending_protocol.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/entities/precomputed_crr.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/financial_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/financial_rrc/entities.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/financial_rrc/perpetual_positions.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/asset_correlation_coefficient.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/capital_requirement_without_buffers.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/exposure_caps.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/fixed_crr_rrc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/instance_financial_rrc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/lending_rrc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/pipeline.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/precomputed_crr_rrc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/financial_rrc/probability_of_default.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/formulas/required_risk_capital.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/lindy_factor.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/smart_contract_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/smart_contract_rrc/exceptions.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/risk_capital/smart_contract_rrc/smart_contract_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/README.md +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/entities/assessor_score.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/entities/assets.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/entities/mappings.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/formulas/crr.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/suraf/formulas/scoring.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/correlation_matrix.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/evm_address.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/math_protocol.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/pendle_validation.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/references/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/runtime/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/runtime/base.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/runtime/math.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/runtime/reference.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/validated_dataclass.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_support/validated_str.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_validator/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_validator/check_source_uuids.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_validator/checker.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_validator/flake8_plugin.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec_validator/python_subset.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome.egg-info/dependency_links.txt +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome.egg-info/requires.txt +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome.egg-info/top_level.txt +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_alm_proxies.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_asset_categories.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_evm_address.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_prime_agent_data_validation.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_ratio_latent_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/asc/test_resting_asc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/administrative_rrc/test_administrative_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/financial_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/financial_rrc/test_lending_rrc.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/financial_rrc/test_perpetual_positions.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/formulas/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/formulas/test_correlation_matrix.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/formulas/test_loss_given_default.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/smart_contract_rrc/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/smart_contract_rrc/test_exceptions.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/risk_capital/smart_contract_rrc/test_smart_contract_risk.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/scripts/test_export_entities.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/spec_support → axis_synome-0.1.0.dev64/tests/axis_synome/spec_inspect}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/spec_support/references → axis_synome-0.1.0.dev64/tests/axis_synome/spec_support}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/spec_support/runtime → axis_synome-0.1.0.dev64/tests/axis_synome/spec_support/references}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/suraf → axis_synome-0.1.0.dev64/tests/axis_synome/spec_support/runtime}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_support/runtime/test_base.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_support/runtime/test_math.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_validator/test_check_source_uuids.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_validator/test_checker.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/spec_validator/test_flake8_plugin.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/suraf/entities → axis_synome-0.1.0.dev64/tests/axis_synome/suraf}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/suraf/formulas → axis_synome-0.1.0.dev64/tests/axis_synome/suraf/entities}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/entities/test_assessor_score.py +0 -0
- {axis_synome-0.1.0.dev62/tests/axis_synome/suraf/suraf_client → axis_synome-0.1.0.dev64/tests/axis_synome/suraf/formulas}/__init__.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/formulas/test_crr.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/formulas/test_scoring.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/crr_mapping.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/penalty.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/scorecards/Assessor_1_scores.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/scorecards/Assessor_2_scores.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/scorecards/Assessor_3_scores.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/static/aave_ausdc/v1/weights.csv +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/suraf_client/suraf_client.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/tests/axis_synome/suraf/suraf_client/test_suraf_client.py +0 -0
- {axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: axis-synome
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev64
|
|
4
4
|
Summary: Axis specification modules (entities, formulas, validators)
|
|
5
5
|
Author-email: Archon Tech <hello@archontech.ai>
|
|
6
6
|
License: MIT
|
|
@@ -86,6 +86,27 @@ Or use as a flake8 plugin:
|
|
|
86
86
|
flake8 --select=AXS your_spec.py
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
## Examples
|
|
90
|
+
|
|
91
|
+
Runnable examples that show how to navigate the entity graph (assets,
|
|
92
|
+
tokens, networks, protocols of a prime) live under
|
|
93
|
+
[`examples/`](./examples/README.md). Run any of them with:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
uv run python examples/02_assets_and_tokens_of_a_prime.py
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Highlights:
|
|
100
|
+
|
|
101
|
+
- `01_prime_basics.py` — basic facts about each `PrimeAgent`.
|
|
102
|
+
- `02_assets_and_tokens_of_a_prime.py` — list assets, tokens, underlying
|
|
103
|
+
tokens, and group by network/protocol.
|
|
104
|
+
- `03_inverse_lookups.py` — *which primes hold token X?*, *which primes are
|
|
105
|
+
on network Y?*, *which prime owns this address?*
|
|
106
|
+
- `04_atlas_provenance.py` — trace each asset back to its Atlas document.
|
|
107
|
+
- `05_feeding_a_formula.py` — bridge external records into `Position`s and
|
|
108
|
+
call `asc(...)`.
|
|
109
|
+
|
|
89
110
|
## About
|
|
90
111
|
|
|
91
112
|
`axis-synome` is a specification framework for defining financial and risk calculations in DeFi, with emphasis on formalized, auditable spec files.
|
|
@@ -71,6 +71,27 @@ Or use as a flake8 plugin:
|
|
|
71
71
|
flake8 --select=AXS your_spec.py
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
Runnable examples that show how to navigate the entity graph (assets,
|
|
77
|
+
tokens, networks, protocols of a prime) live under
|
|
78
|
+
[`examples/`](./examples/README.md). Run any of them with:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
uv run python examples/02_assets_and_tokens_of_a_prime.py
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Highlights:
|
|
85
|
+
|
|
86
|
+
- `01_prime_basics.py` — basic facts about each `PrimeAgent`.
|
|
87
|
+
- `02_assets_and_tokens_of_a_prime.py` — list assets, tokens, underlying
|
|
88
|
+
tokens, and group by network/protocol.
|
|
89
|
+
- `03_inverse_lookups.py` — *which primes hold token X?*, *which primes are
|
|
90
|
+
on network Y?*, *which prime owns this address?*
|
|
91
|
+
- `04_atlas_provenance.py` — trace each asset back to its Atlas document.
|
|
92
|
+
- `05_feeding_a_formula.py` — bridge external records into `Position`s and
|
|
93
|
+
call `asc(...)`.
|
|
94
|
+
|
|
74
95
|
## About
|
|
75
96
|
|
|
76
97
|
`axis-synome` is a specification framework for defining financial and risk calculations in DeFi, with emphasis on formalized, auditable spec files.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
# Examples are runnable scripts; printing is the whole point.
|
|
3
|
+
"""Example 01 — Basic facts about a Prime.
|
|
4
|
+
|
|
5
|
+
A ``PrimeAgent`` is an enum whose ``.value`` is a ``PrimeAgentData`` dataclass
|
|
6
|
+
carrying the operational facts of a Sky Star Agent (prime): its name, the
|
|
7
|
+
assets it controls, the networks it operates on, its PSM protocols, and a
|
|
8
|
+
few ASC-specific knobs.
|
|
9
|
+
|
|
10
|
+
This example walks every prime and prints those facts.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from axis_synome.spec.asc.entities.primes import PrimeAgent
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main() -> None:
|
|
17
|
+
for prime in PrimeAgent:
|
|
18
|
+
data = prime.value
|
|
19
|
+
print(f"=== {data.name} ===")
|
|
20
|
+
print(f" asc_exempt : {data.asc_exempt}")
|
|
21
|
+
print(f" # assets : {len(data.assets)}")
|
|
22
|
+
print(f" networks : {sorted(n.value for n in data.networks)}")
|
|
23
|
+
print(f" psm_protocols : {sorted(p.value for p in data.psm_protocols)}")
|
|
24
|
+
print(f" alm_proxy : {data.alm_proxy.value if data.alm_proxy else None}")
|
|
25
|
+
print(f" max_pct_latent_asc : {data.max_pct_latent_asc}")
|
|
26
|
+
print(f" min_pct_asc_of_collat : {data.min_pct_asc_of_collateral}")
|
|
27
|
+
print()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if __name__ == "__main__":
|
|
31
|
+
main()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
"""Example 02 — Find the assets and tokens associated with a prime.
|
|
3
|
+
|
|
4
|
+
This is the headline question: *"What does Spark hold?"*
|
|
5
|
+
|
|
6
|
+
It demonstrates several useful projections off ``PrimeAgentData.assets``:
|
|
7
|
+
|
|
8
|
+
* the raw list of ``Asset`` rows,
|
|
9
|
+
* the set of ``Token`` symbols held (e.g. ``USDC``, ``sUSDe``, ...),
|
|
10
|
+
* the set of *underlying* tokens (the real economic exposure behind a
|
|
11
|
+
wrapped/yield-bearing asset),
|
|
12
|
+
* assets grouped by ``Network``,
|
|
13
|
+
* assets grouped by ``Protocol``.
|
|
14
|
+
|
|
15
|
+
All of this is pure attribute access on the entity graph — no I/O, no
|
|
16
|
+
external lookups.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from collections import defaultdict
|
|
20
|
+
|
|
21
|
+
from axis_synome.spec.asc.entities.assets import Asset
|
|
22
|
+
from axis_synome.spec.asc.entities.networks import Network
|
|
23
|
+
from axis_synome.spec.asc.entities.primes import PrimeAgent
|
|
24
|
+
from axis_synome.spec.asc.entities.protocol_sets import Protocol
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def show_assets_for(prime: PrimeAgent) -> None:
|
|
28
|
+
data = prime.value
|
|
29
|
+
print(f"=== {data.name} ===")
|
|
30
|
+
print(f"Total assets: {len(data.assets)}\n")
|
|
31
|
+
|
|
32
|
+
# 1. Direct list of assets.
|
|
33
|
+
print("Assets (token @ protocol on network):")
|
|
34
|
+
for asset in data.assets:
|
|
35
|
+
print(f" - {asset.token.value:<20} @ {asset.protocol.value:<35} on {asset.network.value}")
|
|
36
|
+
print()
|
|
37
|
+
|
|
38
|
+
# 2. Set of tokens held.
|
|
39
|
+
tokens_held = {a.token for a in data.assets}
|
|
40
|
+
print(f"Distinct tokens held ({len(tokens_held)}):")
|
|
41
|
+
print(" " + ", ".join(sorted(t.value for t in tokens_held)))
|
|
42
|
+
print()
|
|
43
|
+
|
|
44
|
+
# 3. Set of underlying tokens (real economic exposure).
|
|
45
|
+
underlying = {a.underlying_asset for a in data.assets}
|
|
46
|
+
print(f"Distinct underlying tokens ({len(underlying)}):")
|
|
47
|
+
print(" " + ", ".join(sorted(t.value for t in underlying)))
|
|
48
|
+
print()
|
|
49
|
+
|
|
50
|
+
# 4. Group by network.
|
|
51
|
+
by_network: dict[Network, list[Asset]] = defaultdict(list)
|
|
52
|
+
for a in data.assets:
|
|
53
|
+
by_network[a.network].append(a)
|
|
54
|
+
print("Assets grouped by network:")
|
|
55
|
+
for network in sorted(by_network, key=lambda n: n.value):
|
|
56
|
+
tokens = sorted(a.token.value for a in by_network[network])
|
|
57
|
+
print(f" {network.value:<20} ({len(tokens)}): {', '.join(tokens)}")
|
|
58
|
+
print()
|
|
59
|
+
|
|
60
|
+
# 5. Group by protocol.
|
|
61
|
+
by_protocol: dict[Protocol, list[Asset]] = defaultdict(list)
|
|
62
|
+
for a in data.assets:
|
|
63
|
+
by_protocol[a.protocol].append(a)
|
|
64
|
+
print("Assets grouped by protocol:")
|
|
65
|
+
for protocol in sorted(by_protocol, key=lambda p: p.value):
|
|
66
|
+
tokens = sorted(a.token.value for a in by_protocol[protocol])
|
|
67
|
+
print(f" {protocol.value:<40} ({len(tokens)}): {', '.join(tokens)}")
|
|
68
|
+
print()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main() -> None:
|
|
72
|
+
show_assets_for(PrimeAgent.SPARK)
|
|
73
|
+
show_assets_for(PrimeAgent.GROVE)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
main()
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
"""Example 03 — Inverse lookups across the entity graph.
|
|
3
|
+
|
|
4
|
+
The previous examples ask "given a prime, what does it hold?". This file
|
|
5
|
+
goes the other direction:
|
|
6
|
+
|
|
7
|
+
* Given a ``Token``, which primes hold it (and via which protocol/network)?
|
|
8
|
+
* Given a ``Network``, which primes operate on it?
|
|
9
|
+
* Given an EVM address, which prime owns the matching asset?
|
|
10
|
+
|
|
11
|
+
These queries are simple comprehensions over ``PrimeAgent`` and its
|
|
12
|
+
``.value.assets`` list.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from axis_synome.spec.asc.entities.networks import Network
|
|
16
|
+
from axis_synome.spec.asc.entities.primes import PrimeAgent
|
|
17
|
+
from axis_synome.spec.asc.entities.tokens import Token
|
|
18
|
+
from axis_synome.spec_support.evm_address import EvmAddress
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def primes_holding_token(token: Token) -> list[tuple[PrimeAgent, list[str]]]:
|
|
22
|
+
"""Return ``(prime, [contexts])`` pairs for every prime holding ``token``.
|
|
23
|
+
|
|
24
|
+
``contexts`` strings have the form ``"<protocol> on <network>"``.
|
|
25
|
+
"""
|
|
26
|
+
matches: list[tuple[PrimeAgent, list[str]]] = []
|
|
27
|
+
for prime in PrimeAgent:
|
|
28
|
+
contexts: list[str] = [
|
|
29
|
+
f"{a.protocol.value} on {a.network.value}"
|
|
30
|
+
for a in prime.value.assets
|
|
31
|
+
if a.token == token
|
|
32
|
+
]
|
|
33
|
+
if contexts:
|
|
34
|
+
matches.append((prime, contexts))
|
|
35
|
+
return matches
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def primes_on_network(network: Network) -> list[PrimeAgent]:
|
|
39
|
+
return [p for p in PrimeAgent if network in p.value.networks]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def prime_owning_address(address: EvmAddress) -> tuple[PrimeAgent, str] | None:
|
|
43
|
+
for prime in PrimeAgent:
|
|
44
|
+
for asset in prime.value.assets:
|
|
45
|
+
if asset.address == address:
|
|
46
|
+
return prime, asset.token.value
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
print("=== Primes holding USDC ===")
|
|
52
|
+
for prime, contexts in primes_holding_token(Token.USDC):
|
|
53
|
+
print(f" {prime.value.name}:")
|
|
54
|
+
for ctx in contexts:
|
|
55
|
+
print(f" - {ctx}")
|
|
56
|
+
print()
|
|
57
|
+
|
|
58
|
+
print("=== Primes holding JAAA ===")
|
|
59
|
+
for prime, contexts in primes_holding_token(Token.JAAA):
|
|
60
|
+
print(f" {prime.value.name}: {', '.join(contexts)}")
|
|
61
|
+
print()
|
|
62
|
+
|
|
63
|
+
print("=== Primes operating on Base ===")
|
|
64
|
+
for prime in primes_on_network(Network.BASE):
|
|
65
|
+
print(f" - {prime.value.name}")
|
|
66
|
+
print()
|
|
67
|
+
|
|
68
|
+
print("=== Primes operating on Avalanche ===")
|
|
69
|
+
for prime in primes_on_network(Network.AVALANCHE):
|
|
70
|
+
print(f" - {prime.value.name}")
|
|
71
|
+
print()
|
|
72
|
+
|
|
73
|
+
# Reverse lookup by EVM address — pick a real one from Grove's JAAA holding.
|
|
74
|
+
probe = EvmAddress("0x1121F4e21eD8B9BC1BB9A2952cDD8639aC897784")
|
|
75
|
+
print(f"=== Owner of address {probe} ===")
|
|
76
|
+
hit = prime_owning_address(probe)
|
|
77
|
+
if hit is None:
|
|
78
|
+
print(" (no match)")
|
|
79
|
+
else:
|
|
80
|
+
prime, token_name = hit
|
|
81
|
+
print(f" {prime.value.name} (token: {token_name})")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
"""Example 04 — Atlas provenance for every asset.
|
|
3
|
+
|
|
4
|
+
Every ``Asset`` carries two ``source`` strings: ``source`` (the Atlas
|
|
5
|
+
document number defining the wrapped/listed asset) and
|
|
6
|
+
``underlying_asset_source`` (the document defining the underlying token).
|
|
7
|
+
These are dot-separated identifiers like ``A.6.1.1.2.2.6.1.3.2.1.2.2.2.1``
|
|
8
|
+
that resolve to documents under ``content/`` (validated by the
|
|
9
|
+
``check-spec-uuids`` make target).
|
|
10
|
+
|
|
11
|
+
This example prints the provenance trail for each asset of a prime, so a
|
|
12
|
+
reviewer can jump straight from the spec entity to the Atlas document that
|
|
13
|
+
authorizes it.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from axis_synome.spec.asc.entities.primes import PrimeAgent
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def show_provenance(prime: PrimeAgent) -> None:
|
|
20
|
+
print(f"=== {prime.value.name} — asset provenance ===")
|
|
21
|
+
for asset in prime.value.assets:
|
|
22
|
+
print(f" {asset.token.value} on {asset.network.value} via {asset.protocol.value}")
|
|
23
|
+
print(f" address : {asset.address}")
|
|
24
|
+
print(f" Atlas doc (asset) : {asset.source}")
|
|
25
|
+
print(f" underlying token : {asset.underlying_asset.value}")
|
|
26
|
+
print(f" underlying address : {asset.underlying_asset_address}")
|
|
27
|
+
print(f" Atlas doc (underlying) : {asset.underlying_asset_source}")
|
|
28
|
+
print()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def main() -> None:
|
|
32
|
+
show_provenance(PrimeAgent.GROVE)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
main()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
"""Example 05 — Bridge external records into Positions and call a formula.
|
|
3
|
+
|
|
4
|
+
Once you know the *associated concepts* of a prime (examples 02 and 03),
|
|
5
|
+
the next step is feeding real-world holdings into a formula. This example
|
|
6
|
+
shows the canonical bridge pattern:
|
|
7
|
+
|
|
8
|
+
1. External data arrives as plain dicts (API response, CSV row, DB record).
|
|
9
|
+
2. ``record_to_position`` resolves token/protocol/network strings to enums
|
|
10
|
+
and builds ``Asset`` + ``Position`` instances.
|
|
11
|
+
3. We hand the resulting ``list[Position]`` to ``asc(...)`` to get a USD total.
|
|
12
|
+
|
|
13
|
+
The bridge intentionally lives outside the spec subset (which forbids I/O
|
|
14
|
+
and string→enum coercion). Only the formulas it feeds into are constrained.
|
|
15
|
+
|
|
16
|
+
Note: ``asc(...)`` requires the ``axis-synome[runtime]`` extra (numpy-backed
|
|
17
|
+
``ReferenceSpecRuntime``). It is installed in this repo's dev environment.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from axis_synome.spec.asc.entities.asset_categories import AssetCategory
|
|
21
|
+
from axis_synome.spec.asc.entities.assets import Asset
|
|
22
|
+
from axis_synome.spec.asc.entities.networks import Network
|
|
23
|
+
from axis_synome.spec.asc.entities.primes import EligiblePrimeAgentASC
|
|
24
|
+
from axis_synome.spec.asc.entities.protocol_sets import Protocol
|
|
25
|
+
from axis_synome.spec.asc.entities.tokens import Token
|
|
26
|
+
from axis_synome.spec.asc.entities.types import Position
|
|
27
|
+
from axis_synome.spec.asc.formulas.asc import asc
|
|
28
|
+
from axis_synome.spec_support.evm_address import EvmAddress
|
|
29
|
+
|
|
30
|
+
# A single placeholder address; real callers would pass the on-chain address
|
|
31
|
+
# of the holding (e.g., the LitePSM, the Curve pool, the Aave aToken, ...).
|
|
32
|
+
MOCK_ADDRESS = EvmAddress("0x1121F4e21eD8B9BC1BB9A2952cDD8639aC897784")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def record_to_position(rec: dict) -> Position:
|
|
36
|
+
"""Convert a raw record dict to a ``Position``.
|
|
37
|
+
|
|
38
|
+
Required keys: ``token``, ``protocol``, ``network``, ``value_usd``.
|
|
39
|
+
Optional keys: ``pool_paired_with_usds``, ``fee_tier``.
|
|
40
|
+
"""
|
|
41
|
+
return Position(
|
|
42
|
+
asset=Asset(
|
|
43
|
+
token=Token(rec["token"]),
|
|
44
|
+
protocol=Protocol(rec["protocol"]),
|
|
45
|
+
network=Network(rec["network"]),
|
|
46
|
+
address=MOCK_ADDRESS,
|
|
47
|
+
underlying_asset=Token(rec["token"]),
|
|
48
|
+
underlying_asset_address=MOCK_ADDRESS,
|
|
49
|
+
underlying_asset_source="",
|
|
50
|
+
categories={AssetCategory.CASH_STABLECOIN},
|
|
51
|
+
),
|
|
52
|
+
value_usd=float(rec["value_usd"]),
|
|
53
|
+
pool_paired_with_usds=rec.get("pool_paired_with_usds"),
|
|
54
|
+
fee_tier=rec.get("fee_tier"),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
# Pretend these came from an indexer or a CSV.
|
|
60
|
+
api_records = [
|
|
61
|
+
{
|
|
62
|
+
"token": "USDC",
|
|
63
|
+
"protocol": "LitePSM",
|
|
64
|
+
"network": "Ethereum Mainnet",
|
|
65
|
+
"value_usd": 500_000.0,
|
|
66
|
+
},
|
|
67
|
+
{"token": "USDC", "protocol": "PSM3", "network": "Base", "value_usd": 250_000.0},
|
|
68
|
+
{
|
|
69
|
+
"token": "USDC",
|
|
70
|
+
"protocol": "Curve",
|
|
71
|
+
"network": "Ethereum Mainnet",
|
|
72
|
+
"value_usd": 300_000.0,
|
|
73
|
+
"pool_paired_with_usds": True,
|
|
74
|
+
},
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
positions = [record_to_position(r) for r in api_records]
|
|
78
|
+
|
|
79
|
+
print(f"Built {len(positions)} positions from external records:")
|
|
80
|
+
for p in positions:
|
|
81
|
+
print(
|
|
82
|
+
f" - {p.asset.token.value:<6} via {p.asset.protocol.value:<10} "
|
|
83
|
+
f"on {p.asset.network.value:<18} = ${p.value_usd:,.2f}"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
total_asc = asc(EligiblePrimeAgentASC.SPARK, positions)
|
|
87
|
+
print(f"\nasc(SPARK, positions) = ${total_asc:,.2f}")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
main()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# axis-synome examples
|
|
2
|
+
|
|
3
|
+
Runnable, self-contained scripts that show how to navigate the entity graph
|
|
4
|
+
exposed by `axis_synome.spec` — answering questions like *"what assets does
|
|
5
|
+
Spark hold?"*, *"which primes operate on Base?"*, or *"which Atlas document
|
|
6
|
+
defines this token?"*.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The examples are numbered by complexity. Earlier ones introduce the core
|
|
11
|
+
entities; later ones build on them to do reverse lookups, surface Atlas
|
|
12
|
+
provenance, and bridge external data into a real formula call.
|
|
13
|
+
|
|
14
|
+
Each file is a plain Python script with a module docstring describing what
|
|
15
|
+
it shows and a `main()` that prints to stdout. They use only public imports
|
|
16
|
+
under `axis_synome.spec.asc.entities` and `axis_synome.spec.asc.formulas`,
|
|
17
|
+
and are exercised on every CI run by `tests/axis_synome/test_examples.py`,
|
|
18
|
+
so they cannot silently rot.
|
|
19
|
+
|
|
20
|
+
Run any of them directly:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd axis-synome
|
|
24
|
+
uv run python examples/02_assets_and_tokens_of_a_prime.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| File | Question it answers |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `01_prime_basics.py` | What does a `PrimeAgent` carry (name, networks, PSM protocols, asset count)? |
|
|
30
|
+
| `02_assets_and_tokens_of_a_prime.py` | Which `Asset`s and `Token`s does a given prime hold, grouped by network and protocol? |
|
|
31
|
+
| `03_inverse_lookups.py` | Which primes hold a given token? Which primes operate on a given network? Which prime owns an address? |
|
|
32
|
+
| `04_atlas_provenance.py` | Which Atlas document defines each asset and its underlying token? |
|
|
33
|
+
| `05_feeding_a_formula.py` | How do I bridge external records (API/CSV/DB rows) into `Position`s and call `asc(...)`? |
|
|
34
|
+
|
|
35
|
+
## Running specific spec formulas
|
|
36
|
+
|
|
37
|
+
For end-to-end usage of individual formulas — how to construct the
|
|
38
|
+
expected entity inputs, what the outputs look like, and how to bridge
|
|
39
|
+
external records into the call — read the formula tests under
|
|
40
|
+
`tests/axis_synome/`. They double as worked examples and are the
|
|
41
|
+
authoritative reference for how each formula is meant to be called:
|
|
42
|
+
|
|
43
|
+
- `tests/axis_synome/asc/test_asc.py` — `asc(prime, positions)` end-to-end,
|
|
44
|
+
including a bridge from an API-shaped `dict` into `Position`s
|
|
45
|
+
(`test_bridge_from_api_response`).
|
|
46
|
+
- `tests/axis_synome/asc/test_resting_asc.py`,
|
|
47
|
+
`test_latent_asc.py`, `test_ratio_latent_asc.py`,
|
|
48
|
+
`test_asc_collateral_ratio.py`, `test_asc_incentive.py`, `test_dab.py` —
|
|
49
|
+
one file per ASC sub-formula, each showing the smallest realistic input
|
|
50
|
+
set that exercises the formula.
|
|
51
|
+
- `tests/axis_synome/asc/mocks.py` — shared fixtures (`spark_resting_positions()`,
|
|
52
|
+
`spark_latent_positions()`, …) you can copy when building inputs.
|
|
53
|
+
- `tests/axis_synome/suraf/formulas/test_scoring.py`,
|
|
54
|
+
`tests/axis_synome/suraf/formulas/test_crr.py` — same pattern for the
|
|
55
|
+
SURAF scoring / collateral-risk-rating formulas.
|
|
56
|
+
|
|
57
|
+
When adding a new formula, add a `test_<formula>.py` next to the existing
|
|
58
|
+
ones; that test then becomes the worked example for callers.
|
|
@@ -25,6 +25,7 @@ Repository = "https://github.com/archon-research/next-gen-atlas"
|
|
|
25
25
|
Documentation = "https://github.com/archon-research/next-gen-atlas"
|
|
26
26
|
|
|
27
27
|
[project.scripts]
|
|
28
|
+
axis-spec-inspect = "axis_synome.spec_inspect.cli:main"
|
|
28
29
|
export_entities = "axis_synome.export_entities:main"
|
|
29
30
|
|
|
30
31
|
[project.entry-points."flake8.extension"]
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1, 0, '
|
|
21
|
+
__version__ = version = '0.1.0.dev64'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 0, 'dev64')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
{axis_synome-0.1.0.dev62 → axis_synome-0.1.0.dev64}/src/axis_synome/spec/asc/entities/tokens.py
RENAMED
|
@@ -56,14 +56,9 @@ class Token(Enum):
|
|
|
56
56
|
WETH = "WETH"
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
CASH_STABLECOINS = {Token.USDC, Token.
|
|
59
|
+
CASH_STABLECOINS = {Token.USDC, Token.USDT, Token.PYUSD}
|
|
60
60
|
"""Tokens treated as Cash Stablecoins for ASC/DAB calculations.
|
|
61
61
|
|
|
62
|
-
Note: The Atlas (A.3.3.2.1.3) currently defines Cash Stablecoins as
|
|
63
|
-
USDC, USDT, and pyUSD. This constant differs (includes USDS and DAI;
|
|
64
|
-
omits PYUSD) and the discrepancy should be reconciled — either by
|
|
65
|
-
amending the Atlas or by updating this set.
|
|
66
|
-
|
|
67
62
|
:source_uuid: 066a4d9f-13ed-4ac3-a55a-df7bf3429649
|
|
68
63
|
"""
|
|
69
64
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from axis_synome.spec.asc.entities.primes import EligiblePrimeAgentASC
|
|
2
|
+
from axis_synome.spec.asc.entities.tokens import Token
|
|
2
3
|
from axis_synome.spec.asc.entities.types import Position
|
|
3
4
|
from axis_synome.spec.asc.formulas.latent_asc import latent_asc
|
|
4
5
|
from axis_synome.spec.asc.formulas.resting_asc import resting_asc
|
|
@@ -7,13 +8,14 @@ from axis_synome.spec.asc.formulas.resting_asc import resting_asc
|
|
|
7
8
|
def collateral_portfolio(
|
|
8
9
|
positions: list[Position],
|
|
9
10
|
) -> float:
|
|
10
|
-
"""Total
|
|
11
|
+
"""Total capital deployed by the Prime Agent from Sky through the Allocation System, excluding USDS.
|
|
12
|
+
|
|
13
|
+
Positions are all assets the Prime has deployed via the Allocation System Primitive.
|
|
14
|
+
Any portion held in USDS is excluded per Atlas A.3.3.1.3.1.
|
|
11
15
|
|
|
12
16
|
:source_uuid: 64e1390f-68a1-43ec-87a8-8ae7b990f7ec
|
|
13
|
-
:ambiguity: collateral_portfolio sums all positions including USDS — Atlas
|
|
14
|
-
A.3.3.1.3.1 explicitly excludes USDS from the Agent Collateral Portfolio.
|
|
15
17
|
"""
|
|
16
|
-
return sum(p.value_usd for p in positions)
|
|
18
|
+
return sum(p.value_usd for p in positions if p.asset.underlying_asset != Token.USDS)
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
def asc_collateral_ratio(prime: EligiblePrimeAgentASC, positions: list[Position]) -> float:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from axis_synome.spec.asc.entities.primes import EligiblePrimeAgentASC
|
|
2
2
|
from axis_synome.spec.asc.entities.types import Position
|
|
3
|
+
from axis_synome.spec.asc.formulas.asc_collateral_ratio import collateral_portfolio
|
|
3
4
|
from axis_synome.spec.asc.formulas.latent_asc import latent_asc
|
|
4
5
|
from axis_synome.spec.asc.formulas.resting_asc import resting_asc
|
|
5
6
|
|
|
@@ -12,11 +13,13 @@ def asc_incentive(
|
|
|
12
13
|
) -> float:
|
|
13
14
|
"""ASC incentive payment: eligible ASC times (base_rate - treasury_bill_rate).
|
|
14
15
|
|
|
16
|
+
Eligible ASC is the lesser of actual ASC and minimum required ASC.
|
|
17
|
+
|
|
15
18
|
:source_uuid: 693330d6-9072-4054-bd61-d788537e34e8
|
|
16
|
-
:ambiguity: eligible_asc_usd = actual ASC with no min() cap — Atlas
|
|
17
|
-
A.3.3.2.2.4.1.1 defines Eligible ASC as the lesser of actual ASC and
|
|
18
|
-
Minimum ASC; the cap is absent, causing over-payment when actual ASC
|
|
19
|
-
exceeds the required minimum.
|
|
20
19
|
"""
|
|
21
|
-
|
|
20
|
+
actual_asc_usd: float = resting_asc(positions) + latent_asc(prime, positions)
|
|
21
|
+
agent = prime.value
|
|
22
|
+
portfolio_usd: float = collateral_portfolio(positions)
|
|
23
|
+
minimum_required_asc_usd: float = portfolio_usd * agent.min_pct_asc_of_collateral
|
|
24
|
+
eligible_asc_usd: float = min(actual_asc_usd, minimum_required_asc_usd)
|
|
22
25
|
return eligible_asc_usd * (base_rate - treasury_bill_rate)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from typing import Final
|
|
2
|
+
|
|
3
|
+
from axis_synome.spec.asc.entities.primes import EligiblePrimeAgentASC
|
|
4
|
+
from axis_synome.spec.asc.entities.types import Position
|
|
5
|
+
from axis_synome.spec.asc.formulas.asc_collateral_ratio import collateral_portfolio
|
|
6
|
+
|
|
7
|
+
DAB_REQUIRED_PCT: Final[float] = 0.25
|
|
8
|
+
"""Required DAB as a fraction of minimum required ASC.
|
|
9
|
+
|
|
10
|
+
:source_uuid: 1e129119-a2ce-4978-b235-c50f2a1c5e2e
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def dab_required(
|
|
15
|
+
prime: EligiblePrimeAgentASC,
|
|
16
|
+
positions: list[Position],
|
|
17
|
+
) -> float:
|
|
18
|
+
"""Required DAB: DAB_REQUIRED_PCT of minimum required ASC.
|
|
19
|
+
|
|
20
|
+
:source_uuid: 1e129119-a2ce-4978-b235-c50f2a1c5e2e
|
|
21
|
+
"""
|
|
22
|
+
agent = prime.value
|
|
23
|
+
portfolio_usd: float = collateral_portfolio(positions)
|
|
24
|
+
minimum_required_asc_usd: float = portfolio_usd * agent.min_pct_asc_of_collateral
|
|
25
|
+
return minimum_required_asc_usd * DAB_REQUIRED_PCT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Agent-friendly CLI for inspecting the spec tree.
|
|
2
|
+
|
|
3
|
+
Run as a module::
|
|
4
|
+
|
|
5
|
+
python -m axis_synome.spec_inspect <command> [args...]
|
|
6
|
+
|
|
7
|
+
See :mod:`axis_synome.spec_inspect.cli` for available subcommands.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from axis_synome.spec_inspect.cli import main
|
|
11
|
+
|
|
12
|
+
__all__ = ["main"]
|