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,1536 @@
|
|
|
1
|
+
"""Generic three-generation evolution over genuine K-option model choices.
|
|
2
|
+
|
|
3
|
+
The sealed G3 causal screen answers whether an assigned card can reproduce one
|
|
4
|
+
exact action. This module answers a different question: can causal memory help
|
|
5
|
+
a model *choose* useful actions from authenticated local neighbourhoods and can
|
|
6
|
+
those actions participate in subsequent evolution?
|
|
7
|
+
|
|
8
|
+
No benchmark semantics live here. A benchmark compiles card-local finite
|
|
9
|
+
action authorities and binds an outcome-blind orthogonal mate. The planner
|
|
10
|
+
owns only the reusable chronology:
|
|
11
|
+
|
|
12
|
+
* G1: two randomized diagnostic K-choice model calls;
|
|
13
|
+
* G2: adaptive A and score-shuffled S model choices, a prospective uniform U
|
|
14
|
+
choice on A's exact support, and an engine-owned disjoint mate E;
|
|
15
|
+
* G3: exact reproduction, replay-verified A+E, S+E, and U+E unions, and
|
|
16
|
+
model-selected exact-parent-import A x E and S x E crossovers.
|
|
17
|
+
|
|
18
|
+
A=U aliases are retained. Distinct causal occurrences may therefore share a
|
|
19
|
+
single physical evaluation through the engine cache; neither arm is resampled.
|
|
20
|
+
Reflection is deliberately outside this planner and can consume the exposed
|
|
21
|
+
terminal authorities, decisions, references, and slot identities.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import hashlib
|
|
27
|
+
import json
|
|
28
|
+
import re
|
|
29
|
+
from collections.abc import Mapping
|
|
30
|
+
from dataclasses import dataclass, field, replace
|
|
31
|
+
from types import MappingProxyType
|
|
32
|
+
from typing import Protocol, runtime_checkable
|
|
33
|
+
|
|
34
|
+
from agent_evolve.application.agentic_evolution import (
|
|
35
|
+
AgenticEvolutionEngine,
|
|
36
|
+
CrossoverResponseMode,
|
|
37
|
+
EvolutionCandidate,
|
|
38
|
+
InvocationPlan,
|
|
39
|
+
MaterializedInvocation,
|
|
40
|
+
MutationResponseMode,
|
|
41
|
+
OperatorKind,
|
|
42
|
+
ProposalAuthority,
|
|
43
|
+
RewardPolicyBinding,
|
|
44
|
+
)
|
|
45
|
+
from agent_evolve.application.budgeted_optimizer import (
|
|
46
|
+
FrozenWaveReward,
|
|
47
|
+
GenerationPlan,
|
|
48
|
+
OptimizerBudget,
|
|
49
|
+
OptimizerSlot,
|
|
50
|
+
OptimizerState,
|
|
51
|
+
SlotResult,
|
|
52
|
+
)
|
|
53
|
+
from agent_evolve.application.executable_hypothesis import (
|
|
54
|
+
CompiledHypothesisTreatment,
|
|
55
|
+
)
|
|
56
|
+
from agent_evolve.application.effective_choice_audit import (
|
|
57
|
+
EffectiveChoiceAuditReceipt,
|
|
58
|
+
audit_effective_choice_plan,
|
|
59
|
+
)
|
|
60
|
+
from agent_evolve.application.insight_memory import (
|
|
61
|
+
InsightMemoryBank,
|
|
62
|
+
InsightMemoryEntry,
|
|
63
|
+
context_stratum_hash,
|
|
64
|
+
)
|
|
65
|
+
from agent_evolve.application.matched_finite_action_block import (
|
|
66
|
+
finite_action_mutation_boundary,
|
|
67
|
+
)
|
|
68
|
+
from agent_evolve.application.materialized_variation import (
|
|
69
|
+
materialized_disjoint_invocation,
|
|
70
|
+
materialized_finite_action_decision,
|
|
71
|
+
)
|
|
72
|
+
from agent_evolve.application.staged_memory import (
|
|
73
|
+
DiagnosticMemoryCheckpointService,
|
|
74
|
+
)
|
|
75
|
+
from agent_evolve.domain.finite_action_set import (
|
|
76
|
+
MAX_MATCHED_FINITE_ACTIONS,
|
|
77
|
+
MIN_MATCHED_FINITE_ACTIONS,
|
|
78
|
+
FiniteActionSetAuthority,
|
|
79
|
+
FiniteActionSourceMode,
|
|
80
|
+
)
|
|
81
|
+
from agent_evolve.domain.finite_variation import FiniteVariationContract
|
|
82
|
+
from agent_evolve.domain.ids import CandidateId
|
|
83
|
+
from agent_evolve.domain.insight import InsightRef
|
|
84
|
+
from agent_evolve.domain.patch import ArrayIndex, JsonPath, ObjectKey, require_sha256
|
|
85
|
+
from agent_evolve.domain.typed_json import (
|
|
86
|
+
FrozenJsonObject,
|
|
87
|
+
freeze_json,
|
|
88
|
+
thaw_json,
|
|
89
|
+
typed_json_equal,
|
|
90
|
+
typed_json_sha256,
|
|
91
|
+
)
|
|
92
|
+
from agent_evolve.policies.memory.staged_causal import (
|
|
93
|
+
CausalSearchScorePolicy,
|
|
94
|
+
DeterministicMemoryControlPolicy,
|
|
95
|
+
FrozenDiagnosticMemoryWave,
|
|
96
|
+
MemoryAssignmentArm,
|
|
97
|
+
MemoryCheckpointClosure,
|
|
98
|
+
MemoryCheckpointClosureStatus,
|
|
99
|
+
ResolvedInsightAssignment,
|
|
100
|
+
WaveSealedCheckpointBuilder,
|
|
101
|
+
)
|
|
102
|
+
from agent_evolve.policies.variation.exact_parent_crossover import (
|
|
103
|
+
derive_exact_parent_crossover_contract,
|
|
104
|
+
resolve_exact_parent_import_for_target,
|
|
105
|
+
)
|
|
106
|
+
from agent_evolve.policies.variation.disjoint_recombination import (
|
|
107
|
+
DisjointPatchRecombiner,
|
|
108
|
+
)
|
|
109
|
+
from agent_evolve.policies.variation.typed_patch import derive_patch
|
|
110
|
+
from agent_evolve.ports.agentic_generator import CandidateDraft, SourceAttribution
|
|
111
|
+
from agent_evolve.ports.finite_action_selection import (
|
|
112
|
+
EngineFiniteActionPolicy,
|
|
113
|
+
EngineFiniteActionRequest,
|
|
114
|
+
FiniteActionDecision,
|
|
115
|
+
ProspectiveUniformRankToken,
|
|
116
|
+
)
|
|
117
|
+
from agent_evolve.ports.id_factory import IdFactory
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
MULTI_OPTION_EVOLUTION_POLICY_ID = "multi_option_evolution"
|
|
121
|
+
MULTI_OPTION_EVOLUTION_POLICY_VERSION = 2
|
|
122
|
+
MULTI_OPTION_EVOLUTION_BUDGET = OptimizerBudget(
|
|
123
|
+
max_unique_evaluations=13,
|
|
124
|
+
# Six evolutionary calls plus one separately injected terminal reflection.
|
|
125
|
+
max_logical_llm_calls=7,
|
|
126
|
+
max_generations=3,
|
|
127
|
+
)
|
|
128
|
+
MULTI_OPTION_G1_SLOT_IDS = (
|
|
129
|
+
"g1_diagnostic_0",
|
|
130
|
+
"g1_diagnostic_1",
|
|
131
|
+
)
|
|
132
|
+
MULTI_OPTION_G2_SLOT_IDS = (
|
|
133
|
+
"g2_adaptive",
|
|
134
|
+
"g2_score_shuffled",
|
|
135
|
+
"g2_uniform",
|
|
136
|
+
"g2_mate",
|
|
137
|
+
)
|
|
138
|
+
MULTI_OPTION_G3_CORE_SLOT_IDS = (
|
|
139
|
+
"g3_reproduction",
|
|
140
|
+
"g3_adaptive_union",
|
|
141
|
+
"g3_score_shuffled_union",
|
|
142
|
+
"g3_uniform_union",
|
|
143
|
+
)
|
|
144
|
+
MULTI_OPTION_G3_CROSSOVER_SLOT_IDS = (
|
|
145
|
+
"g3_adaptive_mate_crossover",
|
|
146
|
+
"g3_score_shuffled_mate_crossover",
|
|
147
|
+
)
|
|
148
|
+
MULTI_OPTION_G3_SLOT_IDS = (
|
|
149
|
+
*MULTI_OPTION_G3_CORE_SLOT_IDS,
|
|
150
|
+
*MULTI_OPTION_G3_CROSSOVER_SLOT_IDS,
|
|
151
|
+
)
|
|
152
|
+
MULTI_OPTION_G3_UNION_SOURCES = (
|
|
153
|
+
(MULTI_OPTION_G2_SLOT_IDS[0], MULTI_OPTION_G2_SLOT_IDS[3]),
|
|
154
|
+
(MULTI_OPTION_G2_SLOT_IDS[1], MULTI_OPTION_G2_SLOT_IDS[3]),
|
|
155
|
+
(MULTI_OPTION_G2_SLOT_IDS[2], MULTI_OPTION_G2_SLOT_IDS[3]),
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
159
|
+
_REWARD_DOMAIN = b"agent-evolve:multi-option-wave-reward:v1\x00"
|
|
160
|
+
_MATE_DOMAIN = b"agent-evolve:multi-option-parent-bound-mate:v1\x00"
|
|
161
|
+
_CROSSOVER_DEFINITION_SHA256 = hashlib.sha256(
|
|
162
|
+
b"agent-evolve:adaptive-shuffled-mate-crossover:def:v3\x00"
|
|
163
|
+
b"two bounded exact parent-import crossovers: adaptive x mate; "
|
|
164
|
+
b"score-shuffled x mate; exclude every representable known target by "
|
|
165
|
+
b"linear inverse locus resolution and exact replay"
|
|
166
|
+
).hexdigest()
|
|
167
|
+
_SEED_ROLE_DEFINITION = {
|
|
168
|
+
"diagnostic_parent": "first admitted G0 seed",
|
|
169
|
+
"evolution_parent": "second admitted G0 seed",
|
|
170
|
+
}
|
|
171
|
+
_SEED_ROLE_DEFINITION_SHA256 = hashlib.sha256(
|
|
172
|
+
b"agent-evolve:ordered-two-seed-role-policy:def:v1\x00"
|
|
173
|
+
+ json.dumps(
|
|
174
|
+
_SEED_ROLE_DEFINITION,
|
|
175
|
+
ensure_ascii=True,
|
|
176
|
+
allow_nan=False,
|
|
177
|
+
separators=(",", ":"),
|
|
178
|
+
sort_keys=True,
|
|
179
|
+
).encode("ascii")
|
|
180
|
+
).hexdigest()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _canonical_json(value: object) -> bytes:
|
|
184
|
+
return json.dumps(
|
|
185
|
+
value,
|
|
186
|
+
ensure_ascii=True,
|
|
187
|
+
allow_nan=False,
|
|
188
|
+
separators=(",", ":"),
|
|
189
|
+
sort_keys=True,
|
|
190
|
+
).encode("ascii")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
194
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _path_text(path: JsonPath) -> str:
|
|
198
|
+
parts = ["$"]
|
|
199
|
+
for segment in path.segments:
|
|
200
|
+
if type(segment) is ObjectKey:
|
|
201
|
+
parts.append(f".{segment.value}")
|
|
202
|
+
elif type(segment) is ArrayIndex:
|
|
203
|
+
parts.append(f"[{segment.value}]")
|
|
204
|
+
else: # pragma: no cover - JsonPath closes the union.
|
|
205
|
+
raise AssertionError("unsupported JSON-path segment")
|
|
206
|
+
return "".join(parts)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _paths_overlap(first: str, second: str) -> bool:
|
|
210
|
+
return (
|
|
211
|
+
first == second
|
|
212
|
+
or first.startswith(second + ".")
|
|
213
|
+
or first.startswith(second + "[")
|
|
214
|
+
or second.startswith(first + ".")
|
|
215
|
+
or second.startswith(first + "[")
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@dataclass(frozen=True, slots=True)
|
|
220
|
+
class SeedRoleSelection:
|
|
221
|
+
"""Two distinct admitted seeds assigned stable experimental roles."""
|
|
222
|
+
|
|
223
|
+
diagnostic_parent: EvolutionCandidate
|
|
224
|
+
evolution_parent: EvolutionCandidate
|
|
225
|
+
|
|
226
|
+
def __post_init__(self) -> None:
|
|
227
|
+
if (
|
|
228
|
+
type(self.diagnostic_parent) is not EvolutionCandidate
|
|
229
|
+
or type(self.evolution_parent) is not EvolutionCandidate
|
|
230
|
+
):
|
|
231
|
+
raise TypeError("seed roles require exact EvolutionCandidate values")
|
|
232
|
+
EvolutionCandidate.__post_init__(self.diagnostic_parent)
|
|
233
|
+
EvolutionCandidate.__post_init__(self.evolution_parent)
|
|
234
|
+
if self.diagnostic_parent.candidate_id == self.evolution_parent.candidate_id:
|
|
235
|
+
raise ValueError("seed roles require distinct candidate occurrences")
|
|
236
|
+
if not self.diagnostic_parent.valid or not self.evolution_parent.valid:
|
|
237
|
+
raise ValueError("seed roles require valid evaluated candidates")
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@runtime_checkable
|
|
241
|
+
class SeedRolePolicy(Protocol):
|
|
242
|
+
policy_id: str
|
|
243
|
+
policy_version: int
|
|
244
|
+
definition_sha256: str
|
|
245
|
+
|
|
246
|
+
def select(self, state: OptimizerState) -> SeedRoleSelection: ...
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@dataclass(frozen=True, slots=True)
|
|
250
|
+
class OrderedTwoSeedRolePolicy:
|
|
251
|
+
"""Default role policy for an explicitly ordered two-seed G0."""
|
|
252
|
+
|
|
253
|
+
policy_id: str = field(init=False, default="ordered_two_seed_roles")
|
|
254
|
+
policy_version: int = field(init=False, default=2)
|
|
255
|
+
definition_sha256: str = field(
|
|
256
|
+
init=False,
|
|
257
|
+
default=_SEED_ROLE_DEFINITION_SHA256,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def select(self, state: OptimizerState) -> SeedRoleSelection:
|
|
261
|
+
if type(state) is not OptimizerState:
|
|
262
|
+
raise TypeError("state must be an exact OptimizerState")
|
|
263
|
+
if state.generation != 0 or len(state.candidates) != 2:
|
|
264
|
+
raise ValueError("ordered seed roles require exactly two G0 seeds")
|
|
265
|
+
return SeedRoleSelection(state.candidates[0], state.candidates[1])
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@runtime_checkable
|
|
269
|
+
class ParentBoundFiniteChoice(Protocol):
|
|
270
|
+
"""Structural boundary for a prospectively frozen engine mate choice."""
|
|
271
|
+
|
|
272
|
+
catalog_id: str
|
|
273
|
+
parent_configuration_sha256: str
|
|
274
|
+
finite_contract_sha256: str
|
|
275
|
+
option_id: str
|
|
276
|
+
option_identity_sha256: str
|
|
277
|
+
choice_sha256: str
|
|
278
|
+
|
|
279
|
+
def validate_contract(self, contract: FiniteVariationContract) -> None: ...
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
@runtime_checkable
|
|
283
|
+
class MultiOptionEvolutionBenchmark(Protocol):
|
|
284
|
+
"""Narrow inverted benchmark boundary used by the generic planner."""
|
|
285
|
+
|
|
286
|
+
def bind_finite_variation(
|
|
287
|
+
self,
|
|
288
|
+
catalog_id: str,
|
|
289
|
+
parent_configuration: object,
|
|
290
|
+
) -> FiniteVariationContract: ...
|
|
291
|
+
|
|
292
|
+
def compile_registered_hypothesis_treatment(
|
|
293
|
+
self,
|
|
294
|
+
*,
|
|
295
|
+
catalog_id: str,
|
|
296
|
+
parent_candidate_id: CandidateId,
|
|
297
|
+
parent_configuration: object,
|
|
298
|
+
entry: InsightMemoryEntry,
|
|
299
|
+
requested_operator_kind: str,
|
|
300
|
+
context_projection_sha256: str,
|
|
301
|
+
endpoint_definition_sha256: str,
|
|
302
|
+
) -> CompiledHypothesisTreatment: ...
|
|
303
|
+
|
|
304
|
+
def compile_finite_action_set(
|
|
305
|
+
self,
|
|
306
|
+
*,
|
|
307
|
+
compiled_anchor: CompiledHypothesisTreatment,
|
|
308
|
+
required_cardinality: int,
|
|
309
|
+
source_mode: FiniteActionSourceMode,
|
|
310
|
+
) -> tuple[FiniteActionSetAuthority, object]: ...
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@runtime_checkable
|
|
314
|
+
class G3CrossoverPlanPolicy(Protocol):
|
|
315
|
+
"""Extension point for terminal model-directed crossover plans."""
|
|
316
|
+
|
|
317
|
+
policy_id: str
|
|
318
|
+
policy_version: int
|
|
319
|
+
definition_sha256: str
|
|
320
|
+
slot_ids: tuple[str, ...]
|
|
321
|
+
|
|
322
|
+
def plans(
|
|
323
|
+
self,
|
|
324
|
+
*,
|
|
325
|
+
adaptive: EvolutionCandidate,
|
|
326
|
+
shuffled: EvolutionCandidate,
|
|
327
|
+
uniform: EvolutionCandidate,
|
|
328
|
+
mate: EvolutionCandidate,
|
|
329
|
+
phase: str,
|
|
330
|
+
known_targets: tuple[FrozenJsonObject, ...],
|
|
331
|
+
) -> tuple[InvocationPlan, ...]: ...
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
@dataclass(frozen=True, slots=True)
|
|
335
|
+
class AdaptiveShuffledMateCrossoverPolicy:
|
|
336
|
+
"""Default terminal extension: exact-parent-import A x E and S x E crosses."""
|
|
337
|
+
|
|
338
|
+
policy_id: str = field(
|
|
339
|
+
init=False,
|
|
340
|
+
default="adaptive_shuffled_mate_crossover",
|
|
341
|
+
)
|
|
342
|
+
policy_version: int = field(init=False, default=3)
|
|
343
|
+
definition_sha256: str = field(
|
|
344
|
+
init=False,
|
|
345
|
+
default=_CROSSOVER_DEFINITION_SHA256,
|
|
346
|
+
)
|
|
347
|
+
slot_ids: tuple[str, ...] = field(
|
|
348
|
+
init=False,
|
|
349
|
+
default=MULTI_OPTION_G3_CROSSOVER_SLOT_IDS,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
def plans(
|
|
353
|
+
self,
|
|
354
|
+
*,
|
|
355
|
+
adaptive: EvolutionCandidate,
|
|
356
|
+
shuffled: EvolutionCandidate,
|
|
357
|
+
uniform: EvolutionCandidate,
|
|
358
|
+
mate: EvolutionCandidate,
|
|
359
|
+
phase: str,
|
|
360
|
+
known_targets: tuple[FrozenJsonObject, ...],
|
|
361
|
+
) -> tuple[InvocationPlan, ...]:
|
|
362
|
+
del uniform
|
|
363
|
+
if type(known_targets) is not tuple or any(
|
|
364
|
+
type(value) is not FrozenJsonObject for value in known_targets
|
|
365
|
+
):
|
|
366
|
+
raise TypeError("known_targets must contain exact FrozenJsonObject values")
|
|
367
|
+
plans: list[InvocationPlan] = []
|
|
368
|
+
for child, slot_id in zip(
|
|
369
|
+
(adaptive, shuffled),
|
|
370
|
+
self.slot_ids,
|
|
371
|
+
strict=True,
|
|
372
|
+
):
|
|
373
|
+
contract = derive_exact_parent_crossover_contract(
|
|
374
|
+
base=child.configuration,
|
|
375
|
+
donor=mate.configuration,
|
|
376
|
+
)
|
|
377
|
+
forbidden = tuple(
|
|
378
|
+
sorted(
|
|
379
|
+
{
|
|
380
|
+
resolved
|
|
381
|
+
for target in known_targets
|
|
382
|
+
if (
|
|
383
|
+
resolved := resolve_exact_parent_import_for_target(
|
|
384
|
+
base=child.configuration,
|
|
385
|
+
donor=mate.configuration,
|
|
386
|
+
contract=contract,
|
|
387
|
+
target=target,
|
|
388
|
+
)
|
|
389
|
+
)
|
|
390
|
+
is not None
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
)
|
|
394
|
+
plans.append(
|
|
395
|
+
InvocationPlan(
|
|
396
|
+
operator_kind=OperatorKind.TWO_PARENT_CROSSOVER,
|
|
397
|
+
parents=(child, mate),
|
|
398
|
+
generation=3,
|
|
399
|
+
label=slot_id,
|
|
400
|
+
phase=f"{phase}.model_crossover",
|
|
401
|
+
crossover_response_mode=(
|
|
402
|
+
CrossoverResponseMode.EXACT_PARENT_IMPORT_V1
|
|
403
|
+
),
|
|
404
|
+
exact_parent_crossover_contract=contract,
|
|
405
|
+
forbidden_exact_parent_import_sets=forbidden,
|
|
406
|
+
)
|
|
407
|
+
)
|
|
408
|
+
return tuple(plans)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
@dataclass(slots=True)
|
|
412
|
+
class MultiOptionEvolutionPlanner:
|
|
413
|
+
"""Stateful provider-agnostic planner for a full G0-to-G3 K-choice run."""
|
|
414
|
+
|
|
415
|
+
benchmark: MultiOptionEvolutionBenchmark
|
|
416
|
+
engine: AgenticEvolutionEngine
|
|
417
|
+
ids: IdFactory
|
|
418
|
+
memory: InsightMemoryBank
|
|
419
|
+
reward_binding: RewardPolicyBinding
|
|
420
|
+
active_references: tuple[InsightRef, InsightRef]
|
|
421
|
+
model_catalog_id: str
|
|
422
|
+
mate_catalog_id: str
|
|
423
|
+
mate_choice: ParentBoundFiniteChoice
|
|
424
|
+
required_cardinality: int
|
|
425
|
+
uniform_policy: EngineFiniteActionPolicy
|
|
426
|
+
task_sha256: str
|
|
427
|
+
pre_outcome_phase_commit_sha256: str
|
|
428
|
+
endpoint_definition_sha256: str
|
|
429
|
+
context_projection_sha256: str
|
|
430
|
+
estimand_stratum_sha256: str
|
|
431
|
+
phase: str = "multi_option_evolution"
|
|
432
|
+
diagnostic_subset_ranks: tuple[int, int] = (0, 1)
|
|
433
|
+
shuffled_permutation_rank: int = 1
|
|
434
|
+
score_policy: CausalSearchScorePolicy = field(
|
|
435
|
+
default_factory=lambda: CausalSearchScorePolicy(
|
|
436
|
+
prior_effective_sample_size=1.0,
|
|
437
|
+
uncertainty_scale=0.0,
|
|
438
|
+
exploration_weight=0.0,
|
|
439
|
+
)
|
|
440
|
+
)
|
|
441
|
+
controls: DeterministicMemoryControlPolicy = field(
|
|
442
|
+
default_factory=DeterministicMemoryControlPolicy
|
|
443
|
+
)
|
|
444
|
+
seed_role_policy: SeedRolePolicy = field(default_factory=OrderedTwoSeedRolePolicy)
|
|
445
|
+
recombiner: DisjointPatchRecombiner = field(default_factory=DisjointPatchRecombiner)
|
|
446
|
+
crossover_policy: G3CrossoverPlanPolicy = field(
|
|
447
|
+
default_factory=AdaptiveShuffledMateCrossoverPolicy
|
|
448
|
+
)
|
|
449
|
+
trace_sink: object | None = None
|
|
450
|
+
|
|
451
|
+
genesis: object | None = field(init=False, default=None)
|
|
452
|
+
wave: FrozenDiagnosticMemoryWave | None = field(init=False, default=None)
|
|
453
|
+
closure: MemoryCheckpointClosure | None = field(init=False, default=None)
|
|
454
|
+
g1_assignments: tuple[ResolvedInsightAssignment, ...] = field(
|
|
455
|
+
init=False,
|
|
456
|
+
default=(),
|
|
457
|
+
)
|
|
458
|
+
g1_authorities: tuple[FiniteActionSetAuthority, ...] = field(
|
|
459
|
+
init=False,
|
|
460
|
+
default=(),
|
|
461
|
+
)
|
|
462
|
+
g2_assignments: tuple[ResolvedInsightAssignment, ...] = field(
|
|
463
|
+
init=False,
|
|
464
|
+
default=(),
|
|
465
|
+
)
|
|
466
|
+
g2_adaptive_authority: FiniteActionSetAuthority | None = field(
|
|
467
|
+
init=False,
|
|
468
|
+
default=None,
|
|
469
|
+
)
|
|
470
|
+
g2_shuffled_authority: FiniteActionSetAuthority | None = field(
|
|
471
|
+
init=False,
|
|
472
|
+
default=None,
|
|
473
|
+
)
|
|
474
|
+
uniform_rank: ProspectiveUniformRankToken | None = field(
|
|
475
|
+
init=False,
|
|
476
|
+
default=None,
|
|
477
|
+
)
|
|
478
|
+
uniform_decision: FiniteActionDecision | None = field(
|
|
479
|
+
init=False,
|
|
480
|
+
default=None,
|
|
481
|
+
)
|
|
482
|
+
mate_invocation: MaterializedInvocation | None = field(
|
|
483
|
+
init=False,
|
|
484
|
+
default=None,
|
|
485
|
+
)
|
|
486
|
+
g3_union_materialization_receipt_sha256s: tuple[str, ...] = field(
|
|
487
|
+
init=False,
|
|
488
|
+
default=(),
|
|
489
|
+
)
|
|
490
|
+
_effective_choice_audit_receipts: dict[
|
|
491
|
+
tuple[int, str], EffectiveChoiceAuditReceipt
|
|
492
|
+
] = field(init=False, default_factory=dict)
|
|
493
|
+
_checkpoint_service: DiagnosticMemoryCheckpointService = field(init=False)
|
|
494
|
+
_diagnostic_parent_id: CandidateId | None = field(init=False, default=None)
|
|
495
|
+
_evolution_parent_id: CandidateId | None = field(init=False, default=None)
|
|
496
|
+
_diagnostic_parent_hash: str | None = field(init=False, default=None)
|
|
497
|
+
_evolution_parent_hash: str | None = field(init=False, default=None)
|
|
498
|
+
|
|
499
|
+
policy_id = MULTI_OPTION_EVOLUTION_POLICY_ID
|
|
500
|
+
policy_version = MULTI_OPTION_EVOLUTION_POLICY_VERSION
|
|
501
|
+
|
|
502
|
+
def __post_init__(self) -> None:
|
|
503
|
+
if not isinstance(self.benchmark, MultiOptionEvolutionBenchmark):
|
|
504
|
+
raise TypeError("benchmark must implement MultiOptionEvolutionBenchmark")
|
|
505
|
+
if not isinstance(self.engine, AgenticEvolutionEngine):
|
|
506
|
+
raise TypeError("engine must be an AgenticEvolutionEngine")
|
|
507
|
+
if not isinstance(self.ids, IdFactory):
|
|
508
|
+
raise TypeError("ids must implement IdFactory")
|
|
509
|
+
if type(self.memory) is not InsightMemoryBank:
|
|
510
|
+
raise TypeError("memory must be an exact InsightMemoryBank")
|
|
511
|
+
if self.engine.ids is not self.ids or self.engine.memory is not self.memory:
|
|
512
|
+
raise ValueError("planner must share the composed engine IDs and memory")
|
|
513
|
+
if type(self.reward_binding) is not RewardPolicyBinding:
|
|
514
|
+
raise TypeError("reward_binding must be exact")
|
|
515
|
+
RewardPolicyBinding.__post_init__(self.reward_binding)
|
|
516
|
+
if self.endpoint_definition_sha256 != self.reward_binding.definition_hash:
|
|
517
|
+
raise ValueError("endpoint definition must equal the reward/Q definition")
|
|
518
|
+
if (
|
|
519
|
+
type(self.active_references) is not tuple
|
|
520
|
+
or len(self.active_references) != 2
|
|
521
|
+
or self.active_references != tuple(sorted(set(self.active_references)))
|
|
522
|
+
):
|
|
523
|
+
raise ValueError("active_references must contain two canonical exact refs")
|
|
524
|
+
if any(type(value) is not InsightRef for value in self.active_references):
|
|
525
|
+
raise TypeError("active_references must contain exact InsightRef values")
|
|
526
|
+
if (
|
|
527
|
+
type(self.model_catalog_id) is not str
|
|
528
|
+
or _TOKEN.fullmatch(self.model_catalog_id) is None
|
|
529
|
+
):
|
|
530
|
+
raise ValueError("model_catalog_id must use the canonical token grammar")
|
|
531
|
+
if (
|
|
532
|
+
type(self.mate_catalog_id) is not str
|
|
533
|
+
or _TOKEN.fullmatch(self.mate_catalog_id) is None
|
|
534
|
+
):
|
|
535
|
+
raise ValueError("mate_catalog_id must use the canonical token grammar")
|
|
536
|
+
if not isinstance(self.mate_choice, ParentBoundFiniteChoice):
|
|
537
|
+
raise TypeError("mate_choice must implement ParentBoundFiniteChoice")
|
|
538
|
+
if self.mate_choice.catalog_id != self.mate_catalog_id:
|
|
539
|
+
raise ValueError("mate choice and mate catalog differ")
|
|
540
|
+
if not (
|
|
541
|
+
MIN_MATCHED_FINITE_ACTIONS
|
|
542
|
+
<= self.required_cardinality
|
|
543
|
+
<= MAX_MATCHED_FINITE_ACTIONS
|
|
544
|
+
):
|
|
545
|
+
raise ValueError(
|
|
546
|
+
"required_cardinality must lie in the authenticated finite-action range"
|
|
547
|
+
)
|
|
548
|
+
if not isinstance(self.uniform_policy, EngineFiniteActionPolicy):
|
|
549
|
+
raise TypeError("uniform_policy must implement EngineFiniteActionPolicy")
|
|
550
|
+
for name in (
|
|
551
|
+
"task_sha256",
|
|
552
|
+
"pre_outcome_phase_commit_sha256",
|
|
553
|
+
"endpoint_definition_sha256",
|
|
554
|
+
"context_projection_sha256",
|
|
555
|
+
"estimand_stratum_sha256",
|
|
556
|
+
):
|
|
557
|
+
require_sha256(getattr(self, name), name)
|
|
558
|
+
if type(self.phase) is not str or _TOKEN.fullmatch(self.phase) is None:
|
|
559
|
+
raise ValueError("phase must use the canonical token grammar")
|
|
560
|
+
expected_context = context_stratum_hash(
|
|
561
|
+
problem_id=self.engine.problem_id,
|
|
562
|
+
operator_kind=OperatorKind.TYPED_MUTATION.value,
|
|
563
|
+
phase=self.phase,
|
|
564
|
+
)
|
|
565
|
+
if self.context_projection_sha256 != expected_context:
|
|
566
|
+
raise ValueError(
|
|
567
|
+
"context projection must equal the engine's exact invocation context"
|
|
568
|
+
)
|
|
569
|
+
if self.diagnostic_subset_ranks not in {(0, 1), (1, 0)}:
|
|
570
|
+
raise ValueError("diagnostic_subset_ranks must be a permutation of (0,1)")
|
|
571
|
+
if type(self.shuffled_permutation_rank) is not int or (
|
|
572
|
+
self.shuffled_permutation_rank != 1
|
|
573
|
+
):
|
|
574
|
+
raise ValueError("two-card score shuffling requires derangement rank 1")
|
|
575
|
+
if not isinstance(self.score_policy, CausalSearchScorePolicy):
|
|
576
|
+
raise TypeError("score_policy must be a CausalSearchScorePolicy")
|
|
577
|
+
if not isinstance(self.controls, DeterministicMemoryControlPolicy):
|
|
578
|
+
raise TypeError("controls must be a DeterministicMemoryControlPolicy")
|
|
579
|
+
if not isinstance(self.seed_role_policy, SeedRolePolicy):
|
|
580
|
+
raise TypeError("seed_role_policy must implement SeedRolePolicy")
|
|
581
|
+
require_sha256(
|
|
582
|
+
self.seed_role_policy.definition_sha256,
|
|
583
|
+
"seed role policy definition_sha256",
|
|
584
|
+
)
|
|
585
|
+
if not isinstance(self.recombiner, DisjointPatchRecombiner):
|
|
586
|
+
raise TypeError("recombiner must be a DisjointPatchRecombiner")
|
|
587
|
+
if not isinstance(self.crossover_policy, G3CrossoverPlanPolicy):
|
|
588
|
+
raise TypeError("crossover_policy must implement G3CrossoverPlanPolicy")
|
|
589
|
+
require_sha256(
|
|
590
|
+
self.crossover_policy.definition_sha256,
|
|
591
|
+
"crossover policy definition_sha256",
|
|
592
|
+
)
|
|
593
|
+
if (
|
|
594
|
+
type(self.crossover_policy.slot_ids) is not tuple
|
|
595
|
+
or any(
|
|
596
|
+
type(value) is not str or _TOKEN.fullmatch(value) is None
|
|
597
|
+
for value in self.crossover_policy.slot_ids
|
|
598
|
+
)
|
|
599
|
+
or len(set(self.crossover_policy.slot_ids))
|
|
600
|
+
!= len(self.crossover_policy.slot_ids)
|
|
601
|
+
or set(self.crossover_policy.slot_ids).intersection(
|
|
602
|
+
MULTI_OPTION_G3_CORE_SLOT_IDS
|
|
603
|
+
)
|
|
604
|
+
):
|
|
605
|
+
raise ValueError("crossover policy slot IDs must be unique canonical IDs")
|
|
606
|
+
if self.trace_sink is not None and not callable(self.trace_sink):
|
|
607
|
+
raise TypeError("trace_sink must be callable")
|
|
608
|
+
self._checkpoint_service = DiagnosticMemoryCheckpointService(
|
|
609
|
+
WaveSealedCheckpointBuilder(self.score_policy),
|
|
610
|
+
trace_sink=self.trace_sink,
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
@property
|
|
614
|
+
def adaptive_reference(self) -> InsightRef | None:
|
|
615
|
+
"""Exact card chosen by the post-diagnostic adaptive arm, if frozen."""
|
|
616
|
+
|
|
617
|
+
if not self.g2_assignments:
|
|
618
|
+
return None
|
|
619
|
+
selected = self.g2_assignments[0].selection_decision.selected
|
|
620
|
+
return selected[0] if len(selected) == 1 else None
|
|
621
|
+
|
|
622
|
+
@property
|
|
623
|
+
def effective_choice_audit_receipts(
|
|
624
|
+
self,
|
|
625
|
+
) -> Mapping[tuple[int, str], EffectiveChoiceAuditReceipt]:
|
|
626
|
+
"""Immutable chronological ledger keyed by ``(generation, slot_id)``.
|
|
627
|
+
|
|
628
|
+
Only model-authored finite K-choice mutations enter this ledger. A
|
|
629
|
+
plan is not exposed to the optimizer until its receipt has been
|
|
630
|
+
derived from the exact application-layer authority and contract.
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
return MappingProxyType(dict(self._effective_choice_audit_receipts))
|
|
634
|
+
|
|
635
|
+
@property
|
|
636
|
+
def terminal_slot_ids(self) -> tuple[str, ...]:
|
|
637
|
+
return (
|
|
638
|
+
*MULTI_OPTION_G3_CORE_SLOT_IDS,
|
|
639
|
+
*self.crossover_policy.slot_ids,
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
def terminal_union_sources(self) -> tuple[tuple[str, str], ...]:
|
|
644
|
+
return MULTI_OPTION_G3_UNION_SOURCES
|
|
645
|
+
|
|
646
|
+
def plan(self, state: OptimizerState, budget: OptimizerBudget) -> GenerationPlan:
|
|
647
|
+
if type(state) is not OptimizerState:
|
|
648
|
+
raise TypeError("state must be an exact OptimizerState")
|
|
649
|
+
if type(budget) is not OptimizerBudget:
|
|
650
|
+
raise TypeError("budget must be an exact OptimizerBudget")
|
|
651
|
+
extension_count = len(self.crossover_policy.slot_ids)
|
|
652
|
+
if (
|
|
653
|
+
budget.max_generations != 3
|
|
654
|
+
or budget.max_logical_llm_calls < 4 + extension_count
|
|
655
|
+
or budget.max_unique_evaluations < 11 + extension_count
|
|
656
|
+
):
|
|
657
|
+
raise ValueError(
|
|
658
|
+
"multi-option evolution budget cannot reserve its complete "
|
|
659
|
+
"three-generation core and terminal model extensions"
|
|
660
|
+
)
|
|
661
|
+
generation = state.generation + 1
|
|
662
|
+
if generation == 1:
|
|
663
|
+
return self._g1(state)
|
|
664
|
+
if generation == 2:
|
|
665
|
+
return self._g2(state)
|
|
666
|
+
if generation == 3:
|
|
667
|
+
return self._g3(state)
|
|
668
|
+
raise ValueError("multi-option evolution has exactly three generations")
|
|
669
|
+
|
|
670
|
+
def _reward(self, state: OptimizerState, generation: int) -> FrozenWaveReward:
|
|
671
|
+
return FrozenWaveReward(
|
|
672
|
+
binding=self.reward_binding,
|
|
673
|
+
archive_snapshot_hash=state.archive_snapshot_hash,
|
|
674
|
+
reward_snapshot_hash=_hash(
|
|
675
|
+
_REWARD_DOMAIN,
|
|
676
|
+
{
|
|
677
|
+
"generation": generation,
|
|
678
|
+
"archive_snapshot_hash": state.archive_snapshot_hash,
|
|
679
|
+
"endpoint_definition_sha256": self.endpoint_definition_sha256,
|
|
680
|
+
},
|
|
681
|
+
),
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
def _seed_roles(self, state: OptimizerState) -> SeedRoleSelection:
|
|
685
|
+
if self._diagnostic_parent_id is None:
|
|
686
|
+
roles = self.seed_role_policy.select(state)
|
|
687
|
+
SeedRoleSelection.__post_init__(roles)
|
|
688
|
+
self._diagnostic_parent_id = roles.diagnostic_parent.candidate_id
|
|
689
|
+
self._evolution_parent_id = roles.evolution_parent.candidate_id
|
|
690
|
+
self._diagnostic_parent_hash = (
|
|
691
|
+
roles.diagnostic_parent.occurrence.configuration_hash
|
|
692
|
+
)
|
|
693
|
+
self._evolution_parent_hash = (
|
|
694
|
+
roles.evolution_parent.occurrence.configuration_hash
|
|
695
|
+
)
|
|
696
|
+
return roles
|
|
697
|
+
by_id = {value.candidate_id: value for value in state.candidates}
|
|
698
|
+
try:
|
|
699
|
+
diagnostic = by_id[self._diagnostic_parent_id]
|
|
700
|
+
evolution = by_id[self._evolution_parent_id]
|
|
701
|
+
except KeyError as exc:
|
|
702
|
+
raise ValueError("frozen G0 seed occurrence disappeared") from exc
|
|
703
|
+
if (
|
|
704
|
+
diagnostic.occurrence.configuration_hash != self._diagnostic_parent_hash
|
|
705
|
+
or evolution.occurrence.configuration_hash != self._evolution_parent_hash
|
|
706
|
+
):
|
|
707
|
+
raise ValueError("frozen G0 seed configuration changed")
|
|
708
|
+
return SeedRoleSelection(diagnostic, evolution)
|
|
709
|
+
|
|
710
|
+
def _require_state(self, state: OptimizerState) -> SeedRoleSelection:
|
|
711
|
+
expected_candidates = {0: 2, 1: 4, 2: 8}.get(state.generation)
|
|
712
|
+
if expected_candidates is None:
|
|
713
|
+
raise ValueError("unsupported multi-option generation state")
|
|
714
|
+
if len(state.candidates) != expected_candidates:
|
|
715
|
+
raise ValueError("candidate history differs from the G0-to-G3 chronology")
|
|
716
|
+
if len(state.generation_receipts) != state.generation:
|
|
717
|
+
raise ValueError("generation receipt history is incomplete")
|
|
718
|
+
expected_calls = {0: 0, 1: 2, 2: 4}[state.generation]
|
|
719
|
+
if state.logical_llm_calls != expected_calls:
|
|
720
|
+
raise ValueError("logical-call count differs from the four-call chronology")
|
|
721
|
+
return self._seed_roles(state)
|
|
722
|
+
|
|
723
|
+
def _compile_authority(
|
|
724
|
+
self,
|
|
725
|
+
*,
|
|
726
|
+
parent: EvolutionCandidate,
|
|
727
|
+
reference: InsightRef,
|
|
728
|
+
source_mode: FiniteActionSourceMode,
|
|
729
|
+
) -> FiniteActionSetAuthority:
|
|
730
|
+
entry = self.memory.entries_for((reference,))[0]
|
|
731
|
+
if not entry.retrievable:
|
|
732
|
+
raise ValueError(
|
|
733
|
+
"finite-choice causal assignments require a seed or explicitly "
|
|
734
|
+
"promoted card"
|
|
735
|
+
)
|
|
736
|
+
compiled = self.benchmark.compile_registered_hypothesis_treatment(
|
|
737
|
+
catalog_id=self.model_catalog_id,
|
|
738
|
+
parent_candidate_id=parent.candidate_id,
|
|
739
|
+
parent_configuration=parent.configuration,
|
|
740
|
+
entry=entry,
|
|
741
|
+
requested_operator_kind=OperatorKind.TYPED_MUTATION.value,
|
|
742
|
+
context_projection_sha256=self.context_projection_sha256,
|
|
743
|
+
endpoint_definition_sha256=self.endpoint_definition_sha256,
|
|
744
|
+
)
|
|
745
|
+
authority, _ = self.benchmark.compile_finite_action_set(
|
|
746
|
+
compiled_anchor=compiled,
|
|
747
|
+
required_cardinality=self.required_cardinality,
|
|
748
|
+
source_mode=source_mode,
|
|
749
|
+
)
|
|
750
|
+
if type(authority) is not FiniteActionSetAuthority:
|
|
751
|
+
raise TypeError("benchmark returned an invalid finite action authority")
|
|
752
|
+
FiniteActionSetAuthority.__post_init__(authority)
|
|
753
|
+
if (
|
|
754
|
+
authority.card.reference != reference
|
|
755
|
+
or authority.card.source_mode is not source_mode
|
|
756
|
+
or authority.support.parent_candidate_id != parent.candidate_id
|
|
757
|
+
or authority.support.parent_configuration_sha256
|
|
758
|
+
!= parent.occurrence.configuration_hash
|
|
759
|
+
or authority.support.cardinality != self.required_cardinality
|
|
760
|
+
):
|
|
761
|
+
raise ValueError("finite action authority differs from its requested card")
|
|
762
|
+
return authority
|
|
763
|
+
|
|
764
|
+
def _provisional_choice_plan(
|
|
765
|
+
self,
|
|
766
|
+
*,
|
|
767
|
+
parent: EvolutionCandidate,
|
|
768
|
+
generation: int,
|
|
769
|
+
label: str,
|
|
770
|
+
authority: FiniteActionSetAuthority,
|
|
771
|
+
) -> InvocationPlan:
|
|
772
|
+
contract = authority.support.support_contract
|
|
773
|
+
allowed, mutation = finite_action_mutation_boundary(
|
|
774
|
+
contract=contract,
|
|
775
|
+
parent_candidate_id=parent.candidate_id,
|
|
776
|
+
)
|
|
777
|
+
return InvocationPlan(
|
|
778
|
+
operator_kind=OperatorKind.TYPED_MUTATION,
|
|
779
|
+
parents=(parent,),
|
|
780
|
+
generation=generation,
|
|
781
|
+
label=label,
|
|
782
|
+
allowed_top_level=allowed,
|
|
783
|
+
phase=self.phase,
|
|
784
|
+
mutation_contract=mutation,
|
|
785
|
+
mutation_response_mode=MutationResponseMode.FINITE_OPTION_SELECTION_V1,
|
|
786
|
+
finite_variation_contract=contract,
|
|
787
|
+
quarantine_test_insights=(authority.card.reference,),
|
|
788
|
+
finite_action_set_authority=authority,
|
|
789
|
+
)
|
|
790
|
+
|
|
791
|
+
def _resolve_plan(
|
|
792
|
+
self,
|
|
793
|
+
*,
|
|
794
|
+
provisional: InvocationPlan,
|
|
795
|
+
snapshot,
|
|
796
|
+
arm: MemoryAssignmentArm,
|
|
797
|
+
selection_decision,
|
|
798
|
+
block_id: str,
|
|
799
|
+
) -> tuple[InvocationPlan, ResolvedInsightAssignment]:
|
|
800
|
+
prompt_shape = self.engine.prompt_shape_commitment(
|
|
801
|
+
provisional,
|
|
802
|
+
selected_insight_count=1,
|
|
803
|
+
reward_definition_hash=self.reward_binding.definition_hash,
|
|
804
|
+
)
|
|
805
|
+
assignment = ResolvedInsightAssignment.resolve(
|
|
806
|
+
credit_unit_id=self.ids.new_operator_invocation_id(),
|
|
807
|
+
snapshot=snapshot,
|
|
808
|
+
expected_snapshot_sha256=snapshot.snapshot_sha256,
|
|
809
|
+
block_id=block_id,
|
|
810
|
+
arm=arm,
|
|
811
|
+
selection_decision=selection_decision,
|
|
812
|
+
prompt_shape_sha256=prompt_shape,
|
|
813
|
+
)
|
|
814
|
+
return (
|
|
815
|
+
replace(
|
|
816
|
+
provisional,
|
|
817
|
+
quarantine_test_insights=(),
|
|
818
|
+
resolved_insight_assignment=assignment,
|
|
819
|
+
),
|
|
820
|
+
assignment,
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
def _audit_choice_plans(
|
|
824
|
+
self,
|
|
825
|
+
plans: tuple[InvocationPlan, ...],
|
|
826
|
+
) -> tuple[EffectiveChoiceAuditReceipt, ...]:
|
|
827
|
+
"""Fail closed and atomically append a batch of model K-choice plans."""
|
|
828
|
+
|
|
829
|
+
if type(plans) is not tuple or not plans:
|
|
830
|
+
raise ValueError("effective-choice audit batch must be non-empty")
|
|
831
|
+
staged: dict[tuple[int, str], EffectiveChoiceAuditReceipt] = {}
|
|
832
|
+
for plan in plans:
|
|
833
|
+
receipt = audit_effective_choice_plan(
|
|
834
|
+
plan,
|
|
835
|
+
minimum_cardinality=self.required_cardinality,
|
|
836
|
+
)
|
|
837
|
+
key = (receipt.generation, receipt.invocation_label)
|
|
838
|
+
if key in self._effective_choice_audit_receipts or key in staged:
|
|
839
|
+
raise RuntimeError("effective-choice audit coordinate was reused")
|
|
840
|
+
staged[key] = receipt
|
|
841
|
+
self._effective_choice_audit_receipts.update(staged)
|
|
842
|
+
return tuple(staged.values())
|
|
843
|
+
|
|
844
|
+
def _g1(self, state: OptimizerState) -> GenerationPlan:
|
|
845
|
+
if self.wave is not None:
|
|
846
|
+
raise RuntimeError("G1 diagnostic wave was already frozen")
|
|
847
|
+
roles = self._require_state(state)
|
|
848
|
+
entries = self.memory.entries_for(self.active_references)
|
|
849
|
+
self.genesis = self.score_policy.genesis(
|
|
850
|
+
exact_context_hash=self.context_projection_sha256,
|
|
851
|
+
estimand_stratum_hash=self.estimand_stratum_sha256,
|
|
852
|
+
priors={entry.reference: entry.initial_score for entry in entries},
|
|
853
|
+
)
|
|
854
|
+
authorities: list[FiniteActionSetAuthority] = []
|
|
855
|
+
assignments: list[ResolvedInsightAssignment] = []
|
|
856
|
+
choice_plans: list[InvocationPlan] = []
|
|
857
|
+
for index, subset_rank in enumerate(self.diagnostic_subset_ranks):
|
|
858
|
+
decision = self.controls.uniform(
|
|
859
|
+
snapshot=self.genesis,
|
|
860
|
+
subset_size=1,
|
|
861
|
+
subset_rank=subset_rank,
|
|
862
|
+
)
|
|
863
|
+
reference = decision.selected[0]
|
|
864
|
+
authority = self._compile_authority(
|
|
865
|
+
parent=roles.diagnostic_parent,
|
|
866
|
+
reference=reference,
|
|
867
|
+
source_mode=FiniteActionSourceMode.COMPILED_ACTIVE_CARD,
|
|
868
|
+
)
|
|
869
|
+
provisional = self._provisional_choice_plan(
|
|
870
|
+
parent=roles.diagnostic_parent,
|
|
871
|
+
generation=1,
|
|
872
|
+
label=MULTI_OPTION_G1_SLOT_IDS[index],
|
|
873
|
+
authority=authority,
|
|
874
|
+
)
|
|
875
|
+
plan, assignment = self._resolve_plan(
|
|
876
|
+
provisional=provisional,
|
|
877
|
+
snapshot=self.genesis,
|
|
878
|
+
arm=MemoryAssignmentArm.DIAGNOSTIC,
|
|
879
|
+
selection_decision=decision,
|
|
880
|
+
block_id="multi_option_g1_diagnostic",
|
|
881
|
+
)
|
|
882
|
+
authorities.append(authority)
|
|
883
|
+
assignments.append(assignment)
|
|
884
|
+
choice_plans.append(plan)
|
|
885
|
+
if tuple(sorted(value.card.reference for value in authorities)) != (
|
|
886
|
+
self.active_references
|
|
887
|
+
):
|
|
888
|
+
raise RuntimeError("G1 did not cover both active cards exactly once")
|
|
889
|
+
audits = self._audit_choice_plans(tuple(choice_plans))
|
|
890
|
+
slots = tuple(
|
|
891
|
+
OptimizerSlot.model(
|
|
892
|
+
slot_id=MULTI_OPTION_G1_SLOT_IDS[index],
|
|
893
|
+
role="diagnostic_k_option_choice",
|
|
894
|
+
plan=plan,
|
|
895
|
+
)
|
|
896
|
+
for index, plan in enumerate(choice_plans)
|
|
897
|
+
)
|
|
898
|
+
self.g1_authorities = tuple(authorities)
|
|
899
|
+
self.g1_assignments = tuple(assignments)
|
|
900
|
+
self.wave = FrozenDiagnosticMemoryWave(
|
|
901
|
+
wave_id="multi_option_g1_diagnostic_wave",
|
|
902
|
+
prior_snapshot=self.genesis,
|
|
903
|
+
assignments=tuple(
|
|
904
|
+
sorted(assignments, key=lambda value: value.assignment_sha256)
|
|
905
|
+
),
|
|
906
|
+
reward_definition_hash=self.reward_binding.definition_hash,
|
|
907
|
+
no_yield_reward=self.reward_binding.failure_score,
|
|
908
|
+
)
|
|
909
|
+
self._checkpoint_service.publish_frozen_wave(self.wave)
|
|
910
|
+
return GenerationPlan(
|
|
911
|
+
generation=1,
|
|
912
|
+
slots=slots,
|
|
913
|
+
reward=self._reward(state, 1),
|
|
914
|
+
planner_policy_id=self.policy_id,
|
|
915
|
+
planner_policy_version=self.policy_version,
|
|
916
|
+
metadata=tuple(
|
|
917
|
+
sorted(
|
|
918
|
+
(
|
|
919
|
+
("diagnostic_wave_sha256", self.wave.wave_sha256),
|
|
920
|
+
("genesis_snapshot_sha256", self.genesis.snapshot_sha256),
|
|
921
|
+
*(
|
|
922
|
+
(
|
|
923
|
+
f"{slot_id}_authority_sha256",
|
|
924
|
+
authority.authority_sha256,
|
|
925
|
+
)
|
|
926
|
+
for slot_id, authority in zip(
|
|
927
|
+
MULTI_OPTION_G1_SLOT_IDS,
|
|
928
|
+
authorities,
|
|
929
|
+
strict=True,
|
|
930
|
+
)
|
|
931
|
+
),
|
|
932
|
+
*(
|
|
933
|
+
(
|
|
934
|
+
f"{slot_id}_effective_choice_audit_sha256",
|
|
935
|
+
receipt.receipt_sha256,
|
|
936
|
+
)
|
|
937
|
+
for slot_id, receipt in zip(
|
|
938
|
+
MULTI_OPTION_G1_SLOT_IDS,
|
|
939
|
+
audits,
|
|
940
|
+
strict=True,
|
|
941
|
+
)
|
|
942
|
+
),
|
|
943
|
+
)
|
|
944
|
+
)
|
|
945
|
+
),
|
|
946
|
+
)
|
|
947
|
+
|
|
948
|
+
def _materialize_mate(
|
|
949
|
+
self,
|
|
950
|
+
*,
|
|
951
|
+
parent: EvolutionCandidate,
|
|
952
|
+
) -> MaterializedInvocation:
|
|
953
|
+
contract = self.benchmark.bind_finite_variation(
|
|
954
|
+
self.mate_catalog_id,
|
|
955
|
+
parent.configuration,
|
|
956
|
+
)
|
|
957
|
+
self.mate_choice.validate_contract(contract)
|
|
958
|
+
option = contract.resolve(self.mate_choice.option_id)
|
|
959
|
+
if option.identity_sha256 != self.mate_choice.option_identity_sha256:
|
|
960
|
+
raise ValueError("mate option identity changed")
|
|
961
|
+
candidate_id = self.ids.new_candidate_id()
|
|
962
|
+
patch = derive_patch(
|
|
963
|
+
parent.configuration,
|
|
964
|
+
option.child_configuration,
|
|
965
|
+
base_candidate_id=parent.candidate_id,
|
|
966
|
+
target_candidate_id=candidate_id,
|
|
967
|
+
)
|
|
968
|
+
if not patch.operations:
|
|
969
|
+
raise ValueError("orthogonal mate must change at least one path")
|
|
970
|
+
paths = tuple(sorted({_path_text(value.path) for value in patch.operations}))
|
|
971
|
+
top_level = tuple(
|
|
972
|
+
sorted(
|
|
973
|
+
{
|
|
974
|
+
value.path.segments[0].value
|
|
975
|
+
for value in patch.operations
|
|
976
|
+
if type(value.path.segments[0]) is ObjectKey
|
|
977
|
+
}
|
|
978
|
+
)
|
|
979
|
+
)
|
|
980
|
+
configuration = thaw_json(option.child_configuration)
|
|
981
|
+
if type(configuration) is not dict:
|
|
982
|
+
raise TypeError("mate child must be a typed-JSON object")
|
|
983
|
+
receipt_hash = _hash(
|
|
984
|
+
_MATE_DOMAIN,
|
|
985
|
+
{
|
|
986
|
+
"choice_sha256": self.mate_choice.choice_sha256,
|
|
987
|
+
"parent_candidate_id": parent.candidate_id.value,
|
|
988
|
+
"target_candidate_id": candidate_id.value,
|
|
989
|
+
"patch_hash": patch.patch_hash,
|
|
990
|
+
},
|
|
991
|
+
)
|
|
992
|
+
return MaterializedInvocation(
|
|
993
|
+
plan=InvocationPlan(
|
|
994
|
+
operator_kind=OperatorKind.TYPED_MUTATION,
|
|
995
|
+
parents=(parent,),
|
|
996
|
+
generation=2,
|
|
997
|
+
label=MULTI_OPTION_G2_SLOT_IDS[3],
|
|
998
|
+
allowed_top_level=top_level,
|
|
999
|
+
phase=f"{self.phase}.mate",
|
|
1000
|
+
),
|
|
1001
|
+
draft=CandidateDraft(
|
|
1002
|
+
configuration=configuration,
|
|
1003
|
+
design_rationale=(
|
|
1004
|
+
"Engine-owned parent-bound mate on support disjoint from "
|
|
1005
|
+
"every authenticated model option."
|
|
1006
|
+
),
|
|
1007
|
+
intended_changes=paths,
|
|
1008
|
+
source_attribution=tuple(
|
|
1009
|
+
SourceAttribution(path, "mutation") for path in paths
|
|
1010
|
+
),
|
|
1011
|
+
),
|
|
1012
|
+
candidate_id=candidate_id,
|
|
1013
|
+
materialization_policy_id="parent_bound_finite_mate",
|
|
1014
|
+
materialization_policy_version=1,
|
|
1015
|
+
materialization_receipt_hash=receipt_hash,
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
def _require_disjoint_support(
|
|
1019
|
+
self,
|
|
1020
|
+
authority: FiniteActionSetAuthority,
|
|
1021
|
+
mate: MaterializedInvocation,
|
|
1022
|
+
) -> None:
|
|
1023
|
+
mate_paths = mate.draft.intended_changes
|
|
1024
|
+
for row in authority.support.options:
|
|
1025
|
+
if any(
|
|
1026
|
+
_paths_overlap(left, right)
|
|
1027
|
+
for left in row.changed_paths
|
|
1028
|
+
for right in mate_paths
|
|
1029
|
+
):
|
|
1030
|
+
raise ValueError(
|
|
1031
|
+
"mate support overlaps an authenticated model-choice path"
|
|
1032
|
+
)
|
|
1033
|
+
|
|
1034
|
+
def _g2(self, state: OptimizerState) -> GenerationPlan:
|
|
1035
|
+
if self.wave is None or self.genesis is None or not self.g1_authorities:
|
|
1036
|
+
raise RuntimeError("G1 diagnostic authorities are unavailable")
|
|
1037
|
+
if self.closure is not None:
|
|
1038
|
+
raise RuntimeError("G2 memory checkpoint was already closed")
|
|
1039
|
+
roles = self._require_state(state)
|
|
1040
|
+
g1_receipt = state.generation_receipts[0]
|
|
1041
|
+
if tuple(value.slot.slot_id for value in g1_receipt.slot_results) != (
|
|
1042
|
+
MULTI_OPTION_G1_SLOT_IDS
|
|
1043
|
+
):
|
|
1044
|
+
raise ValueError("G1 slot order differs from the planner contract")
|
|
1045
|
+
self.closure = self._checkpoint_service.close_generation(
|
|
1046
|
+
self.wave,
|
|
1047
|
+
g1_receipt,
|
|
1048
|
+
)
|
|
1049
|
+
if self.closure.status is not MemoryCheckpointClosureStatus.SEALED:
|
|
1050
|
+
raise RuntimeError("G1 diagnostic wave was infrastructure-invalidated")
|
|
1051
|
+
snapshot = self.closure.snapshot
|
|
1052
|
+
if snapshot is None:
|
|
1053
|
+
raise RuntimeError("sealed G1 wave has no memory checkpoint")
|
|
1054
|
+
if any(not entry.identified for entry in snapshot.entries):
|
|
1055
|
+
raise ValueError("G1 did not identify both card effects")
|
|
1056
|
+
if len({entry.retrieval_score for entry in snapshot.entries}) != 2:
|
|
1057
|
+
raise ValueError(
|
|
1058
|
+
"G1 card scores tied; adaptive/shuffled arms are undefined"
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
decisions = (
|
|
1062
|
+
self.controls.adaptive(snapshot=snapshot, subset_size=1),
|
|
1063
|
+
self.controls.score_shuffled(
|
|
1064
|
+
snapshot=snapshot,
|
|
1065
|
+
subset_size=1,
|
|
1066
|
+
permutation_rank=self.shuffled_permutation_rank,
|
|
1067
|
+
),
|
|
1068
|
+
)
|
|
1069
|
+
if decisions[0].selected == decisions[1].selected:
|
|
1070
|
+
raise ValueError("score-shuffled control did not derange card selection")
|
|
1071
|
+
source_modes = (
|
|
1072
|
+
FiniteActionSourceMode.COMPILED_ACTIVE_CARD,
|
|
1073
|
+
FiniteActionSourceMode.COMPILED_SHUFFLED_CARD,
|
|
1074
|
+
)
|
|
1075
|
+
authorities: list[FiniteActionSetAuthority] = []
|
|
1076
|
+
assignments: list[ResolvedInsightAssignment] = []
|
|
1077
|
+
choice_plans: list[InvocationPlan] = []
|
|
1078
|
+
roles_text = ("adaptive_k_option_choice", "score_shuffled_k_option_choice")
|
|
1079
|
+
for index, (decision, source_mode) in enumerate(
|
|
1080
|
+
zip(decisions, source_modes, strict=True)
|
|
1081
|
+
):
|
|
1082
|
+
authority = self._compile_authority(
|
|
1083
|
+
parent=roles.evolution_parent,
|
|
1084
|
+
reference=decision.selected[0],
|
|
1085
|
+
source_mode=source_mode,
|
|
1086
|
+
)
|
|
1087
|
+
provisional = self._provisional_choice_plan(
|
|
1088
|
+
parent=roles.evolution_parent,
|
|
1089
|
+
generation=2,
|
|
1090
|
+
label=MULTI_OPTION_G2_SLOT_IDS[index],
|
|
1091
|
+
authority=authority,
|
|
1092
|
+
)
|
|
1093
|
+
plan, assignment = self._resolve_plan(
|
|
1094
|
+
provisional=provisional,
|
|
1095
|
+
snapshot=snapshot,
|
|
1096
|
+
arm=(
|
|
1097
|
+
MemoryAssignmentArm.ADAPTIVE
|
|
1098
|
+
if index == 0
|
|
1099
|
+
else MemoryAssignmentArm.SCORE_SHUFFLED_CONTROL
|
|
1100
|
+
),
|
|
1101
|
+
selection_decision=decision,
|
|
1102
|
+
block_id="multi_option_g2_matched_memory",
|
|
1103
|
+
)
|
|
1104
|
+
authorities.append(authority)
|
|
1105
|
+
assignments.append(assignment)
|
|
1106
|
+
choice_plans.append(plan)
|
|
1107
|
+
adaptive_authority, shuffled_authority = authorities
|
|
1108
|
+
self.g2_adaptive_authority = adaptive_authority
|
|
1109
|
+
self.g2_shuffled_authority = shuffled_authority
|
|
1110
|
+
self.g2_assignments = tuple(assignments)
|
|
1111
|
+
self.uniform_rank = self.uniform_policy.freeze_rank(
|
|
1112
|
+
adaptive_authority,
|
|
1113
|
+
task_sha256=self.task_sha256,
|
|
1114
|
+
pre_outcome_phase_commit_sha256=self.pre_outcome_phase_commit_sha256,
|
|
1115
|
+
)
|
|
1116
|
+
self.uniform_decision = self.uniform_policy.choose(
|
|
1117
|
+
EngineFiniteActionRequest(
|
|
1118
|
+
authority=adaptive_authority,
|
|
1119
|
+
prospective_rank=self.uniform_rank,
|
|
1120
|
+
)
|
|
1121
|
+
)
|
|
1122
|
+
uniform = materialized_finite_action_decision(
|
|
1123
|
+
ids=self.ids,
|
|
1124
|
+
parent=roles.evolution_parent,
|
|
1125
|
+
generation=2,
|
|
1126
|
+
label=MULTI_OPTION_G2_SLOT_IDS[2],
|
|
1127
|
+
authority=adaptive_authority,
|
|
1128
|
+
decision=self.uniform_decision,
|
|
1129
|
+
phase=f"{self.phase}.uniform",
|
|
1130
|
+
)
|
|
1131
|
+
mate = self._materialize_mate(parent=roles.evolution_parent)
|
|
1132
|
+
self._require_disjoint_support(adaptive_authority, mate)
|
|
1133
|
+
self._require_disjoint_support(shuffled_authority, mate)
|
|
1134
|
+
self.mate_invocation = mate
|
|
1135
|
+
audits = self._audit_choice_plans(tuple(choice_plans))
|
|
1136
|
+
model_slots = tuple(
|
|
1137
|
+
OptimizerSlot.model(
|
|
1138
|
+
slot_id=MULTI_OPTION_G2_SLOT_IDS[index],
|
|
1139
|
+
role=roles_text[index],
|
|
1140
|
+
plan=plan,
|
|
1141
|
+
)
|
|
1142
|
+
for index, plan in enumerate(choice_plans)
|
|
1143
|
+
)
|
|
1144
|
+
return GenerationPlan(
|
|
1145
|
+
generation=2,
|
|
1146
|
+
slots=(
|
|
1147
|
+
*model_slots,
|
|
1148
|
+
OptimizerSlot.engine(
|
|
1149
|
+
slot_id=MULTI_OPTION_G2_SLOT_IDS[2],
|
|
1150
|
+
role="prospective_uniform_same_adaptive_support",
|
|
1151
|
+
invocation=uniform,
|
|
1152
|
+
),
|
|
1153
|
+
OptimizerSlot.engine(
|
|
1154
|
+
slot_id=MULTI_OPTION_G2_SLOT_IDS[3],
|
|
1155
|
+
role="orthogonal_engine_mate",
|
|
1156
|
+
invocation=mate,
|
|
1157
|
+
),
|
|
1158
|
+
),
|
|
1159
|
+
reward=self._reward(state, 2),
|
|
1160
|
+
planner_policy_id=self.policy_id,
|
|
1161
|
+
planner_policy_version=self.policy_version,
|
|
1162
|
+
metadata=tuple(
|
|
1163
|
+
sorted(
|
|
1164
|
+
(
|
|
1165
|
+
(
|
|
1166
|
+
"adaptive_authority_sha256",
|
|
1167
|
+
adaptive_authority.authority_sha256,
|
|
1168
|
+
),
|
|
1169
|
+
(
|
|
1170
|
+
"adaptive_reference",
|
|
1171
|
+
assignments[0]
|
|
1172
|
+
.selection_decision.selected[0]
|
|
1173
|
+
.insight_id.value,
|
|
1174
|
+
),
|
|
1175
|
+
("mate_choice_sha256", self.mate_choice.choice_sha256),
|
|
1176
|
+
("memory_snapshot_sha256", snapshot.snapshot_sha256),
|
|
1177
|
+
(
|
|
1178
|
+
"score_shuffled_authority_sha256",
|
|
1179
|
+
shuffled_authority.authority_sha256,
|
|
1180
|
+
),
|
|
1181
|
+
*(
|
|
1182
|
+
(
|
|
1183
|
+
f"{slot_id}_effective_choice_audit_sha256",
|
|
1184
|
+
receipt.receipt_sha256,
|
|
1185
|
+
)
|
|
1186
|
+
for slot_id, receipt in zip(
|
|
1187
|
+
MULTI_OPTION_G2_SLOT_IDS[:2],
|
|
1188
|
+
audits,
|
|
1189
|
+
strict=True,
|
|
1190
|
+
)
|
|
1191
|
+
),
|
|
1192
|
+
(
|
|
1193
|
+
"uniform_decision_sha256",
|
|
1194
|
+
self.uniform_decision.decision_sha256,
|
|
1195
|
+
),
|
|
1196
|
+
("uniform_rank_sha256", self.uniform_rank.token_sha256),
|
|
1197
|
+
)
|
|
1198
|
+
)
|
|
1199
|
+
),
|
|
1200
|
+
)
|
|
1201
|
+
|
|
1202
|
+
@staticmethod
|
|
1203
|
+
def _require_model_choice(
|
|
1204
|
+
result: SlotResult,
|
|
1205
|
+
authority: FiniteActionSetAuthority,
|
|
1206
|
+
) -> EvolutionCandidate:
|
|
1207
|
+
outcome = result.outcome
|
|
1208
|
+
candidate = outcome.candidate
|
|
1209
|
+
decision = outcome.finite_action_decision
|
|
1210
|
+
if (
|
|
1211
|
+
result.slot.proposal_authority is not ProposalAuthority.MODEL
|
|
1212
|
+
or outcome.failure_stage is not None
|
|
1213
|
+
or candidate is None
|
|
1214
|
+
or not candidate.valid
|
|
1215
|
+
or not candidate.operator_compliant
|
|
1216
|
+
or not candidate.evidence_compliant
|
|
1217
|
+
or decision is None
|
|
1218
|
+
):
|
|
1219
|
+
raise ValueError("model K-choice endpoint did not complete successfully")
|
|
1220
|
+
if (
|
|
1221
|
+
result.slot.plan.finite_action_set_authority != authority
|
|
1222
|
+
or decision.authority_sha256 != authority.authority_sha256
|
|
1223
|
+
or decision.support_sha256 != authority.support.support_sha256
|
|
1224
|
+
or candidate.selected_insight_refs != (authority.card.reference,)
|
|
1225
|
+
or candidate.claimed_insight_ids
|
|
1226
|
+
!= (authority.card.reference.insight_id.value,)
|
|
1227
|
+
):
|
|
1228
|
+
raise ValueError("model K-choice endpoint escaped its finite authority")
|
|
1229
|
+
return candidate
|
|
1230
|
+
|
|
1231
|
+
@staticmethod
|
|
1232
|
+
def _require_engine_choice(
|
|
1233
|
+
result: SlotResult,
|
|
1234
|
+
invocation: MaterializedInvocation,
|
|
1235
|
+
) -> EvolutionCandidate:
|
|
1236
|
+
outcome = result.outcome
|
|
1237
|
+
candidate = outcome.candidate
|
|
1238
|
+
if (
|
|
1239
|
+
result.slot.proposal_authority is not ProposalAuthority.ENGINE
|
|
1240
|
+
or result.slot.materialized != invocation
|
|
1241
|
+
or outcome.failure_stage is not None
|
|
1242
|
+
or candidate is None
|
|
1243
|
+
or not candidate.valid
|
|
1244
|
+
or not candidate.operator_compliant
|
|
1245
|
+
or not candidate.evidence_compliant
|
|
1246
|
+
or candidate.candidate_id != invocation.candidate_id
|
|
1247
|
+
):
|
|
1248
|
+
raise ValueError("engine endpoint did not complete successfully")
|
|
1249
|
+
expected = freeze_json(invocation.draft.configuration)
|
|
1250
|
+
if not typed_json_equal(candidate.configuration, expected):
|
|
1251
|
+
raise ValueError("engine endpoint differs from its materialization")
|
|
1252
|
+
return candidate
|
|
1253
|
+
|
|
1254
|
+
def _union(
|
|
1255
|
+
self,
|
|
1256
|
+
*,
|
|
1257
|
+
ancestor: EvolutionCandidate,
|
|
1258
|
+
child: EvolutionCandidate,
|
|
1259
|
+
mate: EvolutionCandidate,
|
|
1260
|
+
slot_id: str,
|
|
1261
|
+
) -> MaterializedInvocation:
|
|
1262
|
+
materialization = self.recombiner.materialize(
|
|
1263
|
+
ancestor=ancestor.configuration,
|
|
1264
|
+
ancestor_candidate_id=ancestor.candidate_id,
|
|
1265
|
+
left=child.configuration,
|
|
1266
|
+
left_candidate_id=child.candidate_id,
|
|
1267
|
+
right=mate.configuration,
|
|
1268
|
+
right_candidate_id=mate.candidate_id,
|
|
1269
|
+
target_candidate_id=self.ids.new_candidate_id(),
|
|
1270
|
+
)
|
|
1271
|
+
return materialized_disjoint_invocation(
|
|
1272
|
+
plan=InvocationPlan(
|
|
1273
|
+
operator_kind=OperatorKind.THREE_WAY_RECOMBINATION,
|
|
1274
|
+
parents=(child, mate),
|
|
1275
|
+
generation=3,
|
|
1276
|
+
label=slot_id,
|
|
1277
|
+
common_ancestor=ancestor,
|
|
1278
|
+
phase=f"{self.phase}.disjoint_union",
|
|
1279
|
+
),
|
|
1280
|
+
materialization=materialization,
|
|
1281
|
+
)
|
|
1282
|
+
|
|
1283
|
+
def _g3(self, state: OptimizerState) -> GenerationPlan:
|
|
1284
|
+
if (
|
|
1285
|
+
self.g2_adaptive_authority is None
|
|
1286
|
+
or self.g2_shuffled_authority is None
|
|
1287
|
+
or self.uniform_decision is None
|
|
1288
|
+
or self.mate_invocation is None
|
|
1289
|
+
):
|
|
1290
|
+
raise RuntimeError("G2 finite-choice authorities are unavailable")
|
|
1291
|
+
roles = self._require_state(state)
|
|
1292
|
+
g2_receipt = state.generation_receipts[1]
|
|
1293
|
+
if tuple(value.slot.slot_id for value in g2_receipt.slot_results) != (
|
|
1294
|
+
MULTI_OPTION_G2_SLOT_IDS
|
|
1295
|
+
):
|
|
1296
|
+
raise ValueError("G2 slot order differs from the planner contract")
|
|
1297
|
+
adaptive = self._require_model_choice(
|
|
1298
|
+
g2_receipt.slot_results[0],
|
|
1299
|
+
self.g2_adaptive_authority,
|
|
1300
|
+
)
|
|
1301
|
+
shuffled = self._require_model_choice(
|
|
1302
|
+
g2_receipt.slot_results[1],
|
|
1303
|
+
self.g2_shuffled_authority,
|
|
1304
|
+
)
|
|
1305
|
+
uniform_invocation = g2_receipt.slot_results[2].slot.materialized
|
|
1306
|
+
if uniform_invocation is None:
|
|
1307
|
+
raise RuntimeError("G2 uniform materialization disappeared")
|
|
1308
|
+
uniform = self._require_engine_choice(
|
|
1309
|
+
g2_receipt.slot_results[2],
|
|
1310
|
+
uniform_invocation,
|
|
1311
|
+
)
|
|
1312
|
+
mate = self._require_engine_choice(
|
|
1313
|
+
g2_receipt.slot_results[3],
|
|
1314
|
+
self.mate_invocation,
|
|
1315
|
+
)
|
|
1316
|
+
reproduction = InvocationPlan(
|
|
1317
|
+
operator_kind=OperatorKind.REPRODUCTION,
|
|
1318
|
+
parents=(roles.evolution_parent,),
|
|
1319
|
+
generation=3,
|
|
1320
|
+
label=MULTI_OPTION_G3_CORE_SLOT_IDS[0],
|
|
1321
|
+
phase=f"{self.phase}.reproduction",
|
|
1322
|
+
)
|
|
1323
|
+
unions = tuple(
|
|
1324
|
+
self._union(
|
|
1325
|
+
ancestor=roles.evolution_parent,
|
|
1326
|
+
child=child,
|
|
1327
|
+
mate=mate,
|
|
1328
|
+
slot_id=slot_id,
|
|
1329
|
+
)
|
|
1330
|
+
for child, slot_id in zip(
|
|
1331
|
+
(adaptive, shuffled, uniform),
|
|
1332
|
+
MULTI_OPTION_G3_CORE_SLOT_IDS[1:],
|
|
1333
|
+
strict=True,
|
|
1334
|
+
)
|
|
1335
|
+
)
|
|
1336
|
+
known_by_sha256 = {
|
|
1337
|
+
typed_json_sha256(candidate.configuration): candidate.configuration
|
|
1338
|
+
for candidate in state.candidates
|
|
1339
|
+
}
|
|
1340
|
+
for union in unions:
|
|
1341
|
+
target = freeze_json(union.draft.configuration)
|
|
1342
|
+
if type(target) is not FrozenJsonObject:
|
|
1343
|
+
raise TypeError("scheduled union must materialize an object target")
|
|
1344
|
+
known_by_sha256.setdefault(typed_json_sha256(target), target)
|
|
1345
|
+
known_targets = tuple(
|
|
1346
|
+
known_by_sha256[digest] for digest in sorted(known_by_sha256)
|
|
1347
|
+
)
|
|
1348
|
+
crossover_plans = self.crossover_policy.plans(
|
|
1349
|
+
adaptive=adaptive,
|
|
1350
|
+
shuffled=shuffled,
|
|
1351
|
+
uniform=uniform,
|
|
1352
|
+
mate=mate,
|
|
1353
|
+
phase=self.phase,
|
|
1354
|
+
known_targets=known_targets,
|
|
1355
|
+
)
|
|
1356
|
+
if (
|
|
1357
|
+
type(crossover_plans) is not tuple
|
|
1358
|
+
or len(crossover_plans) != len(self.crossover_policy.slot_ids)
|
|
1359
|
+
or tuple(value.label for value in crossover_plans)
|
|
1360
|
+
!= self.crossover_policy.slot_ids
|
|
1361
|
+
):
|
|
1362
|
+
raise ValueError("crossover policy plans differ from its frozen slot IDs")
|
|
1363
|
+
for plan in crossover_plans:
|
|
1364
|
+
if (
|
|
1365
|
+
type(plan) is not InvocationPlan
|
|
1366
|
+
or plan.operator_kind is not OperatorKind.TWO_PARENT_CROSSOVER
|
|
1367
|
+
or plan.generation != 3
|
|
1368
|
+
or plan.use_memory
|
|
1369
|
+
or plan.quarantine_test_insights
|
|
1370
|
+
or plan.resolved_insight_assignment is not None
|
|
1371
|
+
or plan.insight_treatment_requirement is not None
|
|
1372
|
+
or plan.finite_action_set_authority is not None
|
|
1373
|
+
):
|
|
1374
|
+
raise ValueError(
|
|
1375
|
+
"terminal crossover extensions must be memory-free model plans"
|
|
1376
|
+
)
|
|
1377
|
+
self.g3_union_materialization_receipt_sha256s = tuple(
|
|
1378
|
+
value.materialization_receipt_hash for value in unions
|
|
1379
|
+
)
|
|
1380
|
+
return GenerationPlan(
|
|
1381
|
+
generation=3,
|
|
1382
|
+
slots=(
|
|
1383
|
+
OptimizerSlot.reproduction(
|
|
1384
|
+
slot_id=MULTI_OPTION_G3_CORE_SLOT_IDS[0],
|
|
1385
|
+
role="evolution_parent_reproduction",
|
|
1386
|
+
plan=reproduction,
|
|
1387
|
+
),
|
|
1388
|
+
*(
|
|
1389
|
+
OptimizerSlot.engine(
|
|
1390
|
+
slot_id=slot_id,
|
|
1391
|
+
role="deterministic_disjoint_union",
|
|
1392
|
+
invocation=invocation,
|
|
1393
|
+
)
|
|
1394
|
+
for slot_id, invocation in zip(
|
|
1395
|
+
MULTI_OPTION_G3_CORE_SLOT_IDS[1:],
|
|
1396
|
+
unions,
|
|
1397
|
+
strict=True,
|
|
1398
|
+
)
|
|
1399
|
+
),
|
|
1400
|
+
*(
|
|
1401
|
+
OptimizerSlot.model(
|
|
1402
|
+
slot_id=slot_id,
|
|
1403
|
+
role="model_selected_exact_parent_crossover",
|
|
1404
|
+
plan=plan,
|
|
1405
|
+
)
|
|
1406
|
+
for slot_id, plan in zip(
|
|
1407
|
+
self.crossover_policy.slot_ids,
|
|
1408
|
+
crossover_plans,
|
|
1409
|
+
strict=True,
|
|
1410
|
+
)
|
|
1411
|
+
),
|
|
1412
|
+
),
|
|
1413
|
+
reward=self._reward(state, 3),
|
|
1414
|
+
planner_policy_id=self.policy_id,
|
|
1415
|
+
planner_policy_version=self.policy_version,
|
|
1416
|
+
metadata=tuple(
|
|
1417
|
+
sorted(
|
|
1418
|
+
(
|
|
1419
|
+
(
|
|
1420
|
+
"adaptive_reference",
|
|
1421
|
+
self.adaptive_reference.insight_id.value,
|
|
1422
|
+
),
|
|
1423
|
+
*(
|
|
1424
|
+
(
|
|
1425
|
+
f"{slot_id}_materialization_receipt_sha256",
|
|
1426
|
+
invocation.materialization_receipt_hash,
|
|
1427
|
+
)
|
|
1428
|
+
for slot_id, invocation in zip(
|
|
1429
|
+
MULTI_OPTION_G3_CORE_SLOT_IDS[1:],
|
|
1430
|
+
unions,
|
|
1431
|
+
strict=True,
|
|
1432
|
+
)
|
|
1433
|
+
),
|
|
1434
|
+
(
|
|
1435
|
+
"crossover_policy_definition_sha256",
|
|
1436
|
+
self.crossover_policy.definition_sha256,
|
|
1437
|
+
),
|
|
1438
|
+
)
|
|
1439
|
+
)
|
|
1440
|
+
),
|
|
1441
|
+
)
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
@dataclass(frozen=True, slots=True)
|
|
1445
|
+
class MultiOptionEvolutionPlannerFactory:
|
|
1446
|
+
"""Deferred composition seam for benchmark and runtime dependencies."""
|
|
1447
|
+
|
|
1448
|
+
reward_binding: RewardPolicyBinding
|
|
1449
|
+
active_references: tuple[InsightRef, InsightRef]
|
|
1450
|
+
model_catalog_id: str
|
|
1451
|
+
mate_catalog_id: str
|
|
1452
|
+
mate_choice: ParentBoundFiniteChoice
|
|
1453
|
+
required_cardinality: int
|
|
1454
|
+
uniform_policy: EngineFiniteActionPolicy
|
|
1455
|
+
task_sha256: str
|
|
1456
|
+
pre_outcome_phase_commit_sha256: str
|
|
1457
|
+
endpoint_definition_sha256: str
|
|
1458
|
+
context_projection_sha256: str
|
|
1459
|
+
estimand_stratum_sha256: str
|
|
1460
|
+
phase: str = "multi_option_evolution"
|
|
1461
|
+
diagnostic_subset_ranks: tuple[int, int] = (0, 1)
|
|
1462
|
+
shuffled_permutation_rank: int = 1
|
|
1463
|
+
score_policy: CausalSearchScorePolicy = field(
|
|
1464
|
+
default_factory=lambda: CausalSearchScorePolicy(
|
|
1465
|
+
prior_effective_sample_size=1.0,
|
|
1466
|
+
uncertainty_scale=0.0,
|
|
1467
|
+
exploration_weight=0.0,
|
|
1468
|
+
)
|
|
1469
|
+
)
|
|
1470
|
+
controls: DeterministicMemoryControlPolicy = field(
|
|
1471
|
+
default_factory=DeterministicMemoryControlPolicy
|
|
1472
|
+
)
|
|
1473
|
+
seed_role_policy: SeedRolePolicy = field(default_factory=OrderedTwoSeedRolePolicy)
|
|
1474
|
+
recombiner: DisjointPatchRecombiner = field(default_factory=DisjointPatchRecombiner)
|
|
1475
|
+
crossover_policy: G3CrossoverPlanPolicy = field(
|
|
1476
|
+
default_factory=AdaptiveShuffledMateCrossoverPolicy
|
|
1477
|
+
)
|
|
1478
|
+
trace_sink: object | None = None
|
|
1479
|
+
|
|
1480
|
+
def build(
|
|
1481
|
+
self,
|
|
1482
|
+
*,
|
|
1483
|
+
benchmark: MultiOptionEvolutionBenchmark,
|
|
1484
|
+
engine: AgenticEvolutionEngine,
|
|
1485
|
+
id_factory: IdFactory,
|
|
1486
|
+
memory: InsightMemoryBank,
|
|
1487
|
+
) -> MultiOptionEvolutionPlanner:
|
|
1488
|
+
return MultiOptionEvolutionPlanner(
|
|
1489
|
+
benchmark=benchmark,
|
|
1490
|
+
engine=engine,
|
|
1491
|
+
ids=id_factory,
|
|
1492
|
+
memory=memory,
|
|
1493
|
+
reward_binding=self.reward_binding,
|
|
1494
|
+
active_references=self.active_references,
|
|
1495
|
+
model_catalog_id=self.model_catalog_id,
|
|
1496
|
+
mate_catalog_id=self.mate_catalog_id,
|
|
1497
|
+
mate_choice=self.mate_choice,
|
|
1498
|
+
required_cardinality=self.required_cardinality,
|
|
1499
|
+
uniform_policy=self.uniform_policy,
|
|
1500
|
+
task_sha256=self.task_sha256,
|
|
1501
|
+
pre_outcome_phase_commit_sha256=(self.pre_outcome_phase_commit_sha256),
|
|
1502
|
+
endpoint_definition_sha256=self.endpoint_definition_sha256,
|
|
1503
|
+
context_projection_sha256=self.context_projection_sha256,
|
|
1504
|
+
estimand_stratum_sha256=self.estimand_stratum_sha256,
|
|
1505
|
+
phase=self.phase,
|
|
1506
|
+
diagnostic_subset_ranks=self.diagnostic_subset_ranks,
|
|
1507
|
+
shuffled_permutation_rank=self.shuffled_permutation_rank,
|
|
1508
|
+
score_policy=self.score_policy,
|
|
1509
|
+
controls=self.controls,
|
|
1510
|
+
seed_role_policy=self.seed_role_policy,
|
|
1511
|
+
recombiner=self.recombiner,
|
|
1512
|
+
crossover_policy=self.crossover_policy,
|
|
1513
|
+
trace_sink=self.trace_sink,
|
|
1514
|
+
)
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
__all__ = [
|
|
1518
|
+
"AdaptiveShuffledMateCrossoverPolicy",
|
|
1519
|
+
"G3CrossoverPlanPolicy",
|
|
1520
|
+
"MULTI_OPTION_EVOLUTION_BUDGET",
|
|
1521
|
+
"MULTI_OPTION_EVOLUTION_POLICY_ID",
|
|
1522
|
+
"MULTI_OPTION_EVOLUTION_POLICY_VERSION",
|
|
1523
|
+
"MULTI_OPTION_G1_SLOT_IDS",
|
|
1524
|
+
"MULTI_OPTION_G2_SLOT_IDS",
|
|
1525
|
+
"MULTI_OPTION_G3_CORE_SLOT_IDS",
|
|
1526
|
+
"MULTI_OPTION_G3_CROSSOVER_SLOT_IDS",
|
|
1527
|
+
"MULTI_OPTION_G3_SLOT_IDS",
|
|
1528
|
+
"MULTI_OPTION_G3_UNION_SOURCES",
|
|
1529
|
+
"MultiOptionEvolutionBenchmark",
|
|
1530
|
+
"MultiOptionEvolutionPlanner",
|
|
1531
|
+
"MultiOptionEvolutionPlannerFactory",
|
|
1532
|
+
"OrderedTwoSeedRolePolicy",
|
|
1533
|
+
"ParentBoundFiniteChoice",
|
|
1534
|
+
"SeedRolePolicy",
|
|
1535
|
+
"SeedRoleSelection",
|
|
1536
|
+
]
|