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,719 @@
|
|
|
1
|
+
"""Authenticated elite/explorer parent selection over generic Pareto archives.
|
|
2
|
+
|
|
3
|
+
The policy exposes two stable lanes to generation and memory planners:
|
|
4
|
+
|
|
5
|
+
``elite``
|
|
6
|
+
Rotates over exact members of the archive's current Pareto front.
|
|
7
|
+
|
|
8
|
+
``explorer``
|
|
9
|
+
Rotates over the best available dominated nondomination rank. When no
|
|
10
|
+
dominated history exists it uses a distinct current-front member. An
|
|
11
|
+
exact singleton front is the only case in which it reuses the elite, and
|
|
12
|
+
that exception is explicit in the receipt.
|
|
13
|
+
|
|
14
|
+
Selection depends only on the task identity and the authenticated archive
|
|
15
|
+
state. It contains no workload semantics and makes no causal-propensity
|
|
16
|
+
claim. Complete front and ranking evidence is carried in every receipt so a
|
|
17
|
+
consumer can reject stale, foreign, or tampered parent choices.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import hashlib
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from enum import Enum
|
|
25
|
+
from typing import Protocol
|
|
26
|
+
|
|
27
|
+
from agent_evolve.application.agentic_evolution import EvolutionCandidate
|
|
28
|
+
from agent_evolve.application.budgeted_optimizer import OptimizerState
|
|
29
|
+
from agent_evolve.application.pareto_archive import ParetoCandidateRef
|
|
30
|
+
from agent_evolve.domain.patch import require_sha256
|
|
31
|
+
from agent_evolve.policies.selection.archive_elite import (
|
|
32
|
+
ArchiveReservoirRankedCandidate,
|
|
33
|
+
_canonical_json,
|
|
34
|
+
_candidate_reference,
|
|
35
|
+
_eligible_front_sha256,
|
|
36
|
+
_eligible_ranking_sha256,
|
|
37
|
+
_ranked_eligible_history,
|
|
38
|
+
_reference_key,
|
|
39
|
+
_reference_record,
|
|
40
|
+
_reservoir_member_key,
|
|
41
|
+
_validated_front,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
POLICY_ID = "task_keyed_archive_elite_explorer_parent"
|
|
46
|
+
POLICY_VERSION = 1
|
|
47
|
+
SCHEMA_VERSION = 1
|
|
48
|
+
ROTATION_LAW_ID = "task_archive_lane_pool_sha256_cyclic_v1"
|
|
49
|
+
_MAX_ROTATION_INDEX = (1 << 63) - 1
|
|
50
|
+
_DEFINITION_DOMAIN = b"agent-evolve:archive-elite-explorer-parent:def:v1\x00"
|
|
51
|
+
_POOL_DOMAIN = b"agent-evolve:archive-elite-explorer-parent:pool:v1\x00"
|
|
52
|
+
_ROTATION_DOMAIN = b"agent-evolve:archive-elite-explorer-parent:rotation:v1\x00"
|
|
53
|
+
_RECEIPT_DOMAIN = b"agent-evolve:archive-elite-explorer-parent:receipt:v1\x00"
|
|
54
|
+
_DEFINITION = {
|
|
55
|
+
"archive_authority": "exact ParetoArchiveSnapshot and snapshot hash",
|
|
56
|
+
"eligible_history": (
|
|
57
|
+
"complete archive-authenticated, gate-passing unique-configuration history"
|
|
58
|
+
),
|
|
59
|
+
"elite_lane": "exact current Pareto-front member",
|
|
60
|
+
"explorer_lane": (
|
|
61
|
+
"best available nondomination rank greater than one; otherwise distinct "
|
|
62
|
+
"current-front fallback; singleton reuse only for a singleton front"
|
|
63
|
+
),
|
|
64
|
+
"lane_ids": ["elite", "explorer"],
|
|
65
|
+
"rotation_law_id": ROTATION_LAW_ID,
|
|
66
|
+
"benchmark_branching": False,
|
|
67
|
+
"causal_propensity_claim": False,
|
|
68
|
+
"stale_or_foreign_candidate_admission": False,
|
|
69
|
+
}
|
|
70
|
+
POLICY_DEFINITION_SHA256 = hashlib.sha256(
|
|
71
|
+
_DEFINITION_DOMAIN + _canonical_json(_DEFINITION)
|
|
72
|
+
).hexdigest()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class EliteExplorerLaneId(str, Enum):
|
|
76
|
+
"""Stable lane identifiers for variation and balanced-memory plans."""
|
|
77
|
+
|
|
78
|
+
ELITE = "elite"
|
|
79
|
+
EXPLORER = "explorer"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class EliteExplorerLaneSource(str, Enum):
|
|
83
|
+
"""Authenticated source from which a lane parent was selected."""
|
|
84
|
+
|
|
85
|
+
CURRENT_PARETO_FRONT = "current_pareto_front"
|
|
86
|
+
BEST_DOMINATED_RANK = "best_dominated_rank"
|
|
87
|
+
DISTINCT_FRONT_FALLBACK = "distinct_front_fallback"
|
|
88
|
+
SINGLETON_REUSE_FALLBACK = "singleton_reuse_fallback"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class EliteExplorerFallbackReason(str, Enum):
|
|
92
|
+
"""Why the explorer lane departed from its preferred dominated source."""
|
|
93
|
+
|
|
94
|
+
NONE = "none"
|
|
95
|
+
NO_DOMINATED_HISTORY = "no_dominated_history"
|
|
96
|
+
SINGLETON_FRONT = "singleton_front"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _selection_pool_sha256(
|
|
100
|
+
lane_id: EliteExplorerLaneId,
|
|
101
|
+
pool: tuple[ParetoCandidateRef, ...],
|
|
102
|
+
) -> str:
|
|
103
|
+
if type(lane_id) is not EliteExplorerLaneId:
|
|
104
|
+
raise TypeError("lane_id must be an EliteExplorerLaneId")
|
|
105
|
+
if type(pool) is not tuple or not pool:
|
|
106
|
+
raise ValueError("selection_pool must be a non-empty exact tuple")
|
|
107
|
+
for reference in pool:
|
|
108
|
+
_reference_record(reference)
|
|
109
|
+
return hashlib.sha256(
|
|
110
|
+
_POOL_DOMAIN
|
|
111
|
+
+ lane_id.value.encode("ascii")
|
|
112
|
+
+ b"\x00"
|
|
113
|
+
+ _canonical_json([_reference_record(reference) for reference in pool])
|
|
114
|
+
).hexdigest()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _rotation_anchor(
|
|
118
|
+
*,
|
|
119
|
+
task_sha256: str,
|
|
120
|
+
archive_snapshot_hash: str,
|
|
121
|
+
eligible_front_sha256: str,
|
|
122
|
+
eligible_ranking_sha256: str,
|
|
123
|
+
lane_id: EliteExplorerLaneId,
|
|
124
|
+
source: EliteExplorerLaneSource,
|
|
125
|
+
nondomination_rank: int,
|
|
126
|
+
fallback_reason: EliteExplorerFallbackReason,
|
|
127
|
+
selection_pool_sha256: str,
|
|
128
|
+
cardinality: int,
|
|
129
|
+
) -> int:
|
|
130
|
+
require_sha256(task_sha256, "task_sha256")
|
|
131
|
+
require_sha256(archive_snapshot_hash, "archive_snapshot_hash")
|
|
132
|
+
require_sha256(eligible_front_sha256, "eligible_front_sha256")
|
|
133
|
+
require_sha256(eligible_ranking_sha256, "eligible_ranking_sha256")
|
|
134
|
+
require_sha256(selection_pool_sha256, "selection_pool_sha256")
|
|
135
|
+
if type(lane_id) is not EliteExplorerLaneId:
|
|
136
|
+
raise TypeError("lane_id must be an EliteExplorerLaneId")
|
|
137
|
+
if type(source) is not EliteExplorerLaneSource:
|
|
138
|
+
raise TypeError("source must be an EliteExplorerLaneSource")
|
|
139
|
+
if type(fallback_reason) is not EliteExplorerFallbackReason:
|
|
140
|
+
raise TypeError("fallback_reason must be an EliteExplorerFallbackReason")
|
|
141
|
+
if type(nondomination_rank) is not int or nondomination_rank <= 0:
|
|
142
|
+
raise ValueError("nondomination_rank must be a positive exact integer")
|
|
143
|
+
if type(cardinality) is not int or cardinality <= 0:
|
|
144
|
+
raise ValueError("selection-pool cardinality must be positive")
|
|
145
|
+
digest = hashlib.sha256(
|
|
146
|
+
_ROTATION_DOMAIN
|
|
147
|
+
+ bytes.fromhex(task_sha256)
|
|
148
|
+
+ bytes.fromhex(archive_snapshot_hash)
|
|
149
|
+
+ bytes.fromhex(eligible_front_sha256)
|
|
150
|
+
+ bytes.fromhex(eligible_ranking_sha256)
|
|
151
|
+
+ lane_id.value.encode("ascii")
|
|
152
|
+
+ b"\x00"
|
|
153
|
+
+ source.value.encode("ascii")
|
|
154
|
+
+ b"\x00"
|
|
155
|
+
+ nondomination_rank.to_bytes(8, "big", signed=False)
|
|
156
|
+
+ fallback_reason.value.encode("ascii")
|
|
157
|
+
+ b"\x00"
|
|
158
|
+
+ bytes.fromhex(selection_pool_sha256)
|
|
159
|
+
).digest()
|
|
160
|
+
return int.from_bytes(digest, "big", signed=False) % cardinality
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@dataclass(frozen=True, slots=True)
|
|
164
|
+
class EliteExplorerLaneReceipt:
|
|
165
|
+
"""One stable lane's source, rotation, and selected parent identity."""
|
|
166
|
+
|
|
167
|
+
lane_id: EliteExplorerLaneId
|
|
168
|
+
source: EliteExplorerLaneSource
|
|
169
|
+
nondomination_rank: int
|
|
170
|
+
fallback_reason: EliteExplorerFallbackReason
|
|
171
|
+
selection_pool: tuple[ParetoCandidateRef, ...]
|
|
172
|
+
rotation_anchor: int
|
|
173
|
+
selected_ordinal: int
|
|
174
|
+
selected_parent: ParetoCandidateRef
|
|
175
|
+
selection_pool_sha256: str = field(init=False, default="")
|
|
176
|
+
|
|
177
|
+
def __post_init__(self) -> None:
|
|
178
|
+
if type(self.lane_id) is not EliteExplorerLaneId:
|
|
179
|
+
raise TypeError("lane_id must be an EliteExplorerLaneId")
|
|
180
|
+
if type(self.source) is not EliteExplorerLaneSource:
|
|
181
|
+
raise TypeError("source must be an EliteExplorerLaneSource")
|
|
182
|
+
if type(self.fallback_reason) is not EliteExplorerFallbackReason:
|
|
183
|
+
raise TypeError("fallback_reason must be an EliteExplorerFallbackReason")
|
|
184
|
+
if type(self.nondomination_rank) is not int or self.nondomination_rank <= 0:
|
|
185
|
+
raise ValueError("nondomination_rank must be a positive exact integer")
|
|
186
|
+
if type(self.selection_pool) is not tuple or not self.selection_pool:
|
|
187
|
+
raise ValueError("selection_pool must be a non-empty exact tuple")
|
|
188
|
+
for reference in self.selection_pool:
|
|
189
|
+
_reference_record(reference)
|
|
190
|
+
if len({value.candidate_id for value in self.selection_pool}) != len(
|
|
191
|
+
self.selection_pool
|
|
192
|
+
):
|
|
193
|
+
raise ValueError("selection_pool contains duplicate candidate IDs")
|
|
194
|
+
if len({value.configuration_hash for value in self.selection_pool}) != len(
|
|
195
|
+
self.selection_pool
|
|
196
|
+
):
|
|
197
|
+
raise ValueError("selection_pool contains duplicate configurations")
|
|
198
|
+
computed_pool_sha256 = _selection_pool_sha256(
|
|
199
|
+
self.lane_id,
|
|
200
|
+
self.selection_pool,
|
|
201
|
+
)
|
|
202
|
+
if self.selection_pool_sha256 not in ("", computed_pool_sha256):
|
|
203
|
+
raise ValueError("selection_pool_sha256 does not identify selection_pool")
|
|
204
|
+
object.__setattr__(self, "selection_pool_sha256", computed_pool_sha256)
|
|
205
|
+
if type(self.rotation_anchor) is not int or not (
|
|
206
|
+
0 <= self.rotation_anchor < len(self.selection_pool)
|
|
207
|
+
):
|
|
208
|
+
raise ValueError("rotation_anchor must lie within selection_pool")
|
|
209
|
+
if type(self.selected_ordinal) is not int or not (
|
|
210
|
+
0 <= self.selected_ordinal < len(self.selection_pool)
|
|
211
|
+
):
|
|
212
|
+
raise ValueError("selected_ordinal must lie within selection_pool")
|
|
213
|
+
_reference_record(self.selected_parent)
|
|
214
|
+
if self.selected_parent != self.selection_pool[self.selected_ordinal]:
|
|
215
|
+
raise ValueError("selected_parent does not match selected_ordinal")
|
|
216
|
+
|
|
217
|
+
def revalidate(self) -> None:
|
|
218
|
+
if type(self) is not EliteExplorerLaneReceipt:
|
|
219
|
+
raise TypeError("lane must be an exact EliteExplorerLaneReceipt")
|
|
220
|
+
EliteExplorerLaneReceipt.__post_init__(self)
|
|
221
|
+
|
|
222
|
+
def to_trace_record(self) -> dict[str, object]:
|
|
223
|
+
self.revalidate()
|
|
224
|
+
return {
|
|
225
|
+
"lane_id": self.lane_id.value,
|
|
226
|
+
"source": self.source.value,
|
|
227
|
+
"nondomination_rank": self.nondomination_rank,
|
|
228
|
+
"fallback_reason": self.fallback_reason.value,
|
|
229
|
+
"selection_pool": [
|
|
230
|
+
_reference_record(reference) for reference in self.selection_pool
|
|
231
|
+
],
|
|
232
|
+
"selection_pool_sha256": self.selection_pool_sha256,
|
|
233
|
+
"rotation_anchor": self.rotation_anchor,
|
|
234
|
+
"selected_ordinal": self.selected_ordinal,
|
|
235
|
+
"selected_parent": _reference_record(self.selected_parent),
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def _validate_complete_authority(
|
|
240
|
+
eligible_front: tuple[ParetoCandidateRef, ...],
|
|
241
|
+
eligible_ranking: tuple[ArchiveReservoirRankedCandidate, ...],
|
|
242
|
+
) -> None:
|
|
243
|
+
if type(eligible_front) is not tuple or not eligible_front:
|
|
244
|
+
raise ValueError("eligible_front must be a non-empty exact tuple")
|
|
245
|
+
for reference in eligible_front:
|
|
246
|
+
_reference_record(reference)
|
|
247
|
+
if eligible_front != tuple(sorted(eligible_front, key=_reference_key)):
|
|
248
|
+
raise ValueError("eligible_front must preserve canonical archive order")
|
|
249
|
+
if len({value.candidate_id for value in eligible_front}) != len(eligible_front):
|
|
250
|
+
raise ValueError("eligible_front contains duplicate candidate IDs")
|
|
251
|
+
if len({value.configuration_hash for value in eligible_front}) != len(
|
|
252
|
+
eligible_front
|
|
253
|
+
):
|
|
254
|
+
raise ValueError("eligible_front contains duplicate configurations")
|
|
255
|
+
|
|
256
|
+
if type(eligible_ranking) is not tuple or not eligible_ranking:
|
|
257
|
+
raise ValueError("eligible_ranking must be a non-empty exact tuple")
|
|
258
|
+
if any(
|
|
259
|
+
type(member) is not ArchiveReservoirRankedCandidate
|
|
260
|
+
for member in eligible_ranking
|
|
261
|
+
):
|
|
262
|
+
raise TypeError("eligible_ranking must contain exact ranked candidates")
|
|
263
|
+
for member in eligible_ranking:
|
|
264
|
+
ArchiveReservoirRankedCandidate.__post_init__(member)
|
|
265
|
+
if eligible_ranking != tuple(sorted(eligible_ranking, key=_reservoir_member_key)):
|
|
266
|
+
raise ValueError("eligible_ranking does not preserve policy order")
|
|
267
|
+
ranking_references = tuple(member.reference for member in eligible_ranking)
|
|
268
|
+
if len({value.candidate_id for value in ranking_references}) != len(
|
|
269
|
+
ranking_references
|
|
270
|
+
):
|
|
271
|
+
raise ValueError("eligible_ranking contains duplicate candidate IDs")
|
|
272
|
+
if len({value.configuration_hash for value in ranking_references}) != len(
|
|
273
|
+
ranking_references
|
|
274
|
+
):
|
|
275
|
+
raise ValueError("eligible_ranking contains duplicate configurations")
|
|
276
|
+
observed_ranks = {member.nondomination_rank for member in eligible_ranking}
|
|
277
|
+
if observed_ranks != set(range(1, max(observed_ranks) + 1)):
|
|
278
|
+
raise ValueError("eligible_ranking has non-contiguous nondomination ranks")
|
|
279
|
+
|
|
280
|
+
rank_one_references = {
|
|
281
|
+
member.reference
|
|
282
|
+
for member in eligible_ranking
|
|
283
|
+
if member.nondomination_rank == 1
|
|
284
|
+
}
|
|
285
|
+
if not set(eligible_front).issubset(rank_one_references):
|
|
286
|
+
raise ValueError("eligible_front is not contained in ranking rank one")
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _expected_lane_specs(
|
|
290
|
+
*,
|
|
291
|
+
task_sha256: str,
|
|
292
|
+
archive_snapshot_hash: str,
|
|
293
|
+
eligible_front: tuple[ParetoCandidateRef, ...],
|
|
294
|
+
eligible_ranking: tuple[ArchiveReservoirRankedCandidate, ...],
|
|
295
|
+
rotation_index: int,
|
|
296
|
+
) -> tuple[EliteExplorerLaneReceipt, EliteExplorerLaneReceipt]:
|
|
297
|
+
front_sha256 = _eligible_front_sha256(eligible_front)
|
|
298
|
+
ranking_sha256 = _eligible_ranking_sha256(eligible_ranking)
|
|
299
|
+
|
|
300
|
+
elite_pool = eligible_front
|
|
301
|
+
elite_pool_sha256 = _selection_pool_sha256(EliteExplorerLaneId.ELITE, elite_pool)
|
|
302
|
+
elite_anchor = _rotation_anchor(
|
|
303
|
+
task_sha256=task_sha256,
|
|
304
|
+
archive_snapshot_hash=archive_snapshot_hash,
|
|
305
|
+
eligible_front_sha256=front_sha256,
|
|
306
|
+
eligible_ranking_sha256=ranking_sha256,
|
|
307
|
+
lane_id=EliteExplorerLaneId.ELITE,
|
|
308
|
+
source=EliteExplorerLaneSource.CURRENT_PARETO_FRONT,
|
|
309
|
+
nondomination_rank=1,
|
|
310
|
+
fallback_reason=EliteExplorerFallbackReason.NONE,
|
|
311
|
+
selection_pool_sha256=elite_pool_sha256,
|
|
312
|
+
cardinality=len(elite_pool),
|
|
313
|
+
)
|
|
314
|
+
elite_ordinal = (elite_anchor + rotation_index) % len(elite_pool)
|
|
315
|
+
elite = EliteExplorerLaneReceipt(
|
|
316
|
+
lane_id=EliteExplorerLaneId.ELITE,
|
|
317
|
+
source=EliteExplorerLaneSource.CURRENT_PARETO_FRONT,
|
|
318
|
+
nondomination_rank=1,
|
|
319
|
+
fallback_reason=EliteExplorerFallbackReason.NONE,
|
|
320
|
+
selection_pool=elite_pool,
|
|
321
|
+
rotation_anchor=elite_anchor,
|
|
322
|
+
selected_ordinal=elite_ordinal,
|
|
323
|
+
selected_parent=elite_pool[elite_ordinal],
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
dominated_ranks = tuple(
|
|
327
|
+
sorted(
|
|
328
|
+
{
|
|
329
|
+
member.nondomination_rank
|
|
330
|
+
for member in eligible_ranking
|
|
331
|
+
if member.nondomination_rank > 1
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
if dominated_ranks:
|
|
336
|
+
explorer_rank = dominated_ranks[0]
|
|
337
|
+
explorer_source = EliteExplorerLaneSource.BEST_DOMINATED_RANK
|
|
338
|
+
fallback_reason = EliteExplorerFallbackReason.NONE
|
|
339
|
+
explorer_pool = tuple(
|
|
340
|
+
member.reference
|
|
341
|
+
for member in eligible_ranking
|
|
342
|
+
if member.nondomination_rank == explorer_rank
|
|
343
|
+
)
|
|
344
|
+
elif len(eligible_front) > 1:
|
|
345
|
+
explorer_rank = 1
|
|
346
|
+
explorer_source = EliteExplorerLaneSource.DISTINCT_FRONT_FALLBACK
|
|
347
|
+
fallback_reason = EliteExplorerFallbackReason.NO_DOMINATED_HISTORY
|
|
348
|
+
explorer_pool = tuple(
|
|
349
|
+
reference
|
|
350
|
+
for reference in eligible_front
|
|
351
|
+
if reference != elite.selected_parent
|
|
352
|
+
)
|
|
353
|
+
else:
|
|
354
|
+
explorer_rank = 1
|
|
355
|
+
explorer_source = EliteExplorerLaneSource.SINGLETON_REUSE_FALLBACK
|
|
356
|
+
fallback_reason = EliteExplorerFallbackReason.SINGLETON_FRONT
|
|
357
|
+
explorer_pool = eligible_front
|
|
358
|
+
|
|
359
|
+
explorer_pool_sha256 = _selection_pool_sha256(
|
|
360
|
+
EliteExplorerLaneId.EXPLORER,
|
|
361
|
+
explorer_pool,
|
|
362
|
+
)
|
|
363
|
+
explorer_anchor = _rotation_anchor(
|
|
364
|
+
task_sha256=task_sha256,
|
|
365
|
+
archive_snapshot_hash=archive_snapshot_hash,
|
|
366
|
+
eligible_front_sha256=front_sha256,
|
|
367
|
+
eligible_ranking_sha256=ranking_sha256,
|
|
368
|
+
lane_id=EliteExplorerLaneId.EXPLORER,
|
|
369
|
+
source=explorer_source,
|
|
370
|
+
nondomination_rank=explorer_rank,
|
|
371
|
+
fallback_reason=fallback_reason,
|
|
372
|
+
selection_pool_sha256=explorer_pool_sha256,
|
|
373
|
+
cardinality=len(explorer_pool),
|
|
374
|
+
)
|
|
375
|
+
explorer_ordinal = (explorer_anchor + rotation_index) % len(explorer_pool)
|
|
376
|
+
explorer = EliteExplorerLaneReceipt(
|
|
377
|
+
lane_id=EliteExplorerLaneId.EXPLORER,
|
|
378
|
+
source=explorer_source,
|
|
379
|
+
nondomination_rank=explorer_rank,
|
|
380
|
+
fallback_reason=fallback_reason,
|
|
381
|
+
selection_pool=explorer_pool,
|
|
382
|
+
rotation_anchor=explorer_anchor,
|
|
383
|
+
selected_ordinal=explorer_ordinal,
|
|
384
|
+
selected_parent=explorer_pool[explorer_ordinal],
|
|
385
|
+
)
|
|
386
|
+
return elite, explorer
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@dataclass(frozen=True, slots=True)
|
|
390
|
+
class ArchiveEliteExplorerParentSelectionReceipt:
|
|
391
|
+
"""Replayable binding of two named parents to complete archive authority."""
|
|
392
|
+
|
|
393
|
+
task_sha256: str
|
|
394
|
+
optimizer_generation: int
|
|
395
|
+
archive_snapshot_hash: str
|
|
396
|
+
eligible_front: tuple[ParetoCandidateRef, ...]
|
|
397
|
+
eligible_ranking: tuple[ArchiveReservoirRankedCandidate, ...]
|
|
398
|
+
rotation_index: int
|
|
399
|
+
lanes: tuple[EliteExplorerLaneReceipt, EliteExplorerLaneReceipt]
|
|
400
|
+
schema_version: int = field(init=False, default=SCHEMA_VERSION)
|
|
401
|
+
policy_id: str = field(init=False, default=POLICY_ID)
|
|
402
|
+
policy_version: int = field(init=False, default=POLICY_VERSION)
|
|
403
|
+
policy_definition_sha256: str = field(
|
|
404
|
+
init=False,
|
|
405
|
+
default=POLICY_DEFINITION_SHA256,
|
|
406
|
+
)
|
|
407
|
+
rotation_law_id: str = field(init=False, default=ROTATION_LAW_ID)
|
|
408
|
+
eligible_front_sha256: str = field(init=False, default="")
|
|
409
|
+
eligible_ranking_sha256: str = field(init=False, default="")
|
|
410
|
+
receipt_sha256: str = field(init=False, default="")
|
|
411
|
+
|
|
412
|
+
def __post_init__(self) -> None:
|
|
413
|
+
if (
|
|
414
|
+
self.schema_version != SCHEMA_VERSION
|
|
415
|
+
or self.policy_id != POLICY_ID
|
|
416
|
+
or self.policy_version != POLICY_VERSION
|
|
417
|
+
or self.policy_definition_sha256 != POLICY_DEFINITION_SHA256
|
|
418
|
+
or self.rotation_law_id != ROTATION_LAW_ID
|
|
419
|
+
):
|
|
420
|
+
raise ValueError("elite/explorer receipt uses a foreign policy identity")
|
|
421
|
+
require_sha256(self.task_sha256, "task_sha256")
|
|
422
|
+
require_sha256(self.archive_snapshot_hash, "archive_snapshot_hash")
|
|
423
|
+
if type(self.optimizer_generation) is not int or self.optimizer_generation < 0:
|
|
424
|
+
raise ValueError("optimizer_generation must be non-negative")
|
|
425
|
+
_validate_complete_authority(self.eligible_front, self.eligible_ranking)
|
|
426
|
+
computed_front_sha256 = _eligible_front_sha256(self.eligible_front)
|
|
427
|
+
if self.eligible_front_sha256 not in ("", computed_front_sha256):
|
|
428
|
+
raise ValueError("eligible_front_sha256 does not identify eligible_front")
|
|
429
|
+
object.__setattr__(self, "eligible_front_sha256", computed_front_sha256)
|
|
430
|
+
computed_ranking_sha256 = _eligible_ranking_sha256(self.eligible_ranking)
|
|
431
|
+
if self.eligible_ranking_sha256 not in ("", computed_ranking_sha256):
|
|
432
|
+
raise ValueError(
|
|
433
|
+
"eligible_ranking_sha256 does not identify eligible_ranking"
|
|
434
|
+
)
|
|
435
|
+
object.__setattr__(self, "eligible_ranking_sha256", computed_ranking_sha256)
|
|
436
|
+
if type(self.rotation_index) is not int or not (
|
|
437
|
+
0 <= self.rotation_index <= _MAX_ROTATION_INDEX
|
|
438
|
+
):
|
|
439
|
+
raise ValueError("rotation_index must be an exact non-negative int63")
|
|
440
|
+
if type(self.lanes) is not tuple or len(self.lanes) != 2:
|
|
441
|
+
raise ValueError("lanes must contain the exact elite/explorer pair")
|
|
442
|
+
if any(type(lane) is not EliteExplorerLaneReceipt for lane in self.lanes):
|
|
443
|
+
raise TypeError("lanes must contain exact EliteExplorerLaneReceipt values")
|
|
444
|
+
for lane in self.lanes:
|
|
445
|
+
lane.revalidate()
|
|
446
|
+
if tuple(lane.lane_id for lane in self.lanes) != (
|
|
447
|
+
EliteExplorerLaneId.ELITE,
|
|
448
|
+
EliteExplorerLaneId.EXPLORER,
|
|
449
|
+
):
|
|
450
|
+
raise ValueError("lanes must preserve stable elite/explorer order")
|
|
451
|
+
|
|
452
|
+
expected_lanes = _expected_lane_specs(
|
|
453
|
+
task_sha256=self.task_sha256,
|
|
454
|
+
archive_snapshot_hash=self.archive_snapshot_hash,
|
|
455
|
+
eligible_front=self.eligible_front,
|
|
456
|
+
eligible_ranking=self.eligible_ranking,
|
|
457
|
+
rotation_index=self.rotation_index,
|
|
458
|
+
)
|
|
459
|
+
if self.lanes != expected_lanes:
|
|
460
|
+
raise ValueError("lanes do not replay the elite/explorer rotation law")
|
|
461
|
+
if (
|
|
462
|
+
self.lanes[0].selected_parent == self.lanes[1].selected_parent
|
|
463
|
+
and self.lanes[1].source
|
|
464
|
+
is not EliteExplorerLaneSource.SINGLETON_REUSE_FALLBACK
|
|
465
|
+
):
|
|
466
|
+
raise ValueError("elite and explorer parents must be distinct")
|
|
467
|
+
|
|
468
|
+
computed_receipt_sha256 = hashlib.sha256(
|
|
469
|
+
_RECEIPT_DOMAIN + _canonical_json(self._record_without_hash())
|
|
470
|
+
).hexdigest()
|
|
471
|
+
if self.receipt_sha256 not in ("", computed_receipt_sha256):
|
|
472
|
+
raise ValueError("receipt_sha256 does not verify")
|
|
473
|
+
object.__setattr__(self, "receipt_sha256", computed_receipt_sha256)
|
|
474
|
+
|
|
475
|
+
def _record_without_hash(self) -> dict[str, object]:
|
|
476
|
+
return {
|
|
477
|
+
"schema_version": self.schema_version,
|
|
478
|
+
"policy_id": self.policy_id,
|
|
479
|
+
"policy_version": self.policy_version,
|
|
480
|
+
"policy_definition_sha256": self.policy_definition_sha256,
|
|
481
|
+
"rotation_law_id": self.rotation_law_id,
|
|
482
|
+
"task_sha256": self.task_sha256,
|
|
483
|
+
"optimizer_generation": self.optimizer_generation,
|
|
484
|
+
"archive_snapshot_hash": self.archive_snapshot_hash,
|
|
485
|
+
"eligible_front": [
|
|
486
|
+
_reference_record(reference) for reference in self.eligible_front
|
|
487
|
+
],
|
|
488
|
+
"eligible_front_sha256": self.eligible_front_sha256,
|
|
489
|
+
"eligible_ranking": [
|
|
490
|
+
member.to_trace_record() for member in self.eligible_ranking
|
|
491
|
+
],
|
|
492
|
+
"eligible_ranking_sha256": self.eligible_ranking_sha256,
|
|
493
|
+
"rotation_index": self.rotation_index,
|
|
494
|
+
"lanes": [lane.to_trace_record() for lane in self.lanes],
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
def revalidate(self) -> None:
|
|
498
|
+
if type(self) is not ArchiveEliteExplorerParentSelectionReceipt:
|
|
499
|
+
raise TypeError(
|
|
500
|
+
"receipt must be an exact ArchiveEliteExplorerParentSelectionReceipt"
|
|
501
|
+
)
|
|
502
|
+
ArchiveEliteExplorerParentSelectionReceipt.__post_init__(self)
|
|
503
|
+
|
|
504
|
+
def to_trace_record(self) -> dict[str, object]:
|
|
505
|
+
self.revalidate()
|
|
506
|
+
return {**self._record_without_hash(), "receipt_sha256": self.receipt_sha256}
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
@dataclass(frozen=True, slots=True)
|
|
510
|
+
class ArchiveEliteExplorerParentSelection:
|
|
511
|
+
"""Exactly two stable-lane parents and their authenticated receipt."""
|
|
512
|
+
|
|
513
|
+
parents: tuple[EvolutionCandidate, EvolutionCandidate]
|
|
514
|
+
receipt: ArchiveEliteExplorerParentSelectionReceipt
|
|
515
|
+
|
|
516
|
+
def __post_init__(self) -> None:
|
|
517
|
+
if type(self.parents) is not tuple or len(self.parents) != 2:
|
|
518
|
+
raise ValueError("parents must contain the exact elite/explorer pair")
|
|
519
|
+
if any(type(parent) is not EvolutionCandidate for parent in self.parents):
|
|
520
|
+
raise TypeError("parents must contain exact EvolutionCandidate values")
|
|
521
|
+
for parent in self.parents:
|
|
522
|
+
EvolutionCandidate.__post_init__(parent)
|
|
523
|
+
if type(self.receipt) is not ArchiveEliteExplorerParentSelectionReceipt:
|
|
524
|
+
raise TypeError("receipt must be an exact elite/explorer receipt")
|
|
525
|
+
self.receipt.revalidate()
|
|
526
|
+
if tuple(_candidate_reference(parent) for parent in self.parents) != tuple(
|
|
527
|
+
lane.selected_parent for lane in self.receipt.lanes
|
|
528
|
+
):
|
|
529
|
+
raise ValueError("selected parent values differ from their lane receipts")
|
|
530
|
+
if (
|
|
531
|
+
self.parents[0].candidate_id == self.parents[1].candidate_id
|
|
532
|
+
and self.receipt.lanes[1].source
|
|
533
|
+
is not EliteExplorerLaneSource.SINGLETON_REUSE_FALLBACK
|
|
534
|
+
):
|
|
535
|
+
raise ValueError(
|
|
536
|
+
"parent occurrences must be distinct outside singleton reuse"
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
@property
|
|
540
|
+
def elite(self) -> EvolutionCandidate:
|
|
541
|
+
"""Return the parent assigned to the stable elite lane."""
|
|
542
|
+
|
|
543
|
+
return self.parents[0]
|
|
544
|
+
|
|
545
|
+
@property
|
|
546
|
+
def explorer(self) -> EvolutionCandidate:
|
|
547
|
+
"""Return the parent assigned to the stable explorer lane."""
|
|
548
|
+
|
|
549
|
+
return self.parents[1]
|
|
550
|
+
|
|
551
|
+
def parent_for(self, lane_id: EliteExplorerLaneId) -> EvolutionCandidate:
|
|
552
|
+
"""Resolve a parent by stable lane identity."""
|
|
553
|
+
|
|
554
|
+
if type(lane_id) is not EliteExplorerLaneId:
|
|
555
|
+
raise TypeError("lane_id must be an EliteExplorerLaneId")
|
|
556
|
+
return self.parents[0 if lane_id is EliteExplorerLaneId.ELITE else 1]
|
|
557
|
+
|
|
558
|
+
def revalidate(self) -> None:
|
|
559
|
+
if type(self) is not ArchiveEliteExplorerParentSelection:
|
|
560
|
+
raise TypeError(
|
|
561
|
+
"selection must be an exact ArchiveEliteExplorerParentSelection"
|
|
562
|
+
)
|
|
563
|
+
ArchiveEliteExplorerParentSelection.__post_init__(self)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def validate_archive_elite_explorer_parent_selection(
|
|
567
|
+
state: OptimizerState,
|
|
568
|
+
selection: ArchiveEliteExplorerParentSelection,
|
|
569
|
+
) -> None:
|
|
570
|
+
"""Reject stale, foreign, incompletely ranked, or tampered lane choices."""
|
|
571
|
+
|
|
572
|
+
front_candidates, front_references = _validated_front(state)
|
|
573
|
+
ranked_candidates, ranked_members = _ranked_eligible_history(state)
|
|
574
|
+
if type(selection) is not ArchiveEliteExplorerParentSelection:
|
|
575
|
+
raise TypeError(
|
|
576
|
+
"selection must be an exact ArchiveEliteExplorerParentSelection"
|
|
577
|
+
)
|
|
578
|
+
selection.revalidate()
|
|
579
|
+
receipt = selection.receipt
|
|
580
|
+
if receipt.optimizer_generation != state.generation:
|
|
581
|
+
raise ValueError("elite/explorer selection is stale for this generation")
|
|
582
|
+
if receipt.archive_snapshot_hash != state.archive_snapshot_hash:
|
|
583
|
+
raise ValueError("elite/explorer selection is stale for this snapshot")
|
|
584
|
+
if receipt.eligible_front != front_references:
|
|
585
|
+
raise ValueError("receipt does not bind the complete current archive front")
|
|
586
|
+
if receipt.eligible_ranking != ranked_members:
|
|
587
|
+
raise ValueError("receipt does not bind the complete current eligible ranking")
|
|
588
|
+
|
|
589
|
+
candidates_by_id = {
|
|
590
|
+
candidate.candidate_id: candidate
|
|
591
|
+
for candidate in (*front_candidates, *ranked_candidates)
|
|
592
|
+
}
|
|
593
|
+
expected_parents = tuple(
|
|
594
|
+
candidates_by_id[lane.selected_parent.candidate_id] for lane in receipt.lanes
|
|
595
|
+
)
|
|
596
|
+
if selection.parents != expected_parents:
|
|
597
|
+
raise ValueError("elite/explorer parents are foreign to current history")
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
class ArchiveEliteExplorerParentSelector(Protocol):
|
|
601
|
+
"""Inverted planner seam for two stable archive parent lanes."""
|
|
602
|
+
|
|
603
|
+
policy_id: str
|
|
604
|
+
policy_version: int
|
|
605
|
+
definition_sha256: str
|
|
606
|
+
|
|
607
|
+
def select(
|
|
608
|
+
self,
|
|
609
|
+
state: OptimizerState,
|
|
610
|
+
*,
|
|
611
|
+
task_sha256: str,
|
|
612
|
+
expected_archive_snapshot_hash: str,
|
|
613
|
+
rotation_index: int = 0,
|
|
614
|
+
) -> ArchiveEliteExplorerParentSelection: ...
|
|
615
|
+
|
|
616
|
+
def to_record(self) -> dict[str, object]: ...
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
@dataclass(frozen=True, slots=True)
|
|
620
|
+
class TaskKeyedArchiveEliteExplorerParentPolicy:
|
|
621
|
+
"""Select explicit elite and explorer lanes without workload semantics."""
|
|
622
|
+
|
|
623
|
+
policy_id: str = field(init=False, default=POLICY_ID)
|
|
624
|
+
policy_version: int = field(init=False, default=POLICY_VERSION)
|
|
625
|
+
definition_sha256: str = field(
|
|
626
|
+
init=False,
|
|
627
|
+
default=POLICY_DEFINITION_SHA256,
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
def _validate_identity(self) -> None:
|
|
631
|
+
if type(self) is not TaskKeyedArchiveEliteExplorerParentPolicy:
|
|
632
|
+
raise TypeError(
|
|
633
|
+
"policy must be an exact TaskKeyedArchiveEliteExplorerParentPolicy"
|
|
634
|
+
)
|
|
635
|
+
if (
|
|
636
|
+
self.policy_id != POLICY_ID
|
|
637
|
+
or self.policy_version != POLICY_VERSION
|
|
638
|
+
or self.definition_sha256 != POLICY_DEFINITION_SHA256
|
|
639
|
+
):
|
|
640
|
+
raise ValueError("elite/explorer selector uses a foreign identity")
|
|
641
|
+
|
|
642
|
+
def select(
|
|
643
|
+
self,
|
|
644
|
+
state: OptimizerState,
|
|
645
|
+
*,
|
|
646
|
+
task_sha256: str,
|
|
647
|
+
expected_archive_snapshot_hash: str,
|
|
648
|
+
rotation_index: int = 0,
|
|
649
|
+
) -> ArchiveEliteExplorerParentSelection:
|
|
650
|
+
self._validate_identity()
|
|
651
|
+
require_sha256(task_sha256, "task_sha256")
|
|
652
|
+
require_sha256(
|
|
653
|
+
expected_archive_snapshot_hash,
|
|
654
|
+
"expected_archive_snapshot_hash",
|
|
655
|
+
)
|
|
656
|
+
if type(rotation_index) is not int or not (
|
|
657
|
+
0 <= rotation_index <= _MAX_ROTATION_INDEX
|
|
658
|
+
):
|
|
659
|
+
raise ValueError("rotation_index must be an exact non-negative int63")
|
|
660
|
+
front_candidates, front_references = _validated_front(state)
|
|
661
|
+
ranked_candidates, ranked_members = _ranked_eligible_history(state)
|
|
662
|
+
if expected_archive_snapshot_hash != state.archive_snapshot_hash:
|
|
663
|
+
raise ValueError("expected archive snapshot is stale")
|
|
664
|
+
|
|
665
|
+
lanes = _expected_lane_specs(
|
|
666
|
+
task_sha256=task_sha256,
|
|
667
|
+
archive_snapshot_hash=state.archive_snapshot_hash,
|
|
668
|
+
eligible_front=front_references,
|
|
669
|
+
eligible_ranking=ranked_members,
|
|
670
|
+
rotation_index=rotation_index,
|
|
671
|
+
)
|
|
672
|
+
candidates_by_id = {
|
|
673
|
+
candidate.candidate_id: candidate
|
|
674
|
+
for candidate in (*front_candidates, *ranked_candidates)
|
|
675
|
+
}
|
|
676
|
+
receipt = ArchiveEliteExplorerParentSelectionReceipt(
|
|
677
|
+
task_sha256=task_sha256,
|
|
678
|
+
optimizer_generation=state.generation,
|
|
679
|
+
archive_snapshot_hash=state.archive_snapshot_hash,
|
|
680
|
+
eligible_front=front_references,
|
|
681
|
+
eligible_ranking=ranked_members,
|
|
682
|
+
rotation_index=rotation_index,
|
|
683
|
+
lanes=lanes,
|
|
684
|
+
)
|
|
685
|
+
selection = ArchiveEliteExplorerParentSelection(
|
|
686
|
+
parents=tuple(
|
|
687
|
+
candidates_by_id[lane.selected_parent.candidate_id] for lane in lanes
|
|
688
|
+
),
|
|
689
|
+
receipt=receipt,
|
|
690
|
+
)
|
|
691
|
+
validate_archive_elite_explorer_parent_selection(state, selection)
|
|
692
|
+
return selection
|
|
693
|
+
|
|
694
|
+
def to_record(self) -> dict[str, object]:
|
|
695
|
+
self._validate_identity()
|
|
696
|
+
return {
|
|
697
|
+
"policy_id": self.policy_id,
|
|
698
|
+
"policy_version": self.policy_version,
|
|
699
|
+
"definition_sha256": self.definition_sha256,
|
|
700
|
+
"lane_ids": [lane.value for lane in EliteExplorerLaneId],
|
|
701
|
+
"rotation_law_id": ROTATION_LAW_ID,
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
__all__ = [
|
|
706
|
+
"ArchiveEliteExplorerParentSelection",
|
|
707
|
+
"ArchiveEliteExplorerParentSelectionReceipt",
|
|
708
|
+
"ArchiveEliteExplorerParentSelector",
|
|
709
|
+
"EliteExplorerFallbackReason",
|
|
710
|
+
"EliteExplorerLaneId",
|
|
711
|
+
"EliteExplorerLaneReceipt",
|
|
712
|
+
"EliteExplorerLaneSource",
|
|
713
|
+
"POLICY_DEFINITION_SHA256",
|
|
714
|
+
"POLICY_ID",
|
|
715
|
+
"POLICY_VERSION",
|
|
716
|
+
"ROTATION_LAW_ID",
|
|
717
|
+
"TaskKeyedArchiveEliteExplorerParentPolicy",
|
|
718
|
+
"validate_archive_elite_explorer_parent_selection",
|
|
719
|
+
]
|