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.
Files changed (414) hide show
  1. agent_evolve/__init__.py +722 -0
  2. agent_evolve/agentic.py +2800 -0
  3. agent_evolve/api.py +767 -0
  4. agent_evolve/application/__init__.py +1580 -0
  5. agent_evolve/application/action_allocation.py +744 -0
  6. agent_evolve/application/action_allocation_frame.py +347 -0
  7. agent_evolve/application/action_allocation_frame_commit.py +185 -0
  8. agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
  9. agent_evolve/application/action_allocation_frame_v3.py +338 -0
  10. agent_evolve/application/action_archive_value.py +497 -0
  11. agent_evolve/application/action_evidence_consistency.py +455 -0
  12. agent_evolve/application/action_forecast_partitioning.py +1471 -0
  13. agent_evolve/application/action_metric_projection.py +211 -0
  14. agent_evolve/application/action_role_value.py +680 -0
  15. agent_evolve/application/action_score_authorities.py +363 -0
  16. agent_evolve/application/action_structural_signature.py +116 -0
  17. agent_evolve/application/action_target_realization.py +402 -0
  18. agent_evolve/application/agentic_evolution.py +7734 -0
  19. agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
  20. agent_evolve/application/anchor_residual_identification.py +463 -0
  21. agent_evolve/application/archive_conditioned_action_target.py +208 -0
  22. agent_evolve/application/artifact_journal.py +246 -0
  23. agent_evolve/application/artifact_replay.py +347 -0
  24. agent_evolve/application/budgeted_optimizer.py +1828 -0
  25. agent_evolve/application/calibrated_campaign.py +485 -0
  26. agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
  27. agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
  28. agent_evolve/application/campaign_capacity_recourse.py +254 -0
  29. agent_evolve/application/campaign_contextual_outcomes.py +119 -0
  30. agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
  31. agent_evolve/application/campaign_evidence_registry.py +262 -0
  32. agent_evolve/application/campaign_execution.py +2537 -0
  33. agent_evolve/application/campaign_generation_audit.py +942 -0
  34. agent_evolve/application/campaign_learning.py +1812 -0
  35. agent_evolve/application/campaign_learning_runtime.py +1977 -0
  36. agent_evolve/application/campaign_search_phase.py +227 -0
  37. agent_evolve/application/campaign_selector_context_extension.py +220 -0
  38. agent_evolve/application/campaign_variation_envelope.py +649 -0
  39. agent_evolve/application/campaign_variation_trace.py +451 -0
  40. agent_evolve/application/candidate_archive_consequence.py +128 -0
  41. agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
  42. agent_evolve/application/composite_outcome_updater.py +145 -0
  43. agent_evolve/application/composition_portfolio_selection.py +363 -0
  44. agent_evolve/application/concurrent_stage.py +144 -0
  45. agent_evolve/application/contextual_action_allocation.py +181 -0
  46. agent_evolve/application/contextual_campaign_outcomes.py +267 -0
  47. agent_evolve/application/contextual_campaign_planning.py +1366 -0
  48. agent_evolve/application/contextual_delayed_credit.py +651 -0
  49. agent_evolve/application/contextual_search_controller.py +2374 -0
  50. agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
  51. agent_evolve/application/decision_metric_projection.py +112 -0
  52. agent_evolve/application/derived_action_semantics.py +129 -0
  53. agent_evolve/application/detailed_evaluation.py +449 -0
  54. agent_evolve/application/earned_lineage.py +1011 -0
  55. agent_evolve/application/effective_choice_audit.py +484 -0
  56. agent_evolve/application/empirical_consequence_calibration.py +908 -0
  57. agent_evolve/application/evaluation_accounting.py +325 -0
  58. agent_evolve/application/evaluation_cache.py +199 -0
  59. agent_evolve/application/evaluation_escrow.py +547 -0
  60. agent_evolve/application/evaluation_recourse.py +253 -0
  61. agent_evolve/application/event_recorder.py +151 -0
  62. agent_evolve/application/evolution_campaign.py +1840 -0
  63. agent_evolve/application/executable_hypothesis.py +323 -0
  64. agent_evolve/application/factorial_branch_pilot.py +772 -0
  65. agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
  66. agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
  67. agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
  68. agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
  69. agent_evolve/application/finite_action_selection.py +188 -0
  70. agent_evolve/application/finite_action_set.py +306 -0
  71. agent_evolve/application/finite_action_transition.py +537 -0
  72. agent_evolve/application/finite_variation_eligibility.py +296 -0
  73. agent_evolve/application/forecast_geometry_portfolio.py +799 -0
  74. agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
  75. agent_evolve/application/front_proximity_admission.py +311 -0
  76. agent_evolve/application/front_proximity_parent_basis.py +458 -0
  77. agent_evolve/application/frozen_hurdle_score.py +659 -0
  78. agent_evolve/application/g3_causal_screen.py +2257 -0
  79. agent_evolve/application/g3_causal_validation.py +1046 -0
  80. agent_evolve/application/g3_postseal_curation.py +818 -0
  81. agent_evolve/application/gated_agentic_generator.py +205 -0
  82. agent_evolve/application/generation_feedback.py +293 -0
  83. agent_evolve/application/generative_proposal_journal.py +185 -0
  84. agent_evolve/application/geometry_conditional_elasticity.py +453 -0
  85. agent_evolve/application/global_wave_action_allocation.py +1151 -0
  86. agent_evolve/application/head_mass_conditional_seat.py +268 -0
  87. agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
  88. agent_evolve/application/identifiable_reflection_learning.py +395 -0
  89. agent_evolve/application/identifiable_reflection_request.py +364 -0
  90. agent_evolve/application/in_memory_residual_archive.py +341 -0
  91. agent_evolve/application/insight_memory.py +1804 -0
  92. agent_evolve/application/live_runtime_manifest.py +758 -0
  93. agent_evolve/application/llm_task_queue.py +769 -0
  94. agent_evolve/application/matched_finite_action_block.py +409 -0
  95. agent_evolve/application/materialized_action_broker.py +2328 -0
  96. agent_evolve/application/materialized_action_constraints.py +83 -0
  97. agent_evolve/application/materialized_variation.py +211 -0
  98. agent_evolve/application/multi_option_evolution.py +1536 -0
  99. agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
  100. agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
  101. agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
  102. agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
  103. agent_evolve/application/outcome_relation.py +193 -0
  104. agent_evolve/application/paired_allocation_comparison.py +241 -0
  105. agent_evolve/application/paired_block_schedule.py +127 -0
  106. agent_evolve/application/parent_measurement.py +226 -0
  107. agent_evolve/application/pareto_archive.py +811 -0
  108. agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
  109. agent_evolve/application/portfolio_evolution.py +2950 -0
  110. agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
  111. agent_evolve/application/portfolio_memory_attribution.py +581 -0
  112. agent_evolve/application/portfolio_memory_dose.py +788 -0
  113. agent_evolve/application/portfolio_memory_matched_control.py +938 -0
  114. agent_evolve/application/portfolio_memory_transfer.py +297 -0
  115. agent_evolve/application/portfolio_optimization_memory.py +363 -0
  116. agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
  117. agent_evolve/application/portfolio_projection.py +335 -0
  118. agent_evolve/application/portfolio_recombination.py +2032 -0
  119. agent_evolve/application/post_evolution_reflection.py +834 -0
  120. agent_evolve/application/postcommit_rank_authority.py +245 -0
  121. agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
  122. agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
  123. agent_evolve/application/prequential_residual_exploration.py +343 -0
  124. agent_evolve/application/prequential_score_portfolio.py +954 -0
  125. agent_evolve/application/projections.py +292 -0
  126. agent_evolve/application/protected_action_committee.py +1027 -0
  127. agent_evolve/application/protected_branch_pilot.py +376 -0
  128. agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
  129. agent_evolve/application/provider_replay.py +910 -0
  130. agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
  131. agent_evolve/application/recombination_residual_expert.py +403 -0
  132. agent_evolve/application/reflection_workflow.py +571 -0
  133. agent_evolve/application/region_conditional_credit.py +911 -0
  134. agent_evolve/application/residual_campaign_runtime.py +531 -0
  135. agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
  136. agent_evolve/application/residual_headroom_ledger.py +1544 -0
  137. agent_evolve/application/residual_learning_transaction.py +396 -0
  138. agent_evolve/application/residual_portfolio_evolution.py +1228 -0
  139. agent_evolve/application/residual_reachability.py +749 -0
  140. agent_evolve/application/residual_stage_credit.py +499 -0
  141. agent_evolve/application/same_prefix_paired_audit.py +1580 -0
  142. agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
  143. agent_evolve/application/sequential_lineage_allocation.py +1017 -0
  144. agent_evolve/application/sequential_market_replay.py +1395 -0
  145. agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
  146. agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
  147. agent_evolve/application/single_score_action_allocation.py +299 -0
  148. agent_evolve/application/source_exposure_allocation.py +906 -0
  149. agent_evolve/application/staged_memory.py +210 -0
  150. agent_evolve/application/stratified_cold_start_allocation.py +732 -0
  151. agent_evolve/application/support_guarded_hurdle_score.py +549 -0
  152. agent_evolve/application/target_conditioned_action_forecast.py +595 -0
  153. agent_evolve/application/target_conditioned_campaign.py +566 -0
  154. agent_evolve/application/treatment_assignment.py +201 -0
  155. agent_evolve/application/trusted_objective_evidence.py +217 -0
  156. agent_evolve/application/two_stage_action_evolution.py +1131 -0
  157. agent_evolve/application/v8lite_allocation_policy.py +1083 -0
  158. agent_evolve/application/v9_candidate_policy.py +1303 -0
  159. agent_evolve/bootstrap.py +108 -0
  160. agent_evolve/campaign_presets.py +517 -0
  161. agent_evolve/campaign_profiles.py +452 -0
  162. agent_evolve/campaign_variation_topology.py +288 -0
  163. agent_evolve/campaign_workload.py +950 -0
  164. agent_evolve/cli.py +797 -0
  165. agent_evolve/contract.py +241 -0
  166. agent_evolve/core/__init__.py +91 -0
  167. agent_evolve/core/action_semantics.py +411 -0
  168. agent_evolve/core/authored.py +105 -0
  169. agent_evolve/core/formatting.py +286 -0
  170. agent_evolve/core/optimization_semantics.py +324 -0
  171. agent_evolve/core/problem.py +167 -0
  172. agent_evolve/core/results.py +323 -0
  173. agent_evolve/core/stats.py +70 -0
  174. agent_evolve/core/telemetry.py +100 -0
  175. agent_evolve/domain/__init__.py +89 -0
  176. agent_evolve/domain/artifact.py +162 -0
  177. agent_evolve/domain/durable_text.py +68 -0
  178. agent_evolve/domain/event.py +1454 -0
  179. agent_evolve/domain/finite_action_set.py +426 -0
  180. agent_evolve/domain/finite_variation.py +526 -0
  181. agent_evolve/domain/generative_emission.py +559 -0
  182. agent_evolve/domain/ids.py +163 -0
  183. agent_evolve/domain/inline_text.py +106 -0
  184. agent_evolve/domain/insight.py +27 -0
  185. agent_evolve/domain/lineage.py +737 -0
  186. agent_evolve/domain/llm_task_queue.py +960 -0
  187. agent_evolve/domain/outcome.py +96 -0
  188. agent_evolve/domain/patch.py +854 -0
  189. agent_evolve/domain/typed_json.py +542 -0
  190. agent_evolve/domain/variation_space.py +158 -0
  191. agent_evolve/driver.py +1014 -0
  192. agent_evolve/harness/__init__.py +29 -0
  193. agent_evolve/harness/base.py +242 -0
  194. agent_evolve/harness/directives.py +163 -0
  195. agent_evolve/harness/generative_seal.py +479 -0
  196. agent_evolve/harness/registry.py +41 -0
  197. agent_evolve/infrastructure/__init__.py +39 -0
  198. agent_evolve/infrastructure/artifacts/__init__.py +6 -0
  199. agent_evolve/infrastructure/artifacts/_verification.py +67 -0
  200. agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
  201. agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
  202. agent_evolve/infrastructure/asyncio_runtime.py +109 -0
  203. agent_evolve/infrastructure/authored_runtime.py +188 -0
  204. agent_evolve/infrastructure/authored_worker.py +171 -0
  205. agent_evolve/infrastructure/clock.py +53 -0
  206. agent_evolve/infrastructure/events/__init__.py +6 -0
  207. agent_evolve/infrastructure/events/_validation.py +89 -0
  208. agent_evolve/infrastructure/events/in_memory.py +56 -0
  209. agent_evolve/infrastructure/events/jsonl.py +193 -0
  210. agent_evolve/infrastructure/exception_provenance.py +215 -0
  211. agent_evolve/infrastructure/ids.py +118 -0
  212. agent_evolve/infrastructure/lineage_codec.py +1836 -0
  213. agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
  214. agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
  215. agent_evolve/infrastructure/resource_lease.py +370 -0
  216. agent_evolve/infrastructure/sanitization/__init__.py +8 -0
  217. agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
  218. agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
  219. agent_evolve/infrastructure/stream_liveness.py +383 -0
  220. agent_evolve/infrastructure/subprocess_boundary.py +136 -0
  221. agent_evolve/integrations/__init__.py +1 -0
  222. agent_evolve/integrations/botorch/__init__.py +28 -0
  223. agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
  224. agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
  225. agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
  226. agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
  227. agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
  228. agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
  229. agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
  230. agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
  231. agent_evolve/integrations/completion.py +242 -0
  232. agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
  233. agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
  234. agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
  235. agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
  236. agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
  237. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
  238. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
  239. agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
  240. agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
  241. agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
  242. agent_evolve/integrations/pydantic_ai/harness.py +159 -0
  243. agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
  244. agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
  245. agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
  246. agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
  247. agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
  248. agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
  249. agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
  250. agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
  251. agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
  252. agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
  253. agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
  254. agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
  255. agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
  256. agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
  257. agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
  258. agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
  259. agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
  260. agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
  261. agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
  262. agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
  263. agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
  264. agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
  265. agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
  266. agent_evolve/integrations/pymoo_adapter.py +242 -0
  267. agent_evolve/policies/__init__.py +17 -0
  268. agent_evolve/policies/check.py +469 -0
  269. agent_evolve/policies/emit_scaffold.py +451 -0
  270. agent_evolve/policies/feedback/__init__.py +37 -0
  271. agent_evolve/policies/feedback/held_out_asn.py +1325 -0
  272. agent_evolve/policies/genetic.py +607 -0
  273. agent_evolve/policies/llm_backoff.py +183 -0
  274. agent_evolve/policies/llm_chooser.py +226 -0
  275. agent_evolve/policies/llm_generator.py +1760 -0
  276. agent_evolve/policies/llm_init.py +267 -0
  277. agent_evolve/policies/llm_operator.py +109 -0
  278. agent_evolve/policies/llm_prior.py +194 -0
  279. agent_evolve/policies/llm_surrogate.py +334 -0
  280. agent_evolve/policies/measurement_evidence.py +704 -0
  281. agent_evolve/policies/memory/__init__.py +223 -0
  282. agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
  283. agent_evolve/policies/memory/compatibility_matching.py +593 -0
  284. agent_evolve/policies/memory/global_falsification.py +1841 -0
  285. agent_evolve/policies/memory/prompt_shape.py +503 -0
  286. agent_evolve/policies/memory/randomized_subset.py +714 -0
  287. agent_evolve/policies/memory/staged_causal.py +1270 -0
  288. agent_evolve/policies/memory/treatment_compliance.py +759 -0
  289. agent_evolve/policies/objective_resolution/__init__.py +17 -0
  290. agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
  291. agent_evolve/policies/operator_portfolio.py +407 -0
  292. agent_evolve/policies/reguidance.py +1133 -0
  293. agent_evolve/policies/reward/__init__.py +83 -0
  294. agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
  295. agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
  296. agent_evolve/policies/reward/affine_hypervolume.py +490 -0
  297. agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
  298. agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
  299. agent_evolve/policies/reward/frozen_archive.py +360 -0
  300. agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
  301. agent_evolve/policies/search_state.py +208 -0
  302. agent_evolve/policies/selection/__init__.py +345 -0
  303. agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
  304. agent_evolve/policies/selection/affine_frontier_context.py +330 -0
  305. agent_evolve/policies/selection/affine_frontier_target.py +473 -0
  306. agent_evolve/policies/selection/archive_elite.py +1346 -0
  307. agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
  308. agent_evolve/policies/selection/calibrated_slate.py +1394 -0
  309. agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
  310. agent_evolve/policies/selection/common_candidate_pool.py +685 -0
  311. agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
  312. agent_evolve/policies/selection/disjoint_pairs.py +479 -0
  313. agent_evolve/policies/selection/elite_explorer.py +719 -0
  314. agent_evolve/policies/selection/finite_action.py +187 -0
  315. agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
  316. agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
  317. agent_evolve/policies/selection/forecast_calibration.py +922 -0
  318. agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
  319. agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
  320. agent_evolve/policies/selection/full_support_slate.py +91 -0
  321. agent_evolve/policies/selection/meaningful_direction.py +240 -0
  322. agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
  323. agent_evolve/policies/selection/model_anchored_slate.py +826 -0
  324. agent_evolve/policies/selection/phenotype_recourse.py +979 -0
  325. agent_evolve/policies/selection/proposal_support.py +368 -0
  326. agent_evolve/policies/selection/random_portfolio.py +254 -0
  327. agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
  328. agent_evolve/policies/selection/residual_frontier.py +463 -0
  329. agent_evolve/policies/selection/residual_frontier_target.py +605 -0
  330. agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
  331. agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
  332. agent_evolve/policies/selection/target_conditioned_features.py +812 -0
  333. agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
  334. agent_evolve/policies/selection/task_keyed_palette.py +906 -0
  335. agent_evolve/policies/semantics.py +147 -0
  336. agent_evolve/policies/structure.py +362 -0
  337. agent_evolve/policies/structured_output_budget.py +62 -0
  338. agent_evolve/policies/surrogate.py +696 -0
  339. agent_evolve/policies/variation/__init__.py +1 -0
  340. agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
  341. agent_evolve/policies/variation/crossover_inheritance.py +575 -0
  342. agent_evolve/policies/variation/disjoint_recombination.py +611 -0
  343. agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
  344. agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
  345. agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
  346. agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
  347. agent_evolve/policies/variation/typed_patch.py +1981 -0
  348. agent_evolve/policies/weighted_prior.py +394 -0
  349. agent_evolve/ports/__init__.py +383 -0
  350. agent_evolve/ports/action_allocation.py +733 -0
  351. agent_evolve/ports/action_allocation_frame.py +1153 -0
  352. agent_evolve/ports/action_allocation_frame_commit.py +294 -0
  353. agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
  354. agent_evolve/ports/action_allocation_frame_v3.py +995 -0
  355. agent_evolve/ports/action_forecast.py +1568 -0
  356. agent_evolve/ports/action_metric_projection.py +165 -0
  357. agent_evolve/ports/agentic_generator.py +1561 -0
  358. agent_evolve/ports/archive_context.py +136 -0
  359. agent_evolve/ports/artifact_sanitizer.py +44 -0
  360. agent_evolve/ports/artifact_store.py +225 -0
  361. agent_evolve/ports/clock.py +13 -0
  362. agent_evolve/ports/contextual_search_allocation.py +827 -0
  363. agent_evolve/ports/decision_metric_projection.py +258 -0
  364. agent_evolve/ports/event_store.py +55 -0
  365. agent_evolve/ports/executable_hypothesis.py +557 -0
  366. agent_evolve/ports/finite_acquisition.py +377 -0
  367. agent_evolve/ports/finite_acquisition_batch.py +296 -0
  368. agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
  369. agent_evolve/ports/finite_acquisition_json.py +247 -0
  370. agent_evolve/ports/finite_acquisition_space.py +168 -0
  371. agent_evolve/ports/finite_action_selection.py +348 -0
  372. agent_evolve/ports/finite_action_set.py +256 -0
  373. agent_evolve/ports/frontier_target.py +396 -0
  374. agent_evolve/ports/generation_failure.py +43 -0
  375. agent_evolve/ports/hard_feasibility.py +233 -0
  376. agent_evolve/ports/id_factory.py +34 -0
  377. agent_evolve/ports/llm_task_queue.py +93 -0
  378. agent_evolve/ports/objective_resolution.py +419 -0
  379. agent_evolve/ports/paired_allocation_comparison.py +401 -0
  380. agent_evolve/ports/paired_block_schedule.py +475 -0
  381. agent_evolve/ports/parent_measurement.py +336 -0
  382. agent_evolve/ports/portfolio_memory_dose.py +643 -0
  383. agent_evolve/ports/portfolio_selection.py +3169 -0
  384. agent_evolve/ports/postcommit_rank_authority.py +467 -0
  385. agent_evolve/ports/presented_action_evidence.py +794 -0
  386. agent_evolve/ports/resource_lease.py +162 -0
  387. agent_evolve/ports/structured_generator.py +734 -0
  388. agent_evolve/ports/structured_output_budget.py +120 -0
  389. agent_evolve/ports/subprocess_boundary.py +138 -0
  390. agent_evolve/ports/treatment_assignment.py +466 -0
  391. agent_evolve/ports/variation_catalog.py +76 -0
  392. agent_evolve/ports/variation_source.py +226 -0
  393. agent_evolve/proposal_mode.py +157 -0
  394. agent_evolve/proposers/__init__.py +10 -0
  395. agent_evolve/proposers/random_proposer.py +188 -0
  396. agent_evolve/provider_accounting.py +163 -0
  397. agent_evolve/py.typed +0 -0
  398. agent_evolve/reference_method.py +1570 -0
  399. agent_evolve/session/__init__.py +11 -0
  400. agent_evolve/session/authorship.py +864 -0
  401. agent_evolve/session/evaluate.py +236 -0
  402. agent_evolve/session/fidelity.py +237 -0
  403. agent_evolve/session/genetic_loop.py +742 -0
  404. agent_evolve/session/loop.py +803 -0
  405. agent_evolve/session/screening.py +671 -0
  406. agent_evolve/settings.py +376 -0
  407. agent_evolve/workload_kit.py +368 -0
  408. agent_evolve/workload_prompt.py +398 -0
  409. agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
  410. agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
  411. agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
  412. agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
  413. agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
  414. 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
+ ]