agentevolve-optimizer 0.5.0__py3-none-any.whl
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.
- agent_evolve/__init__.py +722 -0
- agent_evolve/agentic.py +2800 -0
- agent_evolve/api.py +767 -0
- agent_evolve/application/__init__.py +1580 -0
- agent_evolve/application/action_allocation.py +744 -0
- agent_evolve/application/action_allocation_frame.py +347 -0
- agent_evolve/application/action_allocation_frame_commit.py +185 -0
- agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
- agent_evolve/application/action_allocation_frame_v3.py +338 -0
- agent_evolve/application/action_archive_value.py +497 -0
- agent_evolve/application/action_evidence_consistency.py +455 -0
- agent_evolve/application/action_forecast_partitioning.py +1471 -0
- agent_evolve/application/action_metric_projection.py +211 -0
- agent_evolve/application/action_role_value.py +680 -0
- agent_evolve/application/action_score_authorities.py +363 -0
- agent_evolve/application/action_structural_signature.py +116 -0
- agent_evolve/application/action_target_realization.py +402 -0
- agent_evolve/application/agentic_evolution.py +7734 -0
- agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
- agent_evolve/application/anchor_residual_identification.py +463 -0
- agent_evolve/application/archive_conditioned_action_target.py +208 -0
- agent_evolve/application/artifact_journal.py +246 -0
- agent_evolve/application/artifact_replay.py +347 -0
- agent_evolve/application/budgeted_optimizer.py +1828 -0
- agent_evolve/application/calibrated_campaign.py +485 -0
- agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
- agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
- agent_evolve/application/campaign_capacity_recourse.py +254 -0
- agent_evolve/application/campaign_contextual_outcomes.py +119 -0
- agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
- agent_evolve/application/campaign_evidence_registry.py +262 -0
- agent_evolve/application/campaign_execution.py +2537 -0
- agent_evolve/application/campaign_generation_audit.py +942 -0
- agent_evolve/application/campaign_learning.py +1812 -0
- agent_evolve/application/campaign_learning_runtime.py +1977 -0
- agent_evolve/application/campaign_search_phase.py +227 -0
- agent_evolve/application/campaign_selector_context_extension.py +220 -0
- agent_evolve/application/campaign_variation_envelope.py +649 -0
- agent_evolve/application/campaign_variation_trace.py +451 -0
- agent_evolve/application/candidate_archive_consequence.py +128 -0
- agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
- agent_evolve/application/composite_outcome_updater.py +145 -0
- agent_evolve/application/composition_portfolio_selection.py +363 -0
- agent_evolve/application/concurrent_stage.py +144 -0
- agent_evolve/application/contextual_action_allocation.py +181 -0
- agent_evolve/application/contextual_campaign_outcomes.py +267 -0
- agent_evolve/application/contextual_campaign_planning.py +1366 -0
- agent_evolve/application/contextual_delayed_credit.py +651 -0
- agent_evolve/application/contextual_search_controller.py +2374 -0
- agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
- agent_evolve/application/decision_metric_projection.py +112 -0
- agent_evolve/application/derived_action_semantics.py +129 -0
- agent_evolve/application/detailed_evaluation.py +449 -0
- agent_evolve/application/earned_lineage.py +1011 -0
- agent_evolve/application/effective_choice_audit.py +484 -0
- agent_evolve/application/empirical_consequence_calibration.py +908 -0
- agent_evolve/application/evaluation_accounting.py +325 -0
- agent_evolve/application/evaluation_cache.py +199 -0
- agent_evolve/application/evaluation_escrow.py +547 -0
- agent_evolve/application/evaluation_recourse.py +253 -0
- agent_evolve/application/event_recorder.py +151 -0
- agent_evolve/application/evolution_campaign.py +1840 -0
- agent_evolve/application/executable_hypothesis.py +323 -0
- agent_evolve/application/factorial_branch_pilot.py +772 -0
- agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
- agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
- agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
- agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
- agent_evolve/application/finite_action_selection.py +188 -0
- agent_evolve/application/finite_action_set.py +306 -0
- agent_evolve/application/finite_action_transition.py +537 -0
- agent_evolve/application/finite_variation_eligibility.py +296 -0
- agent_evolve/application/forecast_geometry_portfolio.py +799 -0
- agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
- agent_evolve/application/front_proximity_admission.py +311 -0
- agent_evolve/application/front_proximity_parent_basis.py +458 -0
- agent_evolve/application/frozen_hurdle_score.py +659 -0
- agent_evolve/application/g3_causal_screen.py +2257 -0
- agent_evolve/application/g3_causal_validation.py +1046 -0
- agent_evolve/application/g3_postseal_curation.py +818 -0
- agent_evolve/application/gated_agentic_generator.py +205 -0
- agent_evolve/application/generation_feedback.py +293 -0
- agent_evolve/application/generative_proposal_journal.py +185 -0
- agent_evolve/application/geometry_conditional_elasticity.py +453 -0
- agent_evolve/application/global_wave_action_allocation.py +1151 -0
- agent_evolve/application/head_mass_conditional_seat.py +268 -0
- agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
- agent_evolve/application/identifiable_reflection_learning.py +395 -0
- agent_evolve/application/identifiable_reflection_request.py +364 -0
- agent_evolve/application/in_memory_residual_archive.py +341 -0
- agent_evolve/application/insight_memory.py +1804 -0
- agent_evolve/application/live_runtime_manifest.py +758 -0
- agent_evolve/application/llm_task_queue.py +769 -0
- agent_evolve/application/matched_finite_action_block.py +409 -0
- agent_evolve/application/materialized_action_broker.py +2328 -0
- agent_evolve/application/materialized_action_constraints.py +83 -0
- agent_evolve/application/materialized_variation.py +211 -0
- agent_evolve/application/multi_option_evolution.py +1536 -0
- agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
- agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
- agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
- agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
- agent_evolve/application/outcome_relation.py +193 -0
- agent_evolve/application/paired_allocation_comparison.py +241 -0
- agent_evolve/application/paired_block_schedule.py +127 -0
- agent_evolve/application/parent_measurement.py +226 -0
- agent_evolve/application/pareto_archive.py +811 -0
- agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
- agent_evolve/application/portfolio_evolution.py +2950 -0
- agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
- agent_evolve/application/portfolio_memory_attribution.py +581 -0
- agent_evolve/application/portfolio_memory_dose.py +788 -0
- agent_evolve/application/portfolio_memory_matched_control.py +938 -0
- agent_evolve/application/portfolio_memory_transfer.py +297 -0
- agent_evolve/application/portfolio_optimization_memory.py +363 -0
- agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
- agent_evolve/application/portfolio_projection.py +335 -0
- agent_evolve/application/portfolio_recombination.py +2032 -0
- agent_evolve/application/post_evolution_reflection.py +834 -0
- agent_evolve/application/postcommit_rank_authority.py +245 -0
- agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
- agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
- agent_evolve/application/prequential_residual_exploration.py +343 -0
- agent_evolve/application/prequential_score_portfolio.py +954 -0
- agent_evolve/application/projections.py +292 -0
- agent_evolve/application/protected_action_committee.py +1027 -0
- agent_evolve/application/protected_branch_pilot.py +376 -0
- agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
- agent_evolve/application/provider_replay.py +910 -0
- agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
- agent_evolve/application/recombination_residual_expert.py +403 -0
- agent_evolve/application/reflection_workflow.py +571 -0
- agent_evolve/application/region_conditional_credit.py +911 -0
- agent_evolve/application/residual_campaign_runtime.py +531 -0
- agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
- agent_evolve/application/residual_headroom_ledger.py +1544 -0
- agent_evolve/application/residual_learning_transaction.py +396 -0
- agent_evolve/application/residual_portfolio_evolution.py +1228 -0
- agent_evolve/application/residual_reachability.py +749 -0
- agent_evolve/application/residual_stage_credit.py +499 -0
- agent_evolve/application/same_prefix_paired_audit.py +1580 -0
- agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
- agent_evolve/application/sequential_lineage_allocation.py +1017 -0
- agent_evolve/application/sequential_market_replay.py +1395 -0
- agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
- agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
- agent_evolve/application/single_score_action_allocation.py +299 -0
- agent_evolve/application/source_exposure_allocation.py +906 -0
- agent_evolve/application/staged_memory.py +210 -0
- agent_evolve/application/stratified_cold_start_allocation.py +732 -0
- agent_evolve/application/support_guarded_hurdle_score.py +549 -0
- agent_evolve/application/target_conditioned_action_forecast.py +595 -0
- agent_evolve/application/target_conditioned_campaign.py +566 -0
- agent_evolve/application/treatment_assignment.py +201 -0
- agent_evolve/application/trusted_objective_evidence.py +217 -0
- agent_evolve/application/two_stage_action_evolution.py +1131 -0
- agent_evolve/application/v8lite_allocation_policy.py +1083 -0
- agent_evolve/application/v9_candidate_policy.py +1303 -0
- agent_evolve/bootstrap.py +108 -0
- agent_evolve/campaign_presets.py +517 -0
- agent_evolve/campaign_profiles.py +452 -0
- agent_evolve/campaign_variation_topology.py +288 -0
- agent_evolve/campaign_workload.py +950 -0
- agent_evolve/cli.py +797 -0
- agent_evolve/contract.py +241 -0
- agent_evolve/core/__init__.py +91 -0
- agent_evolve/core/action_semantics.py +411 -0
- agent_evolve/core/authored.py +105 -0
- agent_evolve/core/formatting.py +286 -0
- agent_evolve/core/optimization_semantics.py +324 -0
- agent_evolve/core/problem.py +167 -0
- agent_evolve/core/results.py +323 -0
- agent_evolve/core/stats.py +70 -0
- agent_evolve/core/telemetry.py +100 -0
- agent_evolve/domain/__init__.py +89 -0
- agent_evolve/domain/artifact.py +162 -0
- agent_evolve/domain/durable_text.py +68 -0
- agent_evolve/domain/event.py +1454 -0
- agent_evolve/domain/finite_action_set.py +426 -0
- agent_evolve/domain/finite_variation.py +526 -0
- agent_evolve/domain/generative_emission.py +559 -0
- agent_evolve/domain/ids.py +163 -0
- agent_evolve/domain/inline_text.py +106 -0
- agent_evolve/domain/insight.py +27 -0
- agent_evolve/domain/lineage.py +737 -0
- agent_evolve/domain/llm_task_queue.py +960 -0
- agent_evolve/domain/outcome.py +96 -0
- agent_evolve/domain/patch.py +854 -0
- agent_evolve/domain/typed_json.py +542 -0
- agent_evolve/domain/variation_space.py +158 -0
- agent_evolve/driver.py +1014 -0
- agent_evolve/harness/__init__.py +29 -0
- agent_evolve/harness/base.py +242 -0
- agent_evolve/harness/directives.py +163 -0
- agent_evolve/harness/generative_seal.py +479 -0
- agent_evolve/harness/registry.py +41 -0
- agent_evolve/infrastructure/__init__.py +39 -0
- agent_evolve/infrastructure/artifacts/__init__.py +6 -0
- agent_evolve/infrastructure/artifacts/_verification.py +67 -0
- agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
- agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
- agent_evolve/infrastructure/asyncio_runtime.py +109 -0
- agent_evolve/infrastructure/authored_runtime.py +188 -0
- agent_evolve/infrastructure/authored_worker.py +171 -0
- agent_evolve/infrastructure/clock.py +53 -0
- agent_evolve/infrastructure/events/__init__.py +6 -0
- agent_evolve/infrastructure/events/_validation.py +89 -0
- agent_evolve/infrastructure/events/in_memory.py +56 -0
- agent_evolve/infrastructure/events/jsonl.py +193 -0
- agent_evolve/infrastructure/exception_provenance.py +215 -0
- agent_evolve/infrastructure/ids.py +118 -0
- agent_evolve/infrastructure/lineage_codec.py +1836 -0
- agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
- agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
- agent_evolve/infrastructure/resource_lease.py +370 -0
- agent_evolve/infrastructure/sanitization/__init__.py +8 -0
- agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
- agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
- agent_evolve/infrastructure/stream_liveness.py +383 -0
- agent_evolve/infrastructure/subprocess_boundary.py +136 -0
- agent_evolve/integrations/__init__.py +1 -0
- agent_evolve/integrations/botorch/__init__.py +28 -0
- agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
- agent_evolve/integrations/completion.py +242 -0
- agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
- agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
- agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
- agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
- agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
- agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
- agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
- agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
- agent_evolve/integrations/pydantic_ai/harness.py +159 -0
- agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
- agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
- agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
- agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
- agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
- agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
- agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
- agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
- agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
- agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
- agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
- agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
- agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
- agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
- agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
- agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
- agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
- agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
- agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
- agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
- agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
- agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
- agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
- agent_evolve/integrations/pymoo_adapter.py +242 -0
- agent_evolve/policies/__init__.py +17 -0
- agent_evolve/policies/check.py +469 -0
- agent_evolve/policies/emit_scaffold.py +451 -0
- agent_evolve/policies/feedback/__init__.py +37 -0
- agent_evolve/policies/feedback/held_out_asn.py +1325 -0
- agent_evolve/policies/genetic.py +607 -0
- agent_evolve/policies/llm_backoff.py +183 -0
- agent_evolve/policies/llm_chooser.py +226 -0
- agent_evolve/policies/llm_generator.py +1760 -0
- agent_evolve/policies/llm_init.py +267 -0
- agent_evolve/policies/llm_operator.py +109 -0
- agent_evolve/policies/llm_prior.py +194 -0
- agent_evolve/policies/llm_surrogate.py +334 -0
- agent_evolve/policies/measurement_evidence.py +704 -0
- agent_evolve/policies/memory/__init__.py +223 -0
- agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
- agent_evolve/policies/memory/compatibility_matching.py +593 -0
- agent_evolve/policies/memory/global_falsification.py +1841 -0
- agent_evolve/policies/memory/prompt_shape.py +503 -0
- agent_evolve/policies/memory/randomized_subset.py +714 -0
- agent_evolve/policies/memory/staged_causal.py +1270 -0
- agent_evolve/policies/memory/treatment_compliance.py +759 -0
- agent_evolve/policies/objective_resolution/__init__.py +17 -0
- agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
- agent_evolve/policies/operator_portfolio.py +407 -0
- agent_evolve/policies/reguidance.py +1133 -0
- agent_evolve/policies/reward/__init__.py +83 -0
- agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
- agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
- agent_evolve/policies/reward/affine_hypervolume.py +490 -0
- agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
- agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
- agent_evolve/policies/reward/frozen_archive.py +360 -0
- agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
- agent_evolve/policies/search_state.py +208 -0
- agent_evolve/policies/selection/__init__.py +345 -0
- agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
- agent_evolve/policies/selection/affine_frontier_context.py +330 -0
- agent_evolve/policies/selection/affine_frontier_target.py +473 -0
- agent_evolve/policies/selection/archive_elite.py +1346 -0
- agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
- agent_evolve/policies/selection/calibrated_slate.py +1394 -0
- agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
- agent_evolve/policies/selection/common_candidate_pool.py +685 -0
- agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
- agent_evolve/policies/selection/disjoint_pairs.py +479 -0
- agent_evolve/policies/selection/elite_explorer.py +719 -0
- agent_evolve/policies/selection/finite_action.py +187 -0
- agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
- agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
- agent_evolve/policies/selection/forecast_calibration.py +922 -0
- agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
- agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
- agent_evolve/policies/selection/full_support_slate.py +91 -0
- agent_evolve/policies/selection/meaningful_direction.py +240 -0
- agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
- agent_evolve/policies/selection/model_anchored_slate.py +826 -0
- agent_evolve/policies/selection/phenotype_recourse.py +979 -0
- agent_evolve/policies/selection/proposal_support.py +368 -0
- agent_evolve/policies/selection/random_portfolio.py +254 -0
- agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
- agent_evolve/policies/selection/residual_frontier.py +463 -0
- agent_evolve/policies/selection/residual_frontier_target.py +605 -0
- agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
- agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
- agent_evolve/policies/selection/target_conditioned_features.py +812 -0
- agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
- agent_evolve/policies/selection/task_keyed_palette.py +906 -0
- agent_evolve/policies/semantics.py +147 -0
- agent_evolve/policies/structure.py +362 -0
- agent_evolve/policies/structured_output_budget.py +62 -0
- agent_evolve/policies/surrogate.py +696 -0
- agent_evolve/policies/variation/__init__.py +1 -0
- agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
- agent_evolve/policies/variation/crossover_inheritance.py +575 -0
- agent_evolve/policies/variation/disjoint_recombination.py +611 -0
- agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
- agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
- agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
- agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
- agent_evolve/policies/variation/typed_patch.py +1981 -0
- agent_evolve/policies/weighted_prior.py +394 -0
- agent_evolve/ports/__init__.py +383 -0
- agent_evolve/ports/action_allocation.py +733 -0
- agent_evolve/ports/action_allocation_frame.py +1153 -0
- agent_evolve/ports/action_allocation_frame_commit.py +294 -0
- agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
- agent_evolve/ports/action_allocation_frame_v3.py +995 -0
- agent_evolve/ports/action_forecast.py +1568 -0
- agent_evolve/ports/action_metric_projection.py +165 -0
- agent_evolve/ports/agentic_generator.py +1561 -0
- agent_evolve/ports/archive_context.py +136 -0
- agent_evolve/ports/artifact_sanitizer.py +44 -0
- agent_evolve/ports/artifact_store.py +225 -0
- agent_evolve/ports/clock.py +13 -0
- agent_evolve/ports/contextual_search_allocation.py +827 -0
- agent_evolve/ports/decision_metric_projection.py +258 -0
- agent_evolve/ports/event_store.py +55 -0
- agent_evolve/ports/executable_hypothesis.py +557 -0
- agent_evolve/ports/finite_acquisition.py +377 -0
- agent_evolve/ports/finite_acquisition_batch.py +296 -0
- agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
- agent_evolve/ports/finite_acquisition_json.py +247 -0
- agent_evolve/ports/finite_acquisition_space.py +168 -0
- agent_evolve/ports/finite_action_selection.py +348 -0
- agent_evolve/ports/finite_action_set.py +256 -0
- agent_evolve/ports/frontier_target.py +396 -0
- agent_evolve/ports/generation_failure.py +43 -0
- agent_evolve/ports/hard_feasibility.py +233 -0
- agent_evolve/ports/id_factory.py +34 -0
- agent_evolve/ports/llm_task_queue.py +93 -0
- agent_evolve/ports/objective_resolution.py +419 -0
- agent_evolve/ports/paired_allocation_comparison.py +401 -0
- agent_evolve/ports/paired_block_schedule.py +475 -0
- agent_evolve/ports/parent_measurement.py +336 -0
- agent_evolve/ports/portfolio_memory_dose.py +643 -0
- agent_evolve/ports/portfolio_selection.py +3169 -0
- agent_evolve/ports/postcommit_rank_authority.py +467 -0
- agent_evolve/ports/presented_action_evidence.py +794 -0
- agent_evolve/ports/resource_lease.py +162 -0
- agent_evolve/ports/structured_generator.py +734 -0
- agent_evolve/ports/structured_output_budget.py +120 -0
- agent_evolve/ports/subprocess_boundary.py +138 -0
- agent_evolve/ports/treatment_assignment.py +466 -0
- agent_evolve/ports/variation_catalog.py +76 -0
- agent_evolve/ports/variation_source.py +226 -0
- agent_evolve/proposal_mode.py +157 -0
- agent_evolve/proposers/__init__.py +10 -0
- agent_evolve/proposers/random_proposer.py +188 -0
- agent_evolve/provider_accounting.py +163 -0
- agent_evolve/py.typed +0 -0
- agent_evolve/reference_method.py +1570 -0
- agent_evolve/session/__init__.py +11 -0
- agent_evolve/session/authorship.py +864 -0
- agent_evolve/session/evaluate.py +236 -0
- agent_evolve/session/fidelity.py +237 -0
- agent_evolve/session/genetic_loop.py +742 -0
- agent_evolve/session/loop.py +803 -0
- agent_evolve/session/screening.py +671 -0
- agent_evolve/settings.py +376 -0
- agent_evolve/workload_kit.py +368 -0
- agent_evolve/workload_prompt.py +398 -0
- agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
- agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
- agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
- agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
- agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
- agentevolve_optimizer-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1027 @@
|
|
|
1
|
+
"""Protected action-level aggregation of outcome-blind allocation policies.
|
|
2
|
+
|
|
3
|
+
Complete-slate policies are treated as ballots over a shared sealed action
|
|
4
|
+
market. The committee preserves a configurable floor from one forecast-neutral
|
|
5
|
+
ballot, samples a precommitted uniform disagreement audit with exact marginal
|
|
6
|
+
propensities, and fills the remaining exact-K slate by weighted ballot
|
|
7
|
+
consensus. It never observes current candidate outcomes.
|
|
8
|
+
|
|
9
|
+
This is intentionally a generic application policy. It knows no workload,
|
|
10
|
+
objective, model, provider, prompt, or simulator field.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
import hashlib
|
|
18
|
+
from itertools import combinations
|
|
19
|
+
import json
|
|
20
|
+
import math
|
|
21
|
+
|
|
22
|
+
from agent_evolve.domain.typed_json import freeze_json
|
|
23
|
+
|
|
24
|
+
from .materialized_action_broker import (
|
|
25
|
+
MaterializedActionAllocationRequirement,
|
|
26
|
+
MaterializedActionDescriptor,
|
|
27
|
+
MaterializedSlateFeasibilityPort,
|
|
28
|
+
)
|
|
29
|
+
from .residual_portfolio_evolution import (
|
|
30
|
+
MaterializedActionAllocationPolicyPort,
|
|
31
|
+
MaterializedActionProposalBatch,
|
|
32
|
+
ResidualPortfolioDecisionRequest,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
PROTECTED_ACTION_COMMITTEE_POLICY_ID = "protected_action_committee"
|
|
37
|
+
PROTECTED_ACTION_COMMITTEE_POLICY_VERSION = 1
|
|
38
|
+
_DEFINITION_DOMAIN = b"agent-evolve:protected-action-committee:v1\x00"
|
|
39
|
+
_AUDIT_PRIORITY_DOMAIN = b"agent-evolve:protected-action-committee-audit:v1\x00"
|
|
40
|
+
_AUDIT_SUBSET_PRIORITY_DOMAIN = (
|
|
41
|
+
b"agent-evolve:protected-action-committee-audit-subset:v1\x00"
|
|
42
|
+
)
|
|
43
|
+
_MAX_FEASIBILITY_REPAIR_TRIALS = 100_000
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _canonical_json(value: object) -> bytes:
|
|
47
|
+
return json.dumps(
|
|
48
|
+
value,
|
|
49
|
+
allow_nan=False,
|
|
50
|
+
ensure_ascii=True,
|
|
51
|
+
separators=(",", ":"),
|
|
52
|
+
sort_keys=True,
|
|
53
|
+
).encode("ascii")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _require_sha256(value: str, name: str) -> None:
|
|
57
|
+
if (
|
|
58
|
+
type(value) is not str
|
|
59
|
+
or len(value) != 64
|
|
60
|
+
or any(character not in "0123456789abcdef" for character in value)
|
|
61
|
+
):
|
|
62
|
+
raise ValueError(f"{name} must be a lowercase SHA-256 hex digest")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(frozen=True, slots=True)
|
|
66
|
+
class ActionCommitteeArmBinding:
|
|
67
|
+
"""One outcome-blind complete-slate ballot and its prior trust weight."""
|
|
68
|
+
|
|
69
|
+
arm_id: str
|
|
70
|
+
policy: MaterializedActionAllocationPolicyPort = field(
|
|
71
|
+
repr=False,
|
|
72
|
+
compare=False,
|
|
73
|
+
)
|
|
74
|
+
weight: float
|
|
75
|
+
behavior_definition_sha256: str | None = None
|
|
76
|
+
|
|
77
|
+
def __post_init__(self) -> None:
|
|
78
|
+
if type(self.arm_id) is not str or not self.arm_id:
|
|
79
|
+
raise ValueError("arm_id must be non-empty")
|
|
80
|
+
if not isinstance(self.policy, MaterializedActionAllocationPolicyPort):
|
|
81
|
+
raise TypeError("policy must implement its allocation port")
|
|
82
|
+
if type(self.weight) is not float or not math.isfinite(self.weight):
|
|
83
|
+
raise TypeError("weight must be a finite exact float")
|
|
84
|
+
if self.weight <= 0.0:
|
|
85
|
+
raise ValueError("weight must be positive")
|
|
86
|
+
if self.behavior_definition_sha256 is not None:
|
|
87
|
+
_require_sha256(
|
|
88
|
+
self.behavior_definition_sha256,
|
|
89
|
+
"behavior_definition_sha256",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def identity_record(self) -> dict[str, object]:
|
|
93
|
+
self.__post_init__()
|
|
94
|
+
return {
|
|
95
|
+
"arm_id": self.arm_id,
|
|
96
|
+
"weight_hex": self.weight.hex(),
|
|
97
|
+
"behavior_definition_sha256": (
|
|
98
|
+
self.policy.definition_sha256
|
|
99
|
+
if self.behavior_definition_sha256 is None
|
|
100
|
+
else self.behavior_definition_sha256
|
|
101
|
+
),
|
|
102
|
+
"policy": {
|
|
103
|
+
"policy_id": self.policy.policy_id,
|
|
104
|
+
"policy_version": self.policy.policy_version,
|
|
105
|
+
"definition_sha256": self.policy.definition_sha256,
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@dataclass(frozen=True, slots=True)
|
|
111
|
+
class _CommitteeAction:
|
|
112
|
+
action: MaterializedActionDescriptor
|
|
113
|
+
arm_ids: tuple[str, ...]
|
|
114
|
+
normalized_weighted_support: float
|
|
115
|
+
effective_support: float
|
|
116
|
+
support_count: int
|
|
117
|
+
protected_member: bool
|
|
118
|
+
|
|
119
|
+
def consensus_key(self) -> tuple[float, float, int, str]:
|
|
120
|
+
return (
|
|
121
|
+
-self.normalized_weighted_support,
|
|
122
|
+
-self.effective_support,
|
|
123
|
+
self.action.native_rank,
|
|
124
|
+
self.action.action_sha256,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclass(frozen=True, slots=True)
|
|
129
|
+
class ProtectedActionCommitteePolicy:
|
|
130
|
+
"""Aggregate policy ballots into one protected, auditable exact-K slate.
|
|
131
|
+
|
|
132
|
+
The randomized audit is uniform over feasible audit subsets. Without an
|
|
133
|
+
additional slate constraint, every audit-pool representative has exact
|
|
134
|
+
marginal inclusion probability ``audit_slots / audit_pool_size``.
|
|
135
|
+
Constraint-filtered subset marginals are enumerated and logged exactly.
|
|
136
|
+
The precommitted seed makes the draw replayable while preserving the
|
|
137
|
+
declared randomization distribution.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
arm_bindings: tuple[ActionCommitteeArmBinding, ...]
|
|
141
|
+
protected_arm_id: str
|
|
142
|
+
protected_slots: int
|
|
143
|
+
audit_slots: int
|
|
144
|
+
audit_seed_sha256: str
|
|
145
|
+
slate_feasibility: MaterializedSlateFeasibilityPort | None = field(
|
|
146
|
+
default=None,
|
|
147
|
+
repr=False,
|
|
148
|
+
compare=False,
|
|
149
|
+
)
|
|
150
|
+
policy_id: str = PROTECTED_ACTION_COMMITTEE_POLICY_ID
|
|
151
|
+
policy_version: int = PROTECTED_ACTION_COMMITTEE_POLICY_VERSION
|
|
152
|
+
definition_sha256: str = field(init=False)
|
|
153
|
+
|
|
154
|
+
def __post_init__(self) -> None:
|
|
155
|
+
if (
|
|
156
|
+
type(self.arm_bindings) is not tuple
|
|
157
|
+
or len(self.arm_bindings) < 2
|
|
158
|
+
or any(
|
|
159
|
+
type(value) is not ActionCommitteeArmBinding
|
|
160
|
+
for value in self.arm_bindings
|
|
161
|
+
)
|
|
162
|
+
):
|
|
163
|
+
raise TypeError(
|
|
164
|
+
"arm_bindings must contain at least two exact bindings"
|
|
165
|
+
)
|
|
166
|
+
for value in self.arm_bindings:
|
|
167
|
+
value.__post_init__()
|
|
168
|
+
arm_ids = tuple(value.arm_id for value in self.arm_bindings)
|
|
169
|
+
if arm_ids != tuple(sorted(set(arm_ids))):
|
|
170
|
+
raise ValueError("arm bindings must be unique and canonical")
|
|
171
|
+
if (
|
|
172
|
+
type(self.protected_arm_id) is not str
|
|
173
|
+
or self.protected_arm_id not in arm_ids
|
|
174
|
+
):
|
|
175
|
+
raise ValueError("protected_arm_id must name one bound arm")
|
|
176
|
+
for value, name in (
|
|
177
|
+
(self.protected_slots, "protected_slots"),
|
|
178
|
+
(self.audit_slots, "audit_slots"),
|
|
179
|
+
):
|
|
180
|
+
if type(value) is not int or value < 0:
|
|
181
|
+
raise ValueError(f"{name} must be a non-negative exact integer")
|
|
182
|
+
_require_sha256(self.audit_seed_sha256, "audit_seed_sha256")
|
|
183
|
+
if self.slate_feasibility is not None:
|
|
184
|
+
if not isinstance(
|
|
185
|
+
self.slate_feasibility,
|
|
186
|
+
MaterializedSlateFeasibilityPort,
|
|
187
|
+
):
|
|
188
|
+
raise TypeError(
|
|
189
|
+
"slate_feasibility must implement its application port"
|
|
190
|
+
)
|
|
191
|
+
_require_sha256(
|
|
192
|
+
self.slate_feasibility.definition_sha256,
|
|
193
|
+
"slate_feasibility definition_sha256",
|
|
194
|
+
)
|
|
195
|
+
if (
|
|
196
|
+
self.policy_id != PROTECTED_ACTION_COMMITTEE_POLICY_ID
|
|
197
|
+
or self.policy_version
|
|
198
|
+
!= PROTECTED_ACTION_COMMITTEE_POLICY_VERSION
|
|
199
|
+
):
|
|
200
|
+
raise ValueError("committee policy identity is immutable")
|
|
201
|
+
object.__setattr__(
|
|
202
|
+
self,
|
|
203
|
+
"definition_sha256",
|
|
204
|
+
hashlib.sha256(
|
|
205
|
+
_DEFINITION_DOMAIN
|
|
206
|
+
+ _canonical_json(
|
|
207
|
+
{
|
|
208
|
+
"schema_version": 1,
|
|
209
|
+
"policy_id": self.policy_id,
|
|
210
|
+
"policy_version": self.policy_version,
|
|
211
|
+
"arms": [
|
|
212
|
+
value.identity_record()
|
|
213
|
+
for value in self.arm_bindings
|
|
214
|
+
],
|
|
215
|
+
"protected_arm_id": self.protected_arm_id,
|
|
216
|
+
"protected_slots": self.protected_slots,
|
|
217
|
+
"audit_slots": self.audit_slots,
|
|
218
|
+
"audit_seed_sha256": self.audit_seed_sha256,
|
|
219
|
+
"slate_feasibility_definition_sha256": (
|
|
220
|
+
None
|
|
221
|
+
if self.slate_feasibility is None
|
|
222
|
+
else self.slate_feasibility.definition_sha256
|
|
223
|
+
),
|
|
224
|
+
"consensus": (
|
|
225
|
+
"jaccard_redundancy_adjusted_normalized_weighted_"
|
|
226
|
+
"ballot_membership_then_effective_support_then_"
|
|
227
|
+
"native_rank"
|
|
228
|
+
),
|
|
229
|
+
"audit": (
|
|
230
|
+
"uniform_over_feasible_disagreement_phenotype_"
|
|
231
|
+
"subsets_with_exact_marginals"
|
|
232
|
+
),
|
|
233
|
+
"candidate_outcomes_observed": False,
|
|
234
|
+
"workload_model_provider_branches": False,
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
).hexdigest(),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
@staticmethod
|
|
241
|
+
def _action_market(
|
|
242
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
243
|
+
) -> dict[str, MaterializedActionDescriptor]:
|
|
244
|
+
result: dict[str, MaterializedActionDescriptor] = {}
|
|
245
|
+
for proposal in proposals:
|
|
246
|
+
for action in proposal.actions:
|
|
247
|
+
if action.action_sha256 in result:
|
|
248
|
+
raise ValueError("proposal union repeats an action identity")
|
|
249
|
+
result[action.action_sha256] = action
|
|
250
|
+
return result
|
|
251
|
+
|
|
252
|
+
@staticmethod
|
|
253
|
+
def _phenotype_representatives(
|
|
254
|
+
values: list[_CommitteeAction],
|
|
255
|
+
*,
|
|
256
|
+
normalized_weight_by_arm: dict[str, float],
|
|
257
|
+
effective_vote_by_arm: dict[str, float],
|
|
258
|
+
) -> list[_CommitteeAction]:
|
|
259
|
+
by_phenotype: dict[str, list[_CommitteeAction]] = {}
|
|
260
|
+
for value in values:
|
|
261
|
+
by_phenotype.setdefault(
|
|
262
|
+
value.action.phenotype_identity_sha256,
|
|
263
|
+
[],
|
|
264
|
+
).append(value)
|
|
265
|
+
result: list[_CommitteeAction] = []
|
|
266
|
+
for phenotype_values in by_phenotype.values():
|
|
267
|
+
representative = min(
|
|
268
|
+
phenotype_values,
|
|
269
|
+
key=lambda item: item.consensus_key(),
|
|
270
|
+
)
|
|
271
|
+
arm_ids = tuple(
|
|
272
|
+
sorted(
|
|
273
|
+
{
|
|
274
|
+
arm_id
|
|
275
|
+
for value in phenotype_values
|
|
276
|
+
for arm_id in value.arm_ids
|
|
277
|
+
}
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
result.append(
|
|
281
|
+
_CommitteeAction(
|
|
282
|
+
action=representative.action,
|
|
283
|
+
arm_ids=arm_ids,
|
|
284
|
+
normalized_weighted_support=math.fsum(
|
|
285
|
+
normalized_weight_by_arm[arm_id]
|
|
286
|
+
for arm_id in arm_ids
|
|
287
|
+
),
|
|
288
|
+
effective_support=math.fsum(
|
|
289
|
+
effective_vote_by_arm[arm_id]
|
|
290
|
+
for arm_id in arm_ids
|
|
291
|
+
),
|
|
292
|
+
support_count=len(arm_ids),
|
|
293
|
+
protected_member=any(
|
|
294
|
+
value.protected_member
|
|
295
|
+
for value in phenotype_values
|
|
296
|
+
),
|
|
297
|
+
)
|
|
298
|
+
)
|
|
299
|
+
return result
|
|
300
|
+
|
|
301
|
+
def _audit_priority(
|
|
302
|
+
self,
|
|
303
|
+
*,
|
|
304
|
+
request_sha256: str,
|
|
305
|
+
phenotype_identity_sha256: str,
|
|
306
|
+
) -> str:
|
|
307
|
+
return hashlib.sha256(
|
|
308
|
+
_AUDIT_PRIORITY_DOMAIN
|
|
309
|
+
+ bytes.fromhex(self.audit_seed_sha256)
|
|
310
|
+
+ bytes.fromhex(request_sha256)
|
|
311
|
+
+ bytes.fromhex(phenotype_identity_sha256)
|
|
312
|
+
).hexdigest()
|
|
313
|
+
|
|
314
|
+
def _audit_subset_priority(
|
|
315
|
+
self,
|
|
316
|
+
*,
|
|
317
|
+
request_sha256: str,
|
|
318
|
+
values: tuple[_CommitteeAction, ...],
|
|
319
|
+
) -> str:
|
|
320
|
+
return hashlib.sha256(
|
|
321
|
+
_AUDIT_SUBSET_PRIORITY_DOMAIN
|
|
322
|
+
+ bytes.fromhex(self.audit_seed_sha256)
|
|
323
|
+
+ bytes.fromhex(request_sha256)
|
|
324
|
+
+ b"".join(
|
|
325
|
+
bytes.fromhex(
|
|
326
|
+
value.action.phenotype_identity_sha256
|
|
327
|
+
)
|
|
328
|
+
for value in sorted(
|
|
329
|
+
values,
|
|
330
|
+
key=lambda item: (
|
|
331
|
+
item.action.phenotype_identity_sha256,
|
|
332
|
+
item.action.action_sha256,
|
|
333
|
+
),
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
).hexdigest()
|
|
337
|
+
|
|
338
|
+
async def require(
|
|
339
|
+
self,
|
|
340
|
+
request: ResidualPortfolioDecisionRequest,
|
|
341
|
+
proposals: tuple[MaterializedActionProposalBatch, ...],
|
|
342
|
+
) -> MaterializedActionAllocationRequirement:
|
|
343
|
+
self.__post_init__()
|
|
344
|
+
if type(request) is not ResidualPortfolioDecisionRequest:
|
|
345
|
+
raise TypeError("request must be exact")
|
|
346
|
+
request.__post_init__()
|
|
347
|
+
if type(proposals) is not tuple or not proposals:
|
|
348
|
+
raise ValueError("proposals must be a non-empty exact tuple")
|
|
349
|
+
for proposal in proposals:
|
|
350
|
+
if type(proposal) is not MaterializedActionProposalBatch:
|
|
351
|
+
raise TypeError("proposals must contain exact batches")
|
|
352
|
+
proposal.__post_init__()
|
|
353
|
+
proposal.require_request(request)
|
|
354
|
+
if self.protected_slots + self.audit_slots > request.evaluation_slots:
|
|
355
|
+
raise ValueError(
|
|
356
|
+
"protected and audit slots exceed the evaluation budget"
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
requirements = await asyncio.gather(
|
|
360
|
+
*(
|
|
361
|
+
binding.policy.require(request, proposals)
|
|
362
|
+
for binding in self.arm_bindings
|
|
363
|
+
)
|
|
364
|
+
)
|
|
365
|
+
market = self._action_market(proposals)
|
|
366
|
+
proposal_sha256s = tuple(
|
|
367
|
+
sorted(value.proposal_sha256 for value in proposals)
|
|
368
|
+
)
|
|
369
|
+
requirement_by_arm: dict[
|
|
370
|
+
str,
|
|
371
|
+
MaterializedActionAllocationRequirement,
|
|
372
|
+
] = {}
|
|
373
|
+
for binding, requirement in zip(
|
|
374
|
+
self.arm_bindings,
|
|
375
|
+
requirements,
|
|
376
|
+
strict=True,
|
|
377
|
+
):
|
|
378
|
+
if type(requirement) is not MaterializedActionAllocationRequirement:
|
|
379
|
+
raise TypeError("committee arm returned a foreign requirement")
|
|
380
|
+
requirement.__post_init__()
|
|
381
|
+
if (
|
|
382
|
+
requirement.policy_id,
|
|
383
|
+
requirement.policy_version,
|
|
384
|
+
requirement.policy_definition_sha256,
|
|
385
|
+
) != (
|
|
386
|
+
binding.policy.policy_id,
|
|
387
|
+
binding.policy.policy_version,
|
|
388
|
+
binding.policy.definition_sha256,
|
|
389
|
+
):
|
|
390
|
+
raise ValueError(
|
|
391
|
+
"committee arm requirement changed its policy identity"
|
|
392
|
+
)
|
|
393
|
+
if (
|
|
394
|
+
requirement.residual_request_sha256
|
|
395
|
+
!= request.request_sha256
|
|
396
|
+
or requirement.proposal_sha256s != proposal_sha256s
|
|
397
|
+
):
|
|
398
|
+
raise ValueError("committee arm requirement changed its cutoff")
|
|
399
|
+
if not set(requirement.required_action_sha256s) <= set(market):
|
|
400
|
+
raise ValueError("committee arm selected outside the market")
|
|
401
|
+
if not requirement.required_action_sha256s:
|
|
402
|
+
raise ValueError("committee arm returned an empty ballot")
|
|
403
|
+
requirement_by_arm[binding.arm_id] = requirement
|
|
404
|
+
|
|
405
|
+
phenotype_ballot_by_arm = {
|
|
406
|
+
binding.arm_id: frozenset(
|
|
407
|
+
market[action_id].phenotype_identity_sha256
|
|
408
|
+
for action_id in requirement_by_arm[
|
|
409
|
+
binding.arm_id
|
|
410
|
+
].required_action_sha256s
|
|
411
|
+
)
|
|
412
|
+
for binding in self.arm_bindings
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
def ballot_similarity(left_arm: str, right_arm: str) -> float:
|
|
416
|
+
left = phenotype_ballot_by_arm[left_arm]
|
|
417
|
+
right = phenotype_ballot_by_arm[right_arm]
|
|
418
|
+
union = left | right
|
|
419
|
+
if not union:
|
|
420
|
+
raise RuntimeError("committee arm has an empty phenotype ballot")
|
|
421
|
+
return len(left & right) / len(union)
|
|
422
|
+
|
|
423
|
+
similarity_by_arm = {
|
|
424
|
+
binding.arm_id: {
|
|
425
|
+
other.arm_id: ballot_similarity(
|
|
426
|
+
binding.arm_id,
|
|
427
|
+
other.arm_id,
|
|
428
|
+
)
|
|
429
|
+
for other in self.arm_bindings
|
|
430
|
+
}
|
|
431
|
+
for binding in self.arm_bindings
|
|
432
|
+
}
|
|
433
|
+
redundancy_by_arm = {
|
|
434
|
+
binding.arm_id: math.fsum(
|
|
435
|
+
similarity_by_arm[binding.arm_id].values()
|
|
436
|
+
)
|
|
437
|
+
for binding in self.arm_bindings
|
|
438
|
+
}
|
|
439
|
+
effective_weight_by_arm = {
|
|
440
|
+
binding.arm_id: (
|
|
441
|
+
binding.weight / redundancy_by_arm[binding.arm_id]
|
|
442
|
+
)
|
|
443
|
+
for binding in self.arm_bindings
|
|
444
|
+
}
|
|
445
|
+
effective_vote_by_arm = {
|
|
446
|
+
binding.arm_id: 1.0 / redundancy_by_arm[binding.arm_id]
|
|
447
|
+
for binding in self.arm_bindings
|
|
448
|
+
}
|
|
449
|
+
total_weight = math.fsum(effective_weight_by_arm.values())
|
|
450
|
+
normalized_weight_by_arm = {
|
|
451
|
+
arm_id: weight / total_weight
|
|
452
|
+
for arm_id, weight in effective_weight_by_arm.items()
|
|
453
|
+
}
|
|
454
|
+
actions: list[_CommitteeAction] = []
|
|
455
|
+
for action_id, action in sorted(market.items()):
|
|
456
|
+
memberships = tuple(
|
|
457
|
+
binding.arm_id
|
|
458
|
+
for binding in self.arm_bindings
|
|
459
|
+
if action_id
|
|
460
|
+
in requirement_by_arm[
|
|
461
|
+
binding.arm_id
|
|
462
|
+
].required_action_sha256s
|
|
463
|
+
)
|
|
464
|
+
if not memberships:
|
|
465
|
+
continue
|
|
466
|
+
weighted_support = math.fsum(
|
|
467
|
+
effective_weight_by_arm[arm_id]
|
|
468
|
+
for arm_id in memberships
|
|
469
|
+
)
|
|
470
|
+
effective_support = math.fsum(
|
|
471
|
+
effective_vote_by_arm[arm_id]
|
|
472
|
+
for arm_id in memberships
|
|
473
|
+
)
|
|
474
|
+
actions.append(
|
|
475
|
+
_CommitteeAction(
|
|
476
|
+
action=action,
|
|
477
|
+
arm_ids=memberships,
|
|
478
|
+
normalized_weighted_support=(
|
|
479
|
+
weighted_support / total_weight
|
|
480
|
+
),
|
|
481
|
+
effective_support=effective_support,
|
|
482
|
+
support_count=len(memberships),
|
|
483
|
+
protected_member=(
|
|
484
|
+
self.protected_arm_id in memberships
|
|
485
|
+
),
|
|
486
|
+
)
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
representatives = self._phenotype_representatives(
|
|
490
|
+
actions,
|
|
491
|
+
normalized_weight_by_arm=normalized_weight_by_arm,
|
|
492
|
+
effective_vote_by_arm=effective_vote_by_arm,
|
|
493
|
+
)
|
|
494
|
+
if len(representatives) < request.evaluation_slots:
|
|
495
|
+
raise ValueError(
|
|
496
|
+
"committee ballot union has too few unique phenotypes"
|
|
497
|
+
)
|
|
498
|
+
selected: list[_CommitteeAction] = []
|
|
499
|
+
selected_phenotypes: set[str] = set()
|
|
500
|
+
selection_kind: dict[str, str] = {}
|
|
501
|
+
|
|
502
|
+
def append(value: _CommitteeAction, kind: str) -> None:
|
|
503
|
+
phenotype = value.action.phenotype_identity_sha256
|
|
504
|
+
if phenotype in selected_phenotypes:
|
|
505
|
+
raise RuntimeError("committee selected one phenotype twice")
|
|
506
|
+
selected.append(value)
|
|
507
|
+
selected_phenotypes.add(phenotype)
|
|
508
|
+
selection_kind[value.action.action_sha256] = kind
|
|
509
|
+
|
|
510
|
+
protected = sorted(
|
|
511
|
+
(
|
|
512
|
+
value
|
|
513
|
+
for value in representatives
|
|
514
|
+
if value.protected_member
|
|
515
|
+
),
|
|
516
|
+
key=lambda value: value.consensus_key(),
|
|
517
|
+
)
|
|
518
|
+
if len(protected) < self.protected_slots:
|
|
519
|
+
raise ValueError("protected ballot cannot satisfy its floor")
|
|
520
|
+
for value in protected[: self.protected_slots]:
|
|
521
|
+
append(value, "protected_floor")
|
|
522
|
+
|
|
523
|
+
for value in sorted(
|
|
524
|
+
representatives,
|
|
525
|
+
key=lambda item: item.consensus_key(),
|
|
526
|
+
):
|
|
527
|
+
if len(selected) == request.evaluation_slots:
|
|
528
|
+
break
|
|
529
|
+
if (
|
|
530
|
+
value.action.phenotype_identity_sha256
|
|
531
|
+
in selected_phenotypes
|
|
532
|
+
):
|
|
533
|
+
continue
|
|
534
|
+
append(value, "weighted_consensus")
|
|
535
|
+
if len(selected) != request.evaluation_slots:
|
|
536
|
+
raise RuntimeError(
|
|
537
|
+
"committee failed to construct its deterministic baseline"
|
|
538
|
+
)
|
|
539
|
+
feasibility_replacements: list[dict[str, object]] = []
|
|
540
|
+
|
|
541
|
+
def slate_permitted(values: list[_CommitteeAction]) -> bool:
|
|
542
|
+
return (
|
|
543
|
+
self.slate_feasibility is None
|
|
544
|
+
or self.slate_feasibility.permits(
|
|
545
|
+
tuple(value.action for value in values)
|
|
546
|
+
)
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
if not slate_permitted(selected):
|
|
550
|
+
repairable = tuple(
|
|
551
|
+
value
|
|
552
|
+
for value in selected
|
|
553
|
+
if selection_kind[value.action.action_sha256]
|
|
554
|
+
!= "protected_floor"
|
|
555
|
+
)
|
|
556
|
+
repair_candidates = tuple(
|
|
557
|
+
sorted(
|
|
558
|
+
(
|
|
559
|
+
value
|
|
560
|
+
for value in representatives
|
|
561
|
+
if value.action.phenotype_identity_sha256
|
|
562
|
+
not in selected_phenotypes
|
|
563
|
+
),
|
|
564
|
+
key=lambda value: value.consensus_key(),
|
|
565
|
+
)
|
|
566
|
+
)
|
|
567
|
+
repaired: tuple[
|
|
568
|
+
tuple[_CommitteeAction, ...],
|
|
569
|
+
tuple[_CommitteeAction, ...],
|
|
570
|
+
list[_CommitteeAction],
|
|
571
|
+
] | None = None
|
|
572
|
+
repair_trials = 0
|
|
573
|
+
for swap_count in range(
|
|
574
|
+
1,
|
|
575
|
+
min(len(repairable), len(repair_candidates)) + 1,
|
|
576
|
+
):
|
|
577
|
+
for removed in combinations(repairable, swap_count):
|
|
578
|
+
removed_ids = {
|
|
579
|
+
value.action.action_sha256 for value in removed
|
|
580
|
+
}
|
|
581
|
+
fixed = [
|
|
582
|
+
value
|
|
583
|
+
for value in selected
|
|
584
|
+
if value.action.action_sha256 not in removed_ids
|
|
585
|
+
]
|
|
586
|
+
fixed_phenotypes = {
|
|
587
|
+
value.action.phenotype_identity_sha256
|
|
588
|
+
for value in fixed
|
|
589
|
+
}
|
|
590
|
+
eligible_candidates = tuple(
|
|
591
|
+
value
|
|
592
|
+
for value in repair_candidates
|
|
593
|
+
if value.action.phenotype_identity_sha256
|
|
594
|
+
not in fixed_phenotypes
|
|
595
|
+
)
|
|
596
|
+
for inserted in combinations(
|
|
597
|
+
eligible_candidates,
|
|
598
|
+
swap_count,
|
|
599
|
+
):
|
|
600
|
+
repair_trials += 1
|
|
601
|
+
if (
|
|
602
|
+
repair_trials
|
|
603
|
+
> _MAX_FEASIBILITY_REPAIR_TRIALS
|
|
604
|
+
):
|
|
605
|
+
raise ValueError(
|
|
606
|
+
"committee feasibility repair exceeded "
|
|
607
|
+
"its declared trial bound"
|
|
608
|
+
)
|
|
609
|
+
trial = [*fixed, *inserted]
|
|
610
|
+
if len(
|
|
611
|
+
{
|
|
612
|
+
value.action.phenotype_identity_sha256
|
|
613
|
+
for value in trial
|
|
614
|
+
}
|
|
615
|
+
) != request.evaluation_slots:
|
|
616
|
+
continue
|
|
617
|
+
if slate_permitted(trial):
|
|
618
|
+
repaired = (removed, inserted, trial)
|
|
619
|
+
break
|
|
620
|
+
if repaired is not None:
|
|
621
|
+
break
|
|
622
|
+
if repaired is not None:
|
|
623
|
+
break
|
|
624
|
+
if repaired is None:
|
|
625
|
+
raise ValueError(
|
|
626
|
+
"committee cannot satisfy final slate feasibility "
|
|
627
|
+
"without displacing its protected floor"
|
|
628
|
+
)
|
|
629
|
+
removed, inserted, selected = repaired
|
|
630
|
+
for value in removed:
|
|
631
|
+
selection_kind.pop(value.action.action_sha256)
|
|
632
|
+
for value in inserted:
|
|
633
|
+
selection_kind[
|
|
634
|
+
value.action.action_sha256
|
|
635
|
+
] = "feasibility_repair"
|
|
636
|
+
selected_phenotypes = {
|
|
637
|
+
value.action.phenotype_identity_sha256
|
|
638
|
+
for value in selected
|
|
639
|
+
}
|
|
640
|
+
feasibility_replacements.append(
|
|
641
|
+
{
|
|
642
|
+
"removed_action_sha256s": sorted(
|
|
643
|
+
value.action.action_sha256
|
|
644
|
+
for value in removed
|
|
645
|
+
),
|
|
646
|
+
"inserted_action_sha256s": sorted(
|
|
647
|
+
value.action.action_sha256
|
|
648
|
+
for value in inserted
|
|
649
|
+
),
|
|
650
|
+
"swap_count": len(removed),
|
|
651
|
+
"trials": repair_trials,
|
|
652
|
+
}
|
|
653
|
+
)
|
|
654
|
+
baseline_action_sha256s = tuple(
|
|
655
|
+
sorted(value.action.action_sha256 for value in selected)
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
audit_pool = sorted(
|
|
659
|
+
(
|
|
660
|
+
value
|
|
661
|
+
for value in representatives
|
|
662
|
+
if (
|
|
663
|
+
value.action.phenotype_identity_sha256
|
|
664
|
+
not in selected_phenotypes
|
|
665
|
+
and value.support_count < len(self.arm_bindings)
|
|
666
|
+
)
|
|
667
|
+
),
|
|
668
|
+
key=lambda value: value.action.action_sha256,
|
|
669
|
+
)
|
|
670
|
+
replaceable = [
|
|
671
|
+
value
|
|
672
|
+
for value in selected
|
|
673
|
+
if selection_kind[value.action.action_sha256]
|
|
674
|
+
!= "protected_floor"
|
|
675
|
+
]
|
|
676
|
+
effective_audit_slots = min(
|
|
677
|
+
self.audit_slots,
|
|
678
|
+
len(audit_pool),
|
|
679
|
+
len(replaceable),
|
|
680
|
+
)
|
|
681
|
+
audit_priority = {
|
|
682
|
+
value.action.action_sha256: self._audit_priority(
|
|
683
|
+
request_sha256=request.request_sha256,
|
|
684
|
+
phenotype_identity_sha256=(
|
|
685
|
+
value.action.phenotype_identity_sha256
|
|
686
|
+
),
|
|
687
|
+
)
|
|
688
|
+
for value in audit_pool
|
|
689
|
+
}
|
|
690
|
+
sampled_audit: tuple[_CommitteeAction, ...] = ()
|
|
691
|
+
replaced_baseline: list[_CommitteeAction] = []
|
|
692
|
+
valid_audit_subset_count = 1
|
|
693
|
+
audit_marginal_by_action = {
|
|
694
|
+
value.action.action_sha256: 0.0 for value in audit_pool
|
|
695
|
+
}
|
|
696
|
+
sampled_subset_priority = self._audit_subset_priority(
|
|
697
|
+
request_sha256=request.request_sha256,
|
|
698
|
+
values=(),
|
|
699
|
+
)
|
|
700
|
+
while True:
|
|
701
|
+
replaced_baseline = sorted(
|
|
702
|
+
replaceable,
|
|
703
|
+
key=lambda item: item.consensus_key(),
|
|
704
|
+
reverse=True,
|
|
705
|
+
)[:effective_audit_slots]
|
|
706
|
+
replaced_ids_for_trial = {
|
|
707
|
+
value.action.action_sha256
|
|
708
|
+
for value in replaced_baseline
|
|
709
|
+
}
|
|
710
|
+
fixed_for_trial = [
|
|
711
|
+
value
|
|
712
|
+
for value in selected
|
|
713
|
+
if value.action.action_sha256
|
|
714
|
+
not in replaced_ids_for_trial
|
|
715
|
+
]
|
|
716
|
+
if self.slate_feasibility is None:
|
|
717
|
+
valid_audit_subset_count = math.comb(
|
|
718
|
+
len(audit_pool),
|
|
719
|
+
effective_audit_slots,
|
|
720
|
+
)
|
|
721
|
+
sampled_audit = tuple(
|
|
722
|
+
sorted(
|
|
723
|
+
audit_pool,
|
|
724
|
+
key=lambda item: (
|
|
725
|
+
audit_priority[
|
|
726
|
+
item.action.action_sha256
|
|
727
|
+
],
|
|
728
|
+
item.action.action_sha256,
|
|
729
|
+
),
|
|
730
|
+
)[:effective_audit_slots]
|
|
731
|
+
)
|
|
732
|
+
marginal = (
|
|
733
|
+
0.0
|
|
734
|
+
if not audit_pool
|
|
735
|
+
else effective_audit_slots / len(audit_pool)
|
|
736
|
+
)
|
|
737
|
+
audit_marginal_by_action = {
|
|
738
|
+
value.action.action_sha256: marginal
|
|
739
|
+
for value in audit_pool
|
|
740
|
+
}
|
|
741
|
+
sampled_subset_priority = (
|
|
742
|
+
self._audit_subset_priority(
|
|
743
|
+
request_sha256=request.request_sha256,
|
|
744
|
+
values=sampled_audit,
|
|
745
|
+
)
|
|
746
|
+
)
|
|
747
|
+
break
|
|
748
|
+
|
|
749
|
+
subset_count = math.comb(
|
|
750
|
+
len(audit_pool),
|
|
751
|
+
effective_audit_slots,
|
|
752
|
+
)
|
|
753
|
+
if subset_count > _MAX_FEASIBILITY_REPAIR_TRIALS:
|
|
754
|
+
raise ValueError(
|
|
755
|
+
"feasibility-constrained audit subset count exceeds "
|
|
756
|
+
"its declared exact-enumeration bound"
|
|
757
|
+
)
|
|
758
|
+
valid_subsets = tuple(
|
|
759
|
+
subset
|
|
760
|
+
for subset in combinations(
|
|
761
|
+
audit_pool,
|
|
762
|
+
effective_audit_slots,
|
|
763
|
+
)
|
|
764
|
+
if slate_permitted(
|
|
765
|
+
[*fixed_for_trial, *subset]
|
|
766
|
+
)
|
|
767
|
+
)
|
|
768
|
+
if valid_subsets:
|
|
769
|
+
valid_audit_subset_count = len(valid_subsets)
|
|
770
|
+
sampled_audit = min(
|
|
771
|
+
valid_subsets,
|
|
772
|
+
key=lambda subset: (
|
|
773
|
+
self._audit_subset_priority(
|
|
774
|
+
request_sha256=request.request_sha256,
|
|
775
|
+
values=subset,
|
|
776
|
+
),
|
|
777
|
+
tuple(
|
|
778
|
+
value.action.action_sha256
|
|
779
|
+
for value in subset
|
|
780
|
+
),
|
|
781
|
+
),
|
|
782
|
+
)
|
|
783
|
+
sampled_subset_priority = (
|
|
784
|
+
self._audit_subset_priority(
|
|
785
|
+
request_sha256=request.request_sha256,
|
|
786
|
+
values=sampled_audit,
|
|
787
|
+
)
|
|
788
|
+
)
|
|
789
|
+
audit_marginal_by_action = {
|
|
790
|
+
value.action.action_sha256: (
|
|
791
|
+
sum(
|
|
792
|
+
value in subset
|
|
793
|
+
for subset in valid_subsets
|
|
794
|
+
)
|
|
795
|
+
/ valid_audit_subset_count
|
|
796
|
+
)
|
|
797
|
+
for value in audit_pool
|
|
798
|
+
}
|
|
799
|
+
break
|
|
800
|
+
if effective_audit_slots == 0:
|
|
801
|
+
raise RuntimeError(
|
|
802
|
+
"feasible deterministic baseline became infeasible"
|
|
803
|
+
)
|
|
804
|
+
effective_audit_slots -= 1
|
|
805
|
+
|
|
806
|
+
audit_probabilities = set(
|
|
807
|
+
audit_marginal_by_action.values()
|
|
808
|
+
)
|
|
809
|
+
common_audit_probability = (
|
|
810
|
+
next(iter(audit_probabilities))
|
|
811
|
+
if len(audit_probabilities) == 1
|
|
812
|
+
else None
|
|
813
|
+
)
|
|
814
|
+
replaced_ids = {
|
|
815
|
+
value.action.action_sha256 for value in replaced_baseline
|
|
816
|
+
}
|
|
817
|
+
selected = [
|
|
818
|
+
value
|
|
819
|
+
for value in selected
|
|
820
|
+
if value.action.action_sha256 not in replaced_ids
|
|
821
|
+
]
|
|
822
|
+
for value in replaced_baseline:
|
|
823
|
+
selected_phenotypes.remove(
|
|
824
|
+
value.action.phenotype_identity_sha256
|
|
825
|
+
)
|
|
826
|
+
selection_kind.pop(value.action.action_sha256)
|
|
827
|
+
for value in sampled_audit:
|
|
828
|
+
append(value, "randomized_disagreement_audit")
|
|
829
|
+
if len(selected) != request.evaluation_slots:
|
|
830
|
+
raise RuntimeError("committee failed to fill the exact-K slate")
|
|
831
|
+
if not slate_permitted(selected):
|
|
832
|
+
raise RuntimeError("committee emitted an infeasible final slate")
|
|
833
|
+
|
|
834
|
+
selected_ids = tuple(
|
|
835
|
+
sorted(value.action.action_sha256 for value in selected)
|
|
836
|
+
)
|
|
837
|
+
selected_order = {
|
|
838
|
+
value.action.action_sha256: ordinal
|
|
839
|
+
for ordinal, value in enumerate(selected, start=1)
|
|
840
|
+
}
|
|
841
|
+
evidence = freeze_json(
|
|
842
|
+
{
|
|
843
|
+
"schema_version": 1,
|
|
844
|
+
"candidate_outcomes_observed": False,
|
|
845
|
+
"workload_model_provider_branches": False,
|
|
846
|
+
"selection_trace": [
|
|
847
|
+
{
|
|
848
|
+
"ordinal": selected_order[
|
|
849
|
+
value.action.action_sha256
|
|
850
|
+
],
|
|
851
|
+
"action_sha256": value.action.action_sha256,
|
|
852
|
+
"allocation_kind": selection_kind[
|
|
853
|
+
value.action.action_sha256
|
|
854
|
+
],
|
|
855
|
+
"support_count": value.support_count,
|
|
856
|
+
"arm_ids": list(value.arm_ids),
|
|
857
|
+
"audit_marginal_inclusion_probability_hex": (
|
|
858
|
+
audit_marginal_by_action[
|
|
859
|
+
value.action.action_sha256
|
|
860
|
+
].hex()
|
|
861
|
+
if value in audit_pool
|
|
862
|
+
else (0.0).hex()
|
|
863
|
+
),
|
|
864
|
+
"candidate_outcomes_observed": False,
|
|
865
|
+
}
|
|
866
|
+
for value in sorted(
|
|
867
|
+
selected,
|
|
868
|
+
key=lambda item: selected_order[
|
|
869
|
+
item.action.action_sha256
|
|
870
|
+
],
|
|
871
|
+
)
|
|
872
|
+
],
|
|
873
|
+
"committee": {
|
|
874
|
+
"protected_arm_id": self.protected_arm_id,
|
|
875
|
+
"configured_protected_slots": self.protected_slots,
|
|
876
|
+
"configured_audit_slots": self.audit_slots,
|
|
877
|
+
"effective_audit_slots": effective_audit_slots,
|
|
878
|
+
"audit_pool_size": len(audit_pool),
|
|
879
|
+
"audit_marginal_inclusion_probability_hex": (
|
|
880
|
+
None
|
|
881
|
+
if common_audit_probability is None
|
|
882
|
+
else common_audit_probability.hex()
|
|
883
|
+
),
|
|
884
|
+
"valid_audit_subset_count": (
|
|
885
|
+
valid_audit_subset_count
|
|
886
|
+
),
|
|
887
|
+
"audit_seed_sha256": self.audit_seed_sha256,
|
|
888
|
+
"sampled_audit_subset_priority_sha256": (
|
|
889
|
+
sampled_subset_priority
|
|
890
|
+
),
|
|
891
|
+
"audit_randomization_distribution": (
|
|
892
|
+
"uniform_over_feasible_unselected_disagreement_"
|
|
893
|
+
"phenotype_subsets_with_fixed_baseline_swaps"
|
|
894
|
+
),
|
|
895
|
+
"deterministic_baseline_action_sha256s": list(
|
|
896
|
+
baseline_action_sha256s
|
|
897
|
+
),
|
|
898
|
+
"feasibility_replacements": (
|
|
899
|
+
feasibility_replacements
|
|
900
|
+
),
|
|
901
|
+
"slate_feasibility_definition_sha256": (
|
|
902
|
+
None
|
|
903
|
+
if self.slate_feasibility is None
|
|
904
|
+
else self.slate_feasibility.definition_sha256
|
|
905
|
+
),
|
|
906
|
+
"replaced_baseline_action_sha256s": sorted(replaced_ids),
|
|
907
|
+
"exact_action_set_propensity": (
|
|
908
|
+
1.0 / valid_audit_subset_count
|
|
909
|
+
).hex(),
|
|
910
|
+
},
|
|
911
|
+
"arms": [
|
|
912
|
+
{
|
|
913
|
+
**binding.identity_record(),
|
|
914
|
+
"phenotype_ballot_size": len(
|
|
915
|
+
phenotype_ballot_by_arm[binding.arm_id]
|
|
916
|
+
),
|
|
917
|
+
"behavioral_redundancy_hex": (
|
|
918
|
+
redundancy_by_arm[binding.arm_id].hex()
|
|
919
|
+
),
|
|
920
|
+
"effective_weight_hex": (
|
|
921
|
+
effective_weight_by_arm[binding.arm_id].hex()
|
|
922
|
+
),
|
|
923
|
+
"pairwise_jaccard_similarity_hex": {
|
|
924
|
+
other_arm_id: similarity.hex()
|
|
925
|
+
for other_arm_id, similarity in sorted(
|
|
926
|
+
similarity_by_arm[
|
|
927
|
+
binding.arm_id
|
|
928
|
+
].items()
|
|
929
|
+
)
|
|
930
|
+
},
|
|
931
|
+
"requirement_sha256": requirement_by_arm[
|
|
932
|
+
binding.arm_id
|
|
933
|
+
].requirement_sha256,
|
|
934
|
+
"required_action_sha256s": list(
|
|
935
|
+
requirement_by_arm[
|
|
936
|
+
binding.arm_id
|
|
937
|
+
].required_action_sha256s
|
|
938
|
+
),
|
|
939
|
+
}
|
|
940
|
+
for binding in self.arm_bindings
|
|
941
|
+
],
|
|
942
|
+
"ballot_union": [
|
|
943
|
+
{
|
|
944
|
+
"action_sha256": value.action.action_sha256,
|
|
945
|
+
"phenotype_identity_sha256": (
|
|
946
|
+
value.action.phenotype_identity_sha256
|
|
947
|
+
),
|
|
948
|
+
"arm_ids": list(value.arm_ids),
|
|
949
|
+
"normalized_weighted_support_hex": (
|
|
950
|
+
value.normalized_weighted_support.hex()
|
|
951
|
+
),
|
|
952
|
+
"effective_support_hex": (
|
|
953
|
+
value.effective_support.hex()
|
|
954
|
+
),
|
|
955
|
+
"support_count": value.support_count,
|
|
956
|
+
"protected_member": value.protected_member,
|
|
957
|
+
"audit_eligible": (
|
|
958
|
+
value in audit_pool
|
|
959
|
+
and audit_marginal_by_action[
|
|
960
|
+
value.action.action_sha256
|
|
961
|
+
]
|
|
962
|
+
> 0.0
|
|
963
|
+
),
|
|
964
|
+
"audit_priority_sha256": audit_priority.get(
|
|
965
|
+
value.action.action_sha256
|
|
966
|
+
),
|
|
967
|
+
"audit_marginal_inclusion_probability_hex": (
|
|
968
|
+
audit_marginal_by_action[
|
|
969
|
+
value.action.action_sha256
|
|
970
|
+
].hex()
|
|
971
|
+
if value in audit_pool
|
|
972
|
+
else (0.0).hex()
|
|
973
|
+
),
|
|
974
|
+
"final_marginal_inclusion_probability_hex": (
|
|
975
|
+
audit_marginal_by_action[
|
|
976
|
+
value.action.action_sha256
|
|
977
|
+
].hex()
|
|
978
|
+
if value in audit_pool
|
|
979
|
+
else (
|
|
980
|
+
0.0
|
|
981
|
+
if value.action.action_sha256 in replaced_ids
|
|
982
|
+
else (
|
|
983
|
+
1.0
|
|
984
|
+
if value.action.action_sha256
|
|
985
|
+
in baseline_action_sha256s
|
|
986
|
+
else 0.0
|
|
987
|
+
)
|
|
988
|
+
).hex()
|
|
989
|
+
),
|
|
990
|
+
"selected": (
|
|
991
|
+
value.action.action_sha256 in selected_order
|
|
992
|
+
),
|
|
993
|
+
"selected_ordinal": selected_order.get(
|
|
994
|
+
value.action.action_sha256
|
|
995
|
+
),
|
|
996
|
+
"selection_kind": selection_kind.get(
|
|
997
|
+
value.action.action_sha256
|
|
998
|
+
),
|
|
999
|
+
}
|
|
1000
|
+
for value in sorted(
|
|
1001
|
+
representatives,
|
|
1002
|
+
key=lambda item: item.action.action_sha256,
|
|
1003
|
+
)
|
|
1004
|
+
],
|
|
1005
|
+
"exact_k": request.evaluation_slots,
|
|
1006
|
+
"unique_phenotype_selection": True,
|
|
1007
|
+
"unselected_candidate_outcomes_observed": False,
|
|
1008
|
+
}
|
|
1009
|
+
)
|
|
1010
|
+
return MaterializedActionAllocationRequirement(
|
|
1011
|
+
policy_id=self.policy_id,
|
|
1012
|
+
policy_version=self.policy_version,
|
|
1013
|
+
policy_definition_sha256=self.definition_sha256,
|
|
1014
|
+
residual_request_sha256=request.request_sha256,
|
|
1015
|
+
proposal_sha256s=proposal_sha256s,
|
|
1016
|
+
required_action_sha256s=selected_ids,
|
|
1017
|
+
candidate_outcomes_observed=False,
|
|
1018
|
+
evidence=evidence,
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
__all__ = [
|
|
1023
|
+
"ActionCommitteeArmBinding",
|
|
1024
|
+
"PROTECTED_ACTION_COMMITTEE_POLICY_ID",
|
|
1025
|
+
"PROTECTED_ACTION_COMMITTEE_POLICY_VERSION",
|
|
1026
|
+
"ProtectedActionCommitteePolicy",
|
|
1027
|
+
]
|