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,575 @@
|
|
|
1
|
+
"""Executable, benchmark-neutral two-parent crossover inheritance.
|
|
2
|
+
|
|
3
|
+
Model-authored crossover output contains two different kinds of information:
|
|
4
|
+
|
|
5
|
+
* an inheritance plan (candidate-relative paths attributed to the left or
|
|
6
|
+
right parent), and
|
|
7
|
+
* explicitly synthesized values.
|
|
8
|
+
|
|
9
|
+
An inherited value is not model authority. This service verifies the plan and
|
|
10
|
+
copies the exact immutable subtree from the named parent. The model's value at
|
|
11
|
+
that path is retained only as a consistency witness. Exact typed-JSON equality
|
|
12
|
+
is required except for finite binary64 leaves that differ by at most one ULP,
|
|
13
|
+
which covers decimal spelling versus arithmetic-rounding drift without turning
|
|
14
|
+
the boundary into an optimization tolerance.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
import json
|
|
21
|
+
import struct
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
from enum import Enum
|
|
24
|
+
|
|
25
|
+
from agent_evolve.domain.patch import (
|
|
26
|
+
ArrayIndex,
|
|
27
|
+
JsonPath,
|
|
28
|
+
ObjectKey,
|
|
29
|
+
canonical_path_bytes,
|
|
30
|
+
)
|
|
31
|
+
from agent_evolve.domain.typed_json import (
|
|
32
|
+
FrozenJsonArray,
|
|
33
|
+
FrozenJsonObject,
|
|
34
|
+
FrozenJsonValue,
|
|
35
|
+
freeze_json,
|
|
36
|
+
typed_json_equal,
|
|
37
|
+
typed_json_sha256,
|
|
38
|
+
)
|
|
39
|
+
from agent_evolve.policies.variation.typed_patch import (
|
|
40
|
+
replace_existing_path,
|
|
41
|
+
value_at_path,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
_RECEIPT_DOMAIN = b"agent-evolve:crossover-inheritance-materialization:v1\x00"
|
|
46
|
+
_MISSING = object()
|
|
47
|
+
_BINARY64_SIGN_BIT = 1 << 63
|
|
48
|
+
_BINARY64_MASK = (1 << 64) - 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class CrossoverInheritanceSource(str, Enum):
|
|
52
|
+
"""Closed source vocabulary for executable crossover claims."""
|
|
53
|
+
|
|
54
|
+
LEFT = "left"
|
|
55
|
+
RIGHT = "right"
|
|
56
|
+
SYNTHESIZED = "synthesized"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True, slots=True)
|
|
60
|
+
class CrossoverInheritanceClaim:
|
|
61
|
+
"""One exact candidate-relative component claim."""
|
|
62
|
+
|
|
63
|
+
path: str
|
|
64
|
+
source: CrossoverInheritanceSource
|
|
65
|
+
|
|
66
|
+
def __post_init__(self) -> None:
|
|
67
|
+
if type(self.path) is not str or not self.path.startswith("$."):
|
|
68
|
+
raise ValueError("crossover claim path must be a non-root canonical path")
|
|
69
|
+
if type(self.source) is not CrossoverInheritanceSource:
|
|
70
|
+
raise TypeError("crossover claim source must be closed and exact")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True, slots=True)
|
|
74
|
+
class InheritedPathMaterializationEvidence:
|
|
75
|
+
"""Hash-only evidence for one exact parent-subtree copy."""
|
|
76
|
+
|
|
77
|
+
path: str
|
|
78
|
+
source: CrossoverInheritanceSource
|
|
79
|
+
witness_value_sha256: str
|
|
80
|
+
parent_value_sha256: str
|
|
81
|
+
witness_exact: bool
|
|
82
|
+
adjusted_float_leaf_count: int
|
|
83
|
+
max_float_ulp_distance: int
|
|
84
|
+
|
|
85
|
+
def to_record(self) -> dict[str, object]:
|
|
86
|
+
return {
|
|
87
|
+
"path": self.path,
|
|
88
|
+
"source": self.source.value,
|
|
89
|
+
"witness_value_sha256": self.witness_value_sha256,
|
|
90
|
+
"parent_value_sha256": self.parent_value_sha256,
|
|
91
|
+
"witness_exact": self.witness_exact,
|
|
92
|
+
"adjusted_float_leaf_count": self.adjusted_float_leaf_count,
|
|
93
|
+
"max_float_ulp_distance": self.max_float_ulp_distance,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass(frozen=True, slots=True)
|
|
98
|
+
class SynthesizedPathEvidence:
|
|
99
|
+
"""Hash-only evidence for one explicitly model-authored component."""
|
|
100
|
+
|
|
101
|
+
path: str
|
|
102
|
+
witness_value_sha256: str
|
|
103
|
+
left_value_sha256: str | None
|
|
104
|
+
right_value_sha256: str | None
|
|
105
|
+
|
|
106
|
+
def to_record(self) -> dict[str, object]:
|
|
107
|
+
return {
|
|
108
|
+
"path": self.path,
|
|
109
|
+
"witness_value_sha256": self.witness_value_sha256,
|
|
110
|
+
"left_value_sha256": self.left_value_sha256,
|
|
111
|
+
"right_value_sha256": self.right_value_sha256,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass(frozen=True, slots=True)
|
|
116
|
+
class CrossoverInheritanceMaterialization:
|
|
117
|
+
"""Exact child plus replay-visible materialization evidence."""
|
|
118
|
+
|
|
119
|
+
configuration: FrozenJsonObject
|
|
120
|
+
draft_configuration_sha256: str
|
|
121
|
+
materialized_configuration_sha256: str
|
|
122
|
+
inherited_paths: tuple[InheritedPathMaterializationEvidence, ...]
|
|
123
|
+
synthesized_paths: tuple[SynthesizedPathEvidence, ...]
|
|
124
|
+
|
|
125
|
+
def to_record(self) -> dict[str, object]:
|
|
126
|
+
return {
|
|
127
|
+
"schema_version": 1,
|
|
128
|
+
"materialization_policy": "exact_named_parent_subtree_copy_v1",
|
|
129
|
+
"witness_consistency_policy": (
|
|
130
|
+
"typed_json_exact_or_one_finite_binary64_ulp_per_float_leaf_v1"
|
|
131
|
+
),
|
|
132
|
+
"attribution_policy": "exhaustive_nonoverlapping_component_plan_v1",
|
|
133
|
+
"draft_configuration_sha256": self.draft_configuration_sha256,
|
|
134
|
+
"materialized_configuration_sha256": (
|
|
135
|
+
self.materialized_configuration_sha256
|
|
136
|
+
),
|
|
137
|
+
"inherited_paths": [item.to_record() for item in self.inherited_paths],
|
|
138
|
+
"synthesized_paths": [
|
|
139
|
+
item.to_record() for item in self.synthesized_paths
|
|
140
|
+
],
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def receipt_sha256(self) -> str:
|
|
145
|
+
encoded = json.dumps(
|
|
146
|
+
self.to_record(),
|
|
147
|
+
allow_nan=False,
|
|
148
|
+
ensure_ascii=True,
|
|
149
|
+
separators=(",", ":"),
|
|
150
|
+
sort_keys=True,
|
|
151
|
+
).encode("ascii", errors="strict")
|
|
152
|
+
return hashlib.sha256(_RECEIPT_DOMAIN + encoded).hexdigest()
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _path_text(path: JsonPath) -> str:
|
|
156
|
+
parts = ["$"]
|
|
157
|
+
for segment in path.segments:
|
|
158
|
+
if type(segment) is ObjectKey:
|
|
159
|
+
parts.append(f".{segment.value}")
|
|
160
|
+
elif type(segment) is ArrayIndex:
|
|
161
|
+
parts.append(f"[{segment.value}]")
|
|
162
|
+
else: # pragma: no cover - JsonPath closes the union.
|
|
163
|
+
raise AssertionError("unsupported path segment")
|
|
164
|
+
return "".join(parts)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _path_index(
|
|
168
|
+
root: FrozenJsonValue,
|
|
169
|
+
) -> tuple[dict[str, JsonPath], frozenset[str]]:
|
|
170
|
+
"""Index canonical display paths and surface any ambiguous spelling."""
|
|
171
|
+
|
|
172
|
+
values: dict[str, JsonPath] = {}
|
|
173
|
+
ambiguous: set[str] = set()
|
|
174
|
+
|
|
175
|
+
def visit(value: FrozenJsonValue, path: JsonPath) -> None:
|
|
176
|
+
if path.segments:
|
|
177
|
+
text = _path_text(path)
|
|
178
|
+
prior = values.get(text)
|
|
179
|
+
if prior is not None and canonical_path_bytes(prior) != canonical_path_bytes(
|
|
180
|
+
path
|
|
181
|
+
):
|
|
182
|
+
ambiguous.add(text)
|
|
183
|
+
else:
|
|
184
|
+
values[text] = path
|
|
185
|
+
if type(value) is FrozenJsonObject:
|
|
186
|
+
for key, child in value.items:
|
|
187
|
+
visit(child, path.child_key(key))
|
|
188
|
+
elif type(value) is FrozenJsonArray:
|
|
189
|
+
for index, child in enumerate(value.items):
|
|
190
|
+
visit(child, path.child_index(index))
|
|
191
|
+
|
|
192
|
+
visit(root, JsonPath())
|
|
193
|
+
return values, frozenset(ambiguous)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _witness_equivalence(
|
|
197
|
+
witness: FrozenJsonValue,
|
|
198
|
+
parent: FrozenJsonValue,
|
|
199
|
+
) -> tuple[bool, int, int]:
|
|
200
|
+
"""Return exact/one-ULP structural consistency evidence.
|
|
201
|
+
|
|
202
|
+
The integer fields are adjusted float-leaf count and maximum ULP distance.
|
|
203
|
+
They are zero for exact typed-JSON equality and at most one otherwise.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
if typed_json_equal(witness, parent):
|
|
207
|
+
return True, 0, 0
|
|
208
|
+
if type(witness) is not type(parent):
|
|
209
|
+
return False, 0, 0
|
|
210
|
+
if type(witness) is float:
|
|
211
|
+
assert type(parent) is float
|
|
212
|
+
# Finite values are guaranteed by the frozen typed-JSON boundary. Do
|
|
213
|
+
# not collapse signed zero: it has an intentional exact typed identity.
|
|
214
|
+
if witness == 0.0 and parent == 0.0:
|
|
215
|
+
return False, 0, 0
|
|
216
|
+
witness_bits = int.from_bytes(struct.pack(">d", witness), "big")
|
|
217
|
+
parent_bits = int.from_bytes(struct.pack(">d", parent), "big")
|
|
218
|
+
|
|
219
|
+
def ordered(bits: int) -> int:
|
|
220
|
+
if bits & _BINARY64_SIGN_BIT:
|
|
221
|
+
return (~bits) & _BINARY64_MASK
|
|
222
|
+
return bits | _BINARY64_SIGN_BIT
|
|
223
|
+
|
|
224
|
+
if abs(ordered(witness_bits) - ordered(parent_bits)) == 1:
|
|
225
|
+
return True, 1, 1
|
|
226
|
+
return False, 0, 0
|
|
227
|
+
if type(witness) is FrozenJsonArray:
|
|
228
|
+
assert type(parent) is FrozenJsonArray
|
|
229
|
+
if len(witness.items) != len(parent.items):
|
|
230
|
+
return False, 0, 0
|
|
231
|
+
adjusted = 0
|
|
232
|
+
maximum = 0
|
|
233
|
+
for witness_item, parent_item in zip(
|
|
234
|
+
witness.items, parent.items, strict=True
|
|
235
|
+
):
|
|
236
|
+
equivalent, item_adjusted, item_maximum = _witness_equivalence(
|
|
237
|
+
witness_item, parent_item
|
|
238
|
+
)
|
|
239
|
+
if not equivalent:
|
|
240
|
+
return False, 0, 0
|
|
241
|
+
adjusted += item_adjusted
|
|
242
|
+
maximum = max(maximum, item_maximum)
|
|
243
|
+
return True, adjusted, maximum
|
|
244
|
+
if type(witness) is FrozenJsonObject:
|
|
245
|
+
assert type(parent) is FrozenJsonObject
|
|
246
|
+
if tuple(key for key, _ in witness.items) != tuple(
|
|
247
|
+
key for key, _ in parent.items
|
|
248
|
+
):
|
|
249
|
+
return False, 0, 0
|
|
250
|
+
adjusted = 0
|
|
251
|
+
maximum = 0
|
|
252
|
+
for (_, witness_item), (_, parent_item) in zip(
|
|
253
|
+
witness.items, parent.items, strict=True
|
|
254
|
+
):
|
|
255
|
+
equivalent, item_adjusted, item_maximum = _witness_equivalence(
|
|
256
|
+
witness_item, parent_item
|
|
257
|
+
)
|
|
258
|
+
if not equivalent:
|
|
259
|
+
return False, 0, 0
|
|
260
|
+
adjusted += item_adjusted
|
|
261
|
+
maximum = max(maximum, item_maximum)
|
|
262
|
+
return True, adjusted, maximum
|
|
263
|
+
return False, 0, 0
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def _optional_equal(left: object, right: object) -> bool:
|
|
267
|
+
if left is _MISSING or right is _MISSING:
|
|
268
|
+
return left is right
|
|
269
|
+
return typed_json_equal(left, right)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _audit_exhaustive_plan(
|
|
273
|
+
left: FrozenJsonObject,
|
|
274
|
+
right: FrozenJsonObject,
|
|
275
|
+
child: FrozenJsonObject,
|
|
276
|
+
claims_by_path: dict[bytes, CrossoverInheritanceClaim],
|
|
277
|
+
) -> None:
|
|
278
|
+
"""Require every parent/child difference to have one exact source claim."""
|
|
279
|
+
|
|
280
|
+
consumed: set[bytes] = set()
|
|
281
|
+
|
|
282
|
+
def visit(
|
|
283
|
+
left_value: FrozenJsonValue | object,
|
|
284
|
+
right_value: FrozenJsonValue | object,
|
|
285
|
+
child_value: FrozenJsonValue | object,
|
|
286
|
+
path: JsonPath,
|
|
287
|
+
) -> None:
|
|
288
|
+
encoded_path = canonical_path_bytes(path)
|
|
289
|
+
claim = claims_by_path.get(encoded_path)
|
|
290
|
+
if claim is not None:
|
|
291
|
+
consumed.add(encoded_path)
|
|
292
|
+
if child_value is _MISSING:
|
|
293
|
+
raise ValueError("crossover claim path is absent from the child")
|
|
294
|
+
if claim.source is CrossoverInheritanceSource.LEFT:
|
|
295
|
+
if left_value is _MISSING or right_value is _MISSING:
|
|
296
|
+
raise ValueError("left inheritance path is absent from a parent")
|
|
297
|
+
if _optional_equal(left_value, right_value) or not _optional_equal(
|
|
298
|
+
child_value, left_value
|
|
299
|
+
):
|
|
300
|
+
raise ValueError("left inheritance claim is not discriminating")
|
|
301
|
+
elif claim.source is CrossoverInheritanceSource.RIGHT:
|
|
302
|
+
if left_value is _MISSING or right_value is _MISSING:
|
|
303
|
+
raise ValueError("right inheritance path is absent from a parent")
|
|
304
|
+
if _optional_equal(left_value, right_value) or not _optional_equal(
|
|
305
|
+
child_value, right_value
|
|
306
|
+
):
|
|
307
|
+
raise ValueError("right inheritance claim is not discriminating")
|
|
308
|
+
else:
|
|
309
|
+
if _optional_equal(child_value, left_value) or _optional_equal(
|
|
310
|
+
child_value, right_value
|
|
311
|
+
):
|
|
312
|
+
raise ValueError(
|
|
313
|
+
"synthesized claim must differ from both parent values"
|
|
314
|
+
)
|
|
315
|
+
return
|
|
316
|
+
|
|
317
|
+
if child_value is _MISSING:
|
|
318
|
+
# Absence is a child value, not preservation. In particular, an
|
|
319
|
+
# identically shared parent member cannot silently disappear just
|
|
320
|
+
# because neither parent discriminates it. Since claims name
|
|
321
|
+
# paths that exist in the child, a structural deletion must be
|
|
322
|
+
# claimed as synthesis at a retained containing object/array.
|
|
323
|
+
if _optional_equal(left_value, right_value):
|
|
324
|
+
raise ValueError(
|
|
325
|
+
"crossover omits a shared component without synthesized "
|
|
326
|
+
"container attribution"
|
|
327
|
+
)
|
|
328
|
+
raise ValueError("crossover omits a discriminating component without a claim")
|
|
329
|
+
|
|
330
|
+
if (
|
|
331
|
+
type(left_value) is FrozenJsonObject
|
|
332
|
+
and type(right_value) is FrozenJsonObject
|
|
333
|
+
and type(child_value) is FrozenJsonObject
|
|
334
|
+
):
|
|
335
|
+
left_items = dict(left_value.items)
|
|
336
|
+
right_items = dict(right_value.items)
|
|
337
|
+
child_items = dict(child_value.items)
|
|
338
|
+
for key in sorted(
|
|
339
|
+
set(left_items) | set(right_items) | set(child_items),
|
|
340
|
+
key=lambda item: item.encode("utf-8", errors="strict"),
|
|
341
|
+
):
|
|
342
|
+
visit(
|
|
343
|
+
left_items.get(key, _MISSING),
|
|
344
|
+
right_items.get(key, _MISSING),
|
|
345
|
+
child_items.get(key, _MISSING),
|
|
346
|
+
path.child_key(key),
|
|
347
|
+
)
|
|
348
|
+
return
|
|
349
|
+
|
|
350
|
+
if (
|
|
351
|
+
type(left_value) is FrozenJsonArray
|
|
352
|
+
and type(right_value) is FrozenJsonArray
|
|
353
|
+
and type(child_value) is FrozenJsonArray
|
|
354
|
+
and len(left_value.items)
|
|
355
|
+
== len(right_value.items)
|
|
356
|
+
== len(child_value.items)
|
|
357
|
+
):
|
|
358
|
+
for index, (left_item, right_item, child_item) in enumerate(
|
|
359
|
+
zip(
|
|
360
|
+
left_value.items,
|
|
361
|
+
right_value.items,
|
|
362
|
+
child_value.items,
|
|
363
|
+
strict=True,
|
|
364
|
+
)
|
|
365
|
+
):
|
|
366
|
+
visit(
|
|
367
|
+
left_item,
|
|
368
|
+
right_item,
|
|
369
|
+
child_item,
|
|
370
|
+
path.child_index(index),
|
|
371
|
+
)
|
|
372
|
+
return
|
|
373
|
+
|
|
374
|
+
if _optional_equal(left_value, right_value):
|
|
375
|
+
if not _optional_equal(child_value, left_value):
|
|
376
|
+
raise ValueError(
|
|
377
|
+
"crossover synthesized a component without explicit attribution"
|
|
378
|
+
)
|
|
379
|
+
return
|
|
380
|
+
if _optional_equal(child_value, left_value):
|
|
381
|
+
raise ValueError("crossover inherited a left component without attribution")
|
|
382
|
+
if _optional_equal(child_value, right_value):
|
|
383
|
+
raise ValueError("crossover inherited a right component without attribution")
|
|
384
|
+
raise ValueError("crossover synthesized a component without explicit attribution")
|
|
385
|
+
|
|
386
|
+
visit(left, right, child, JsonPath())
|
|
387
|
+
if consumed != set(claims_by_path):
|
|
388
|
+
raise ValueError("crossover plan contains an unreachable component claim")
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def materialize_crossover_inheritance(
|
|
392
|
+
*,
|
|
393
|
+
left: object,
|
|
394
|
+
right: object,
|
|
395
|
+
draft: object,
|
|
396
|
+
claims: tuple[CrossoverInheritanceClaim, ...],
|
|
397
|
+
) -> CrossoverInheritanceMaterialization:
|
|
398
|
+
"""Verify an executable inheritance plan and materialize its exact child."""
|
|
399
|
+
|
|
400
|
+
frozen_left = freeze_json(left)
|
|
401
|
+
frozen_right = freeze_json(right)
|
|
402
|
+
frozen_draft = freeze_json(draft)
|
|
403
|
+
if any(
|
|
404
|
+
type(value) is not FrozenJsonObject
|
|
405
|
+
for value in (frozen_left, frozen_right, frozen_draft)
|
|
406
|
+
):
|
|
407
|
+
raise TypeError("two-parent crossover roots must be exact JSON objects")
|
|
408
|
+
assert type(frozen_left) is FrozenJsonObject
|
|
409
|
+
assert type(frozen_right) is FrozenJsonObject
|
|
410
|
+
assert type(frozen_draft) is FrozenJsonObject
|
|
411
|
+
if type(claims) is not tuple or any(
|
|
412
|
+
type(claim) is not CrossoverInheritanceClaim for claim in claims
|
|
413
|
+
):
|
|
414
|
+
raise TypeError("crossover claims must be an exact tuple of exact claims")
|
|
415
|
+
for claim in claims:
|
|
416
|
+
CrossoverInheritanceClaim.__post_init__(claim)
|
|
417
|
+
if not claims:
|
|
418
|
+
raise ValueError("two-parent crossover requires an executable source plan")
|
|
419
|
+
|
|
420
|
+
draft_index, draft_ambiguous = _path_index(frozen_draft)
|
|
421
|
+
left_index, left_ambiguous = _path_index(frozen_left)
|
|
422
|
+
right_index, right_ambiguous = _path_index(frozen_right)
|
|
423
|
+
if any(claim.path in draft_ambiguous for claim in claims):
|
|
424
|
+
raise ValueError("crossover claim has an ambiguous candidate path spelling")
|
|
425
|
+
|
|
426
|
+
resolved: list[tuple[CrossoverInheritanceClaim, JsonPath]] = []
|
|
427
|
+
seen_text: set[str] = set()
|
|
428
|
+
for claim in claims:
|
|
429
|
+
if claim.path in seen_text:
|
|
430
|
+
raise ValueError("crossover claim paths must be unique")
|
|
431
|
+
seen_text.add(claim.path)
|
|
432
|
+
path = draft_index.get(claim.path)
|
|
433
|
+
if path is None:
|
|
434
|
+
raise ValueError("crossover claim path does not exist in the draft")
|
|
435
|
+
resolved.append((claim, path))
|
|
436
|
+
|
|
437
|
+
for index, (_, path) in enumerate(resolved):
|
|
438
|
+
for _, other in resolved[index + 1 :]:
|
|
439
|
+
if path.is_prefix_of(other) or other.is_prefix_of(path):
|
|
440
|
+
raise ValueError("crossover claim paths must not overlap")
|
|
441
|
+
|
|
442
|
+
inherited: list[InheritedPathMaterializationEvidence] = []
|
|
443
|
+
synthesized: list[SynthesizedPathEvidence] = []
|
|
444
|
+
materialized: FrozenJsonValue = frozen_draft
|
|
445
|
+
source_counts = {
|
|
446
|
+
CrossoverInheritanceSource.LEFT: 0,
|
|
447
|
+
CrossoverInheritanceSource.RIGHT: 0,
|
|
448
|
+
}
|
|
449
|
+
claims_by_path: dict[bytes, CrossoverInheritanceClaim] = {}
|
|
450
|
+
|
|
451
|
+
for claim, draft_path in resolved:
|
|
452
|
+
encoded_path = canonical_path_bytes(draft_path)
|
|
453
|
+
claims_by_path[encoded_path] = claim
|
|
454
|
+
witness_value = value_at_path(frozen_draft, draft_path)
|
|
455
|
+
if claim.source in (
|
|
456
|
+
CrossoverInheritanceSource.LEFT,
|
|
457
|
+
CrossoverInheritanceSource.RIGHT,
|
|
458
|
+
):
|
|
459
|
+
if claim.path in left_ambiguous or claim.path in right_ambiguous:
|
|
460
|
+
raise ValueError("inherited claim is ambiguous in a parent")
|
|
461
|
+
left_path = left_index.get(claim.path)
|
|
462
|
+
right_path = right_index.get(claim.path)
|
|
463
|
+
if left_path is None or right_path is None:
|
|
464
|
+
raise ValueError("inherited claim path must exist in both parents")
|
|
465
|
+
if (
|
|
466
|
+
canonical_path_bytes(left_path) != encoded_path
|
|
467
|
+
or canonical_path_bytes(right_path) != encoded_path
|
|
468
|
+
):
|
|
469
|
+
raise ValueError("inherited claim path differs across candidate trees")
|
|
470
|
+
left_value = value_at_path(frozen_left, left_path)
|
|
471
|
+
right_value = value_at_path(frozen_right, right_path)
|
|
472
|
+
if typed_json_equal(left_value, right_value):
|
|
473
|
+
raise ValueError("inherited claim path is not parent-discriminating")
|
|
474
|
+
parent_value = (
|
|
475
|
+
left_value
|
|
476
|
+
if claim.source is CrossoverInheritanceSource.LEFT
|
|
477
|
+
else right_value
|
|
478
|
+
)
|
|
479
|
+
equivalent, adjusted, maximum = _witness_equivalence(
|
|
480
|
+
witness_value, parent_value
|
|
481
|
+
)
|
|
482
|
+
if not equivalent:
|
|
483
|
+
raise ValueError(
|
|
484
|
+
"inherited witness differs materially from its named parent"
|
|
485
|
+
)
|
|
486
|
+
materialized = replace_existing_path(
|
|
487
|
+
materialized,
|
|
488
|
+
draft_path,
|
|
489
|
+
parent_value,
|
|
490
|
+
)
|
|
491
|
+
source_counts[claim.source] += 1
|
|
492
|
+
inherited.append(
|
|
493
|
+
InheritedPathMaterializationEvidence(
|
|
494
|
+
path=claim.path,
|
|
495
|
+
source=claim.source,
|
|
496
|
+
witness_value_sha256=typed_json_sha256(witness_value),
|
|
497
|
+
parent_value_sha256=typed_json_sha256(parent_value),
|
|
498
|
+
witness_exact=typed_json_equal(witness_value, parent_value),
|
|
499
|
+
adjusted_float_leaf_count=adjusted,
|
|
500
|
+
max_float_ulp_distance=maximum,
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
else:
|
|
504
|
+
left_path = None if claim.path in left_ambiguous else left_index.get(claim.path)
|
|
505
|
+
right_path = (
|
|
506
|
+
None if claim.path in right_ambiguous else right_index.get(claim.path)
|
|
507
|
+
)
|
|
508
|
+
if claim.path in left_ambiguous or claim.path in right_ambiguous:
|
|
509
|
+
raise ValueError("synthesized claim is ambiguous in a parent")
|
|
510
|
+
left_value = (
|
|
511
|
+
_MISSING
|
|
512
|
+
if left_path is None
|
|
513
|
+
else value_at_path(frozen_left, left_path)
|
|
514
|
+
)
|
|
515
|
+
right_value = (
|
|
516
|
+
_MISSING
|
|
517
|
+
if right_path is None
|
|
518
|
+
else value_at_path(frozen_right, right_path)
|
|
519
|
+
)
|
|
520
|
+
if _optional_equal(witness_value, left_value) or _optional_equal(
|
|
521
|
+
witness_value, right_value
|
|
522
|
+
):
|
|
523
|
+
raise ValueError(
|
|
524
|
+
"synthesized claim must author a value distinct from both parents"
|
|
525
|
+
)
|
|
526
|
+
synthesized.append(
|
|
527
|
+
SynthesizedPathEvidence(
|
|
528
|
+
path=claim.path,
|
|
529
|
+
witness_value_sha256=typed_json_sha256(witness_value),
|
|
530
|
+
left_value_sha256=(
|
|
531
|
+
None
|
|
532
|
+
if left_value is _MISSING
|
|
533
|
+
else typed_json_sha256(left_value)
|
|
534
|
+
),
|
|
535
|
+
right_value_sha256=(
|
|
536
|
+
None
|
|
537
|
+
if right_value is _MISSING
|
|
538
|
+
else typed_json_sha256(right_value)
|
|
539
|
+
),
|
|
540
|
+
)
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
if not all(source_counts.values()):
|
|
544
|
+
raise ValueError(
|
|
545
|
+
"two-parent crossover requires a discriminating claim from both parents"
|
|
546
|
+
)
|
|
547
|
+
if type(materialized) is not FrozenJsonObject: # pragma: no cover - root forbidden.
|
|
548
|
+
raise AssertionError("non-root inheritance changed the candidate root type")
|
|
549
|
+
_audit_exhaustive_plan(
|
|
550
|
+
frozen_left,
|
|
551
|
+
frozen_right,
|
|
552
|
+
materialized,
|
|
553
|
+
claims_by_path,
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
result = CrossoverInheritanceMaterialization(
|
|
557
|
+
configuration=materialized,
|
|
558
|
+
draft_configuration_sha256=typed_json_sha256(frozen_draft),
|
|
559
|
+
materialized_configuration_sha256=typed_json_sha256(materialized),
|
|
560
|
+
inherited_paths=tuple(sorted(inherited, key=lambda item: item.path)),
|
|
561
|
+
synthesized_paths=tuple(sorted(synthesized, key=lambda item: item.path)),
|
|
562
|
+
)
|
|
563
|
+
# Exercise the receipt codec at the trust boundary before returning it.
|
|
564
|
+
result.receipt_sha256
|
|
565
|
+
return result
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
__all__ = [
|
|
569
|
+
"CrossoverInheritanceClaim",
|
|
570
|
+
"CrossoverInheritanceMaterialization",
|
|
571
|
+
"CrossoverInheritanceSource",
|
|
572
|
+
"InheritedPathMaterializationEvidence",
|
|
573
|
+
"SynthesizedPathEvidence",
|
|
574
|
+
"materialize_crossover_inheritance",
|
|
575
|
+
]
|