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,762 @@
1
+ """Archive-aware exploit and structural-coverage disjoint pair selection.
2
+
3
+ The legacy disjoint-pair policy ranks exploit pairs by parent-relative branch
4
+ rewards. Those rewards need not agree with multiobjective archive progress.
5
+ This module provides an opt-in policy that instead consumes an authenticated
6
+ table of marginal branch utilities and exact joint utilities for every pair of
7
+ *observed source branches*, all evaluated against one frozen pre-generation
8
+ archive snapshot.
9
+
10
+ The exploit key is the utility of adding both observed sources jointly to the
11
+ frozen archive. It is not the arithmetic sum of marginal utilities, which can
12
+ double-count overlapping archive gain. It is deliberately not represented as
13
+ a prediction of the unseen recombination child's utility. Coverage remains a
14
+ separately identified structural-diversity role.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import hashlib
20
+ import json
21
+ import math
22
+ import re
23
+ from dataclasses import dataclass
24
+ from itertools import combinations
25
+ from typing import ClassVar, Sequence
26
+
27
+ from agent_evolve.domain.ids import CandidateId
28
+ from agent_evolve.domain.patch import require_sha256
29
+ from agent_evolve.policies.selection.disjoint_pairs import (
30
+ DisjointParentPairPolicy,
31
+ ReplayVerifiedDisjointPair,
32
+ )
33
+
34
+
35
+ POLICY_ID = "frozen_archive_exact_joint_source_utility_disjoint_pair"
36
+ POLICY_VERSION = 2
37
+ _CONTEXT_DOMAIN = b"agent-evolve:frozen-archive-source-utility-context:v1\x00"
38
+ _RECEIPT_DOMAIN = b"agent-evolve:frozen-archive-source-utility-receipt:v1\x00"
39
+ _DECISION_DOMAIN = b"agent-evolve:frozen-archive-disjoint-pair-decision:v2\x00"
40
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
41
+ _MAX_GENERATION = (1 << 63) - 1
42
+
43
+
44
+ def _canonical_json(value: object) -> bytes:
45
+ return json.dumps(
46
+ value,
47
+ allow_nan=False,
48
+ ensure_ascii=True,
49
+ separators=(",", ":"),
50
+ sort_keys=True,
51
+ ).encode("ascii", errors="strict")
52
+
53
+
54
+ def _hash(domain: bytes, value: object) -> str:
55
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
56
+
57
+
58
+ def _require_token(value: str, *, name: str) -> None:
59
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
60
+ raise ValueError(f"{name} must use the closed lowercase token grammar")
61
+
62
+
63
+ def _require_generation(value: int, *, name: str) -> None:
64
+ if type(value) is not int or not 1 <= value <= _MAX_GENERATION:
65
+ raise ValueError(f"{name} must be an exact positive int63")
66
+
67
+
68
+ def _require_utility(value: float, *, name: str) -> None:
69
+ if type(value) is not float or not math.isfinite(value):
70
+ raise TypeError(f"{name} must be a finite canonical float")
71
+
72
+
73
+ def _pair_key(pair: ReplayVerifiedDisjointPair) -> tuple[str, str]:
74
+ pair.revalidate()
75
+ return pair.left.candidate_id.value, pair.right.candidate_id.value
76
+
77
+
78
+ @dataclass(frozen=True, slots=True)
79
+ class FrozenArchiveSourceUtilityContext:
80
+ """Identity of one workload-owned utility and frozen archive cutoff."""
81
+
82
+ utility_id: str
83
+ utility_version: int
84
+ utility_definition_sha256: str
85
+ benchmark_sha256: str
86
+ archive_cutoff_sha256: str
87
+ archive_snapshot_sha256: str
88
+ snapshot_generation: int
89
+
90
+ def __post_init__(self) -> None:
91
+ _require_token(self.utility_id, name="utility_id")
92
+ if type(self.utility_version) is not int or self.utility_version <= 0:
93
+ raise ValueError("utility_version must be a positive exact integer")
94
+ for name in (
95
+ "utility_definition_sha256",
96
+ "benchmark_sha256",
97
+ "archive_cutoff_sha256",
98
+ "archive_snapshot_sha256",
99
+ ):
100
+ require_sha256(getattr(self, name), name)
101
+ _require_generation(self.snapshot_generation, name="snapshot_generation")
102
+
103
+ def revalidate(self) -> None:
104
+ if type(self) is not FrozenArchiveSourceUtilityContext:
105
+ raise TypeError("context must be exact FrozenArchiveSourceUtilityContext")
106
+ FrozenArchiveSourceUtilityContext.__post_init__(self)
107
+
108
+ def _unsigned_record(self) -> dict[str, object]:
109
+ self.revalidate()
110
+ return {
111
+ "schema_version": 1,
112
+ "utility_id": self.utility_id,
113
+ "utility_version": self.utility_version,
114
+ "utility_definition_sha256": self.utility_definition_sha256,
115
+ "benchmark_sha256": self.benchmark_sha256,
116
+ "archive_cutoff_sha256": self.archive_cutoff_sha256,
117
+ "archive_snapshot_sha256": self.archive_snapshot_sha256,
118
+ "snapshot_generation": self.snapshot_generation,
119
+ }
120
+
121
+ @property
122
+ def context_sha256(self) -> str:
123
+ return _hash(_CONTEXT_DOMAIN, self._unsigned_record())
124
+
125
+ def to_record(self) -> dict[str, object]:
126
+ return {**self._unsigned_record(), "context_sha256": self.context_sha256}
127
+
128
+
129
+ @dataclass(frozen=True, slots=True)
130
+ class ObservedSourceBranch:
131
+ """Exact evaluated source occurrence to which utility is attributed."""
132
+
133
+ source_rank: int
134
+ candidate_id: CandidateId
135
+ candidate_configuration_sha256: str
136
+ source_outcome_sha256: str
137
+
138
+ def __post_init__(self) -> None:
139
+ if type(self.source_rank) is not int or self.source_rank <= 0:
140
+ raise ValueError("source_rank must be a positive exact integer")
141
+ if type(self.candidate_id) is not CandidateId:
142
+ raise TypeError("candidate_id must be an exact CandidateId")
143
+ CandidateId.__post_init__(self.candidate_id)
144
+ require_sha256(
145
+ self.candidate_configuration_sha256,
146
+ "candidate_configuration_sha256",
147
+ )
148
+ require_sha256(self.source_outcome_sha256, "source_outcome_sha256")
149
+
150
+ def revalidate(self) -> None:
151
+ if type(self) is not ObservedSourceBranch:
152
+ raise TypeError("source branch must be exact ObservedSourceBranch")
153
+ ObservedSourceBranch.__post_init__(self)
154
+
155
+ def to_record(self) -> dict[str, object]:
156
+ self.revalidate()
157
+ return {
158
+ "source_rank": self.source_rank,
159
+ "candidate_id": self.candidate_id.value,
160
+ "candidate_configuration_sha256": (self.candidate_configuration_sha256),
161
+ "source_outcome_sha256": self.source_outcome_sha256,
162
+ }
163
+
164
+
165
+ @dataclass(frozen=True, slots=True)
166
+ class FrozenArchiveBranchUtility:
167
+ """One observed source branch's marginal utility under the shared snapshot."""
168
+
169
+ source: ObservedSourceBranch
170
+ marginal_utility: float
171
+
172
+ def __post_init__(self) -> None:
173
+ if type(self.source) is not ObservedSourceBranch:
174
+ raise TypeError("source must be exact ObservedSourceBranch")
175
+ self.source.revalidate()
176
+ _require_utility(self.marginal_utility, name="marginal_utility")
177
+
178
+ def revalidate(self) -> None:
179
+ if type(self) is not FrozenArchiveBranchUtility:
180
+ raise TypeError("branch utility must be exact FrozenArchiveBranchUtility")
181
+ FrozenArchiveBranchUtility.__post_init__(self)
182
+
183
+ @property
184
+ def candidate_id(self) -> CandidateId:
185
+ self.revalidate()
186
+ return self.source.candidate_id
187
+
188
+ def to_record(self) -> dict[str, object]:
189
+ self.revalidate()
190
+ return {
191
+ "source": self.source.to_record(),
192
+ "marginal_utility_hex": self.marginal_utility.hex(),
193
+ }
194
+
195
+
196
+ @dataclass(frozen=True, slots=True)
197
+ class FrozenArchiveSourcePairUtility:
198
+ """Exact utility of two observed sources jointly augmenting the archive."""
199
+
200
+ pair_ids: tuple[CandidateId, CandidateId]
201
+ exact_joint_utility: float
202
+
203
+ def __post_init__(self) -> None:
204
+ if (
205
+ type(self.pair_ids) is not tuple
206
+ or len(self.pair_ids) != 2
207
+ or any(type(value) is not CandidateId for value in self.pair_ids)
208
+ ):
209
+ raise TypeError("pair_ids must contain two exact CandidateId values")
210
+ for value in self.pair_ids:
211
+ CandidateId.__post_init__(value)
212
+ if self.pair_ids[0] >= self.pair_ids[1]:
213
+ raise ValueError("source utility pair IDs must use canonical order")
214
+ _require_utility(self.exact_joint_utility, name="exact_joint_utility")
215
+
216
+ def revalidate(self) -> None:
217
+ if type(self) is not FrozenArchiveSourcePairUtility:
218
+ raise TypeError("pair utility must be exact FrozenArchiveSourcePairUtility")
219
+ FrozenArchiveSourcePairUtility.__post_init__(self)
220
+
221
+ def to_record(self) -> dict[str, object]:
222
+ self.revalidate()
223
+ return {
224
+ "pair_ids": [value.value for value in self.pair_ids],
225
+ "exact_joint_utility_hex": self.exact_joint_utility.hex(),
226
+ }
227
+
228
+
229
+ @dataclass(frozen=True, slots=True)
230
+ class FrozenArchiveSourceUtilityReceipt:
231
+ """Complete source and pair utility tables under one archive snapshot."""
232
+
233
+ context: FrozenArchiveSourceUtilityContext
234
+ source_wave_receipt_sha256: str
235
+ source_request_sha256: str
236
+ source_decision_sha256: str
237
+ source_contract_sha256: str
238
+ source_generation: int
239
+ branches: tuple[FrozenArchiveBranchUtility, ...]
240
+ pair_utilities: tuple[FrozenArchiveSourcePairUtility, ...]
241
+
242
+ def __post_init__(self) -> None:
243
+ if type(self.context) is not FrozenArchiveSourceUtilityContext:
244
+ raise TypeError("context must be exact FrozenArchiveSourceUtilityContext")
245
+ self.context.revalidate()
246
+ for name in (
247
+ "source_wave_receipt_sha256",
248
+ "source_request_sha256",
249
+ "source_decision_sha256",
250
+ "source_contract_sha256",
251
+ ):
252
+ require_sha256(getattr(self, name), name)
253
+ _require_generation(self.source_generation, name="source_generation")
254
+ if self.context.snapshot_generation != self.source_generation:
255
+ raise ValueError(
256
+ "archive utility snapshot is stale or foreign to the source generation"
257
+ )
258
+ if type(self.branches) is not tuple or any(
259
+ type(value) is not FrozenArchiveBranchUtility for value in self.branches
260
+ ):
261
+ raise TypeError("branches must contain exact branch utilities")
262
+ for value in self.branches:
263
+ value.revalidate()
264
+ source_ranks = tuple(value.source.source_rank for value in self.branches)
265
+ if source_ranks != tuple(sorted(set(source_ranks))):
266
+ raise ValueError(
267
+ "branch utilities must preserve canonical scored source-rank order"
268
+ )
269
+ ids = tuple(value.candidate_id for value in self.branches)
270
+ if len(set(ids)) != len(ids):
271
+ raise ValueError("branch utility candidate IDs must be unique")
272
+ if type(self.pair_utilities) is not tuple or any(
273
+ type(value) is not FrozenArchiveSourcePairUtility
274
+ for value in self.pair_utilities
275
+ ):
276
+ raise TypeError("pair_utilities must contain exact pair utilities")
277
+ for value in self.pair_utilities:
278
+ value.revalidate()
279
+ expected_pairs = tuple(combinations(sorted(ids), 2))
280
+ if tuple(value.pair_ids for value in self.pair_utilities) != expected_pairs:
281
+ raise ValueError(
282
+ "pair_utilities must completely enumerate source pairs in canonical order"
283
+ )
284
+
285
+ def revalidate(self) -> None:
286
+ if type(self) is not FrozenArchiveSourceUtilityReceipt:
287
+ raise TypeError("receipt must be exact FrozenArchiveSourceUtilityReceipt")
288
+ FrozenArchiveSourceUtilityReceipt.__post_init__(self)
289
+
290
+ def _unsigned_record(self) -> dict[str, object]:
291
+ self.revalidate()
292
+ return {
293
+ "schema_version": 1,
294
+ "context": self.context.to_record(),
295
+ "source_wave_receipt_sha256": self.source_wave_receipt_sha256,
296
+ "source_request_sha256": self.source_request_sha256,
297
+ "source_decision_sha256": self.source_decision_sha256,
298
+ "source_contract_sha256": self.source_contract_sha256,
299
+ "source_generation": self.source_generation,
300
+ "branches": [value.to_record() for value in self.branches],
301
+ "pair_utilities": [value.to_record() for value in self.pair_utilities],
302
+ "utility_semantics": (
303
+ "marginal_branch_diagnostics_and_exact_joint_observed_source_pair_"
304
+ "utility_against_one_frozen_archive; not_a_recombination_child_"
305
+ "prediction"
306
+ ),
307
+ }
308
+
309
+ @property
310
+ def receipt_sha256(self) -> str:
311
+ return _hash(_RECEIPT_DOMAIN, self._unsigned_record())
312
+
313
+ def to_record(self) -> dict[str, object]:
314
+ return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
315
+
316
+ def marginal_utility_for(
317
+ self, candidate_id: CandidateId
318
+ ) -> FrozenArchiveBranchUtility:
319
+ """Resolve a committed source marginal or fail closed."""
320
+
321
+ self.revalidate()
322
+ if type(candidate_id) is not CandidateId:
323
+ raise TypeError("candidate_id must be an exact CandidateId")
324
+ CandidateId.__post_init__(candidate_id)
325
+ for value in self.branches:
326
+ if value.candidate_id == candidate_id:
327
+ return value
328
+ raise ValueError("eligible pair contains a foreign or unscored source branch")
329
+
330
+ def exact_joint_utility_for(
331
+ self,
332
+ pair_ids: tuple[CandidateId, CandidateId],
333
+ ) -> FrozenArchiveSourcePairUtility:
334
+ """Resolve the committed exact joint utility for one canonical pair."""
335
+
336
+ self.revalidate()
337
+ if (
338
+ type(pair_ids) is not tuple
339
+ or len(pair_ids) != 2
340
+ or any(type(value) is not CandidateId for value in pair_ids)
341
+ ):
342
+ raise TypeError("pair_ids must contain two exact CandidateId values")
343
+ for value in self.pair_utilities:
344
+ if value.pair_ids == pair_ids:
345
+ return value
346
+ raise ValueError("eligible pair has no exact joint source utility")
347
+
348
+ def require_exact_context(
349
+ self,
350
+ *,
351
+ context: FrozenArchiveSourceUtilityContext,
352
+ source_wave_receipt_sha256: str,
353
+ source_request_sha256: str,
354
+ source_decision_sha256: str,
355
+ source_contract_sha256: str,
356
+ source_generation: int,
357
+ source_branches: Sequence[ObservedSourceBranch],
358
+ ) -> None:
359
+ """Authenticate the receipt against its calling source-wave boundary."""
360
+
361
+ self.revalidate()
362
+ if type(context) is not FrozenArchiveSourceUtilityContext:
363
+ raise TypeError("context must be exact FrozenArchiveSourceUtilityContext")
364
+ context.revalidate()
365
+ for name, value in (
366
+ ("source_wave_receipt_sha256", source_wave_receipt_sha256),
367
+ ("source_request_sha256", source_request_sha256),
368
+ ("source_decision_sha256", source_decision_sha256),
369
+ ("source_contract_sha256", source_contract_sha256),
370
+ ):
371
+ require_sha256(value, name)
372
+ _require_generation(source_generation, name="source_generation")
373
+ if isinstance(source_branches, (str, bytes)):
374
+ raise TypeError("source_branches must be a finite branch sequence")
375
+ expected_branches = tuple(source_branches)
376
+ for value in expected_branches:
377
+ if type(value) is not ObservedSourceBranch:
378
+ raise TypeError(
379
+ "source_branches must contain exact ObservedSourceBranch values"
380
+ )
381
+ value.revalidate()
382
+ observed_branches = tuple(value.source for value in self.branches)
383
+ if self.context != context:
384
+ raise ValueError("source utility receipt has a foreign archive context")
385
+ if self.source_generation != source_generation:
386
+ raise ValueError("source utility receipt is stale for this generation")
387
+ supplied = (
388
+ self.source_wave_receipt_sha256,
389
+ self.source_request_sha256,
390
+ self.source_decision_sha256,
391
+ self.source_contract_sha256,
392
+ )
393
+ expected = (
394
+ source_wave_receipt_sha256,
395
+ source_request_sha256,
396
+ source_decision_sha256,
397
+ source_contract_sha256,
398
+ )
399
+ if supplied != expected:
400
+ raise ValueError("source utility receipt belongs to a foreign source wave")
401
+ if observed_branches != expected_branches:
402
+ raise ValueError("source utility receipt has foreign or tampered branches")
403
+
404
+
405
+ @dataclass(frozen=True, slots=True)
406
+ class ArchiveAwareDisjointPairScoreRow:
407
+ """One safe pair under source utility and structural coverage scores."""
408
+
409
+ pair: ReplayVerifiedDisjointPair
410
+ left_marginal_utility: FrozenArchiveBranchUtility
411
+ right_marginal_utility: FrozenArchiveBranchUtility
412
+ exact_joint_source_utility: FrozenArchiveSourcePairUtility
413
+ distinct_role_count: int
414
+ distinct_family_count: int
415
+ path_family_exposure_sum: int
416
+
417
+ def __post_init__(self) -> None:
418
+ if type(self.pair) is not ReplayVerifiedDisjointPair:
419
+ raise TypeError("pair must be exact ReplayVerifiedDisjointPair")
420
+ self.pair.revalidate()
421
+ for name in ("left_marginal_utility", "right_marginal_utility"):
422
+ value = getattr(self, name)
423
+ if type(value) is not FrozenArchiveBranchUtility:
424
+ raise TypeError(f"{name} must be exact FrozenArchiveBranchUtility")
425
+ value.revalidate()
426
+ if self.left_marginal_utility.candidate_id != self.pair.left.candidate_id:
427
+ raise ValueError("left marginal belongs to a foreign source branch")
428
+ if self.right_marginal_utility.candidate_id != self.pair.right.candidate_id:
429
+ raise ValueError("right marginal belongs to a foreign source branch")
430
+ if type(self.exact_joint_source_utility) is not FrozenArchiveSourcePairUtility:
431
+ raise TypeError(
432
+ "exact_joint_source_utility must be exact FrozenArchiveSourcePairUtility"
433
+ )
434
+ self.exact_joint_source_utility.revalidate()
435
+ if self.exact_joint_source_utility.pair_ids != self.pair.pair_ids:
436
+ raise ValueError("exact joint utility belongs to a foreign source pair")
437
+ expected_roles = len({self.pair.left.role, self.pair.right.role})
438
+ if (
439
+ type(self.distinct_role_count) is not int
440
+ or self.distinct_role_count != expected_roles
441
+ ):
442
+ raise ValueError("distinct_role_count differs from pair facts")
443
+ expected_families = len({self.pair.left.family, self.pair.right.family})
444
+ if (
445
+ type(self.distinct_family_count) is not int
446
+ or self.distinct_family_count != expected_families
447
+ ):
448
+ raise ValueError("distinct_family_count differs from pair facts")
449
+ expected_exposure = (
450
+ self.pair.left.path_family_exposure + self.pair.right.path_family_exposure
451
+ )
452
+ if (
453
+ type(self.path_family_exposure_sum) is not int
454
+ or self.path_family_exposure_sum != expected_exposure
455
+ ):
456
+ raise ValueError("path_family_exposure_sum differs from pair facts")
457
+
458
+ def revalidate(self) -> None:
459
+ if type(self) is not ArchiveAwareDisjointPairScoreRow:
460
+ raise TypeError("score row must be exact ArchiveAwareDisjointPairScoreRow")
461
+ ArchiveAwareDisjointPairScoreRow.__post_init__(self)
462
+
463
+ @property
464
+ def pair_ids(self) -> tuple[CandidateId, CandidateId]:
465
+ self.revalidate()
466
+ return self.pair.pair_ids
467
+
468
+ def to_record(
469
+ self,
470
+ *,
471
+ exploit_pair_ids: tuple[CandidateId, CandidateId] | None,
472
+ exploit_target_configuration_sha256: str | None,
473
+ ) -> dict[str, object]:
474
+ self.revalidate()
475
+ if exploit_pair_ids is not None:
476
+ if (
477
+ type(exploit_pair_ids) is not tuple
478
+ or len(exploit_pair_ids) != 2
479
+ or any(type(value) is not CandidateId for value in exploit_pair_ids)
480
+ ):
481
+ raise TypeError("exploit_pair_ids must contain exact CandidateIds")
482
+ if exploit_target_configuration_sha256 is not None:
483
+ require_sha256(
484
+ exploit_target_configuration_sha256,
485
+ "exploit_target_configuration_sha256",
486
+ )
487
+ legacy_reward_sum = self.pair.left.reward + self.pair.right.reward
488
+ marginal_sum = (
489
+ self.left_marginal_utility.marginal_utility
490
+ + self.right_marginal_utility.marginal_utility
491
+ )
492
+ return {
493
+ **self.pair.to_trace_record(),
494
+ "left_source_marginal_utility": self.left_marginal_utility.to_record(),
495
+ "right_source_marginal_utility": self.right_marginal_utility.to_record(),
496
+ "marginal_utility_sum_diagnostic_hex": float(marginal_sum).hex(),
497
+ "exact_joint_source_utility": self.exact_joint_source_utility.to_record(),
498
+ "legacy_branch_reward_sum_hex": float(legacy_reward_sum).hex(),
499
+ "distinct_role_count": self.distinct_role_count,
500
+ "distinct_family_count": self.distinct_family_count,
501
+ "path_family_exposure_sum": self.path_family_exposure_sum,
502
+ "pair_distinct_from_exploit": (
503
+ None if exploit_pair_ids is None else self.pair_ids != exploit_pair_ids
504
+ ),
505
+ "target_distinct_from_exploit": (
506
+ None
507
+ if exploit_target_configuration_sha256 is None
508
+ else self.pair.target_configuration_sha256
509
+ != exploit_target_configuration_sha256
510
+ ),
511
+ "exploit_tie_key": [
512
+ -self.exact_joint_source_utility.exact_joint_utility,
513
+ -legacy_reward_sum,
514
+ -self.distinct_role_count,
515
+ self.pair.left.candidate_id.value,
516
+ self.pair.right.candidate_id.value,
517
+ ],
518
+ "coverage_tie_key": [
519
+ (
520
+ None
521
+ if exploit_target_configuration_sha256 is None
522
+ else self.pair.target_configuration_sha256
523
+ == exploit_target_configuration_sha256
524
+ ),
525
+ -self.distinct_family_count,
526
+ -self.distinct_role_count,
527
+ self.path_family_exposure_sum,
528
+ self.pair.left.candidate_id.value,
529
+ self.pair.right.candidate_id.value,
530
+ ],
531
+ }
532
+
533
+
534
+ def _canonical_rows(
535
+ pairs: Sequence[ReplayVerifiedDisjointPair],
536
+ receipt: FrozenArchiveSourceUtilityReceipt,
537
+ ) -> tuple[ArchiveAwareDisjointPairScoreRow, ...]:
538
+ if type(receipt) is not FrozenArchiveSourceUtilityReceipt:
539
+ raise TypeError("source_utilities must be an exact receipt")
540
+ receipt.revalidate()
541
+ legacy_rows = DisjointParentPairPolicy().select(pairs).eligible_rows
542
+ result: list[ArchiveAwareDisjointPairScoreRow] = []
543
+ for legacy in legacy_rows:
544
+ pair = legacy.pair
545
+ left = receipt.marginal_utility_for(pair.left.candidate_id)
546
+ right = receipt.marginal_utility_for(pair.right.candidate_id)
547
+ exact_joint = receipt.exact_joint_utility_for(pair.pair_ids)
548
+ result.append(
549
+ ArchiveAwareDisjointPairScoreRow(
550
+ pair=pair,
551
+ left_marginal_utility=left,
552
+ right_marginal_utility=right,
553
+ exact_joint_source_utility=exact_joint,
554
+ distinct_role_count=legacy.distinct_role_count,
555
+ distinct_family_count=legacy.distinct_family_count,
556
+ path_family_exposure_sum=legacy.path_family_exposure_sum,
557
+ )
558
+ )
559
+ return tuple(result)
560
+
561
+
562
+ def _select_rows(
563
+ rows: tuple[ArchiveAwareDisjointPairScoreRow, ...],
564
+ ) -> tuple[
565
+ ArchiveAwareDisjointPairScoreRow | None,
566
+ ArchiveAwareDisjointPairScoreRow | None,
567
+ ]:
568
+ if not rows:
569
+ return None, None
570
+ exploit = min(
571
+ rows,
572
+ key=lambda row: (
573
+ -row.exact_joint_source_utility.exact_joint_utility,
574
+ -(row.pair.left.reward + row.pair.right.reward),
575
+ -row.distinct_role_count,
576
+ *_pair_key(row.pair),
577
+ ),
578
+ )
579
+ coverage_pool = tuple(row for row in rows if row.pair_ids != exploit.pair_ids)
580
+ if not coverage_pool:
581
+ return exploit, None
582
+ coverage = min(
583
+ coverage_pool,
584
+ key=lambda row: (
585
+ row.pair.target_configuration_sha256
586
+ == exploit.pair.target_configuration_sha256,
587
+ -row.distinct_family_count,
588
+ -row.distinct_role_count,
589
+ row.path_family_exposure_sum,
590
+ *_pair_key(row.pair),
591
+ ),
592
+ )
593
+ return exploit, coverage
594
+
595
+
596
+ @dataclass(frozen=True, slots=True, eq=False)
597
+ class ArchiveAwareDisjointPairSelectionDecision:
598
+ """Trace-complete source-utility exploit and structural coverage choice."""
599
+
600
+ source_utilities: FrozenArchiveSourceUtilityReceipt
601
+ eligible_rows: tuple[ArchiveAwareDisjointPairScoreRow, ...]
602
+ exploit_pair_ids: tuple[CandidateId, CandidateId] | None
603
+ coverage_pair_ids: tuple[CandidateId, CandidateId] | None
604
+
605
+ policy_id: ClassVar[str] = POLICY_ID
606
+ policy_version: ClassVar[int] = POLICY_VERSION
607
+
608
+ def __post_init__(self) -> None:
609
+ if type(self.source_utilities) is not FrozenArchiveSourceUtilityReceipt:
610
+ raise TypeError("source_utilities must be an exact receipt")
611
+ self.source_utilities.revalidate()
612
+ if type(self.eligible_rows) is not tuple or any(
613
+ type(value) is not ArchiveAwareDisjointPairScoreRow
614
+ for value in self.eligible_rows
615
+ ):
616
+ raise TypeError("eligible_rows must contain exact archive-aware rows")
617
+ expected_rows = _canonical_rows(
618
+ tuple(value.pair for value in self.eligible_rows),
619
+ self.source_utilities,
620
+ )
621
+ if self.eligible_rows != expected_rows:
622
+ raise ValueError("eligible_rows differ from utility and pair evidence")
623
+ exploit, coverage = _select_rows(expected_rows)
624
+ expected_exploit = None if exploit is None else exploit.pair_ids
625
+ expected_coverage = None if coverage is None else coverage.pair_ids
626
+ if self.exploit_pair_ids != expected_exploit:
627
+ raise ValueError("exploit_pair_ids do not match frozen source utility")
628
+ if self.coverage_pair_ids != expected_coverage:
629
+ raise ValueError("coverage_pair_ids do not match structural coverage")
630
+
631
+ def revalidate(self) -> None:
632
+ if type(self) is not ArchiveAwareDisjointPairSelectionDecision:
633
+ raise TypeError("decision must be exact archive-aware decision")
634
+ ArchiveAwareDisjointPairSelectionDecision.__post_init__(self)
635
+
636
+ def _row_for(
637
+ self,
638
+ pair_ids: tuple[CandidateId, CandidateId] | None,
639
+ ) -> ArchiveAwareDisjointPairScoreRow | None:
640
+ if pair_ids is None:
641
+ return None
642
+ return next(value for value in self.eligible_rows if value.pair_ids == pair_ids)
643
+
644
+ @property
645
+ def exploit(self) -> ArchiveAwareDisjointPairScoreRow | None:
646
+ self.revalidate()
647
+ return self._row_for(self.exploit_pair_ids)
648
+
649
+ @property
650
+ def coverage(self) -> ArchiveAwareDisjointPairScoreRow | None:
651
+ self.revalidate()
652
+ return self._row_for(self.coverage_pair_ids)
653
+
654
+ def _unsigned_record(self) -> dict[str, object]:
655
+ self.revalidate()
656
+ exploit = self._row_for(self.exploit_pair_ids)
657
+ coverage = self._row_for(self.coverage_pair_ids)
658
+ exploit_target = (
659
+ None if exploit is None else exploit.pair.target_configuration_sha256
660
+ )
661
+ return {
662
+ "schema_version": 1,
663
+ "event_type": "archive_aware_recombination_pair_selected",
664
+ "policy_id": self.policy_id,
665
+ "policy_version": self.policy_version,
666
+ "source_utility_receipt": self.source_utilities.to_record(),
667
+ "source_utility_receipt_sha256": self.source_utilities.receipt_sha256,
668
+ "eligible_rows": [
669
+ value.to_record(
670
+ exploit_pair_ids=self.exploit_pair_ids,
671
+ exploit_target_configuration_sha256=exploit_target,
672
+ )
673
+ for value in self.eligible_rows
674
+ ],
675
+ "exploit_pair_ids": (
676
+ None if exploit is None else [value.value for value in exploit.pair_ids]
677
+ ),
678
+ "exploit_exact_joint_source_utility_hex": (
679
+ None
680
+ if exploit is None
681
+ else exploit.exact_joint_source_utility.exact_joint_utility.hex()
682
+ ),
683
+ "coverage_pair_ids": (
684
+ None
685
+ if coverage is None
686
+ else [value.value for value in coverage.pair_ids]
687
+ ),
688
+ "exploit_rule": (
689
+ "maximum exact utility of the two observed sources jointly added "
690
+ "to one frozen archive; maximum observed parent-relative branch-"
691
+ "reward sum only within an exact archive-utility tie; maximum "
692
+ "distinct source roles; canonical candidate IDs"
693
+ ),
694
+ "coverage_rule": (
695
+ "exclude exploit pair; prefer a target-distinct pair; maximum "
696
+ "distinct families; maximum distinct roles; minimum prior "
697
+ "path/family exposure; canonical candidate IDs"
698
+ ),
699
+ "utility_scope": (
700
+ "exact_joint_observed_sources_only_not_unseen_recombination_child_"
701
+ "performance; branch_reward_sum_is_secondary_exact_tie_break_only; "
702
+ "marginal_utility_sum_is_diagnostic_only"
703
+ ),
704
+ }
705
+
706
+ @property
707
+ def decision_sha256(self) -> str:
708
+ return _hash(_DECISION_DOMAIN, self._unsigned_record())
709
+
710
+ def to_record(self) -> dict[str, object]:
711
+ return {**self._unsigned_record(), "decision_sha256": self.decision_sha256}
712
+
713
+ def to_trace_record(self) -> dict[str, object]:
714
+ """Match the trace surface of the legacy disjoint-pair decision."""
715
+
716
+ return self.to_record()
717
+
718
+ def __eq__(self, other: object) -> bool:
719
+ return (
720
+ type(self) is ArchiveAwareDisjointPairSelectionDecision
721
+ and type(other) is ArchiveAwareDisjointPairSelectionDecision
722
+ and self.decision_sha256 == other.decision_sha256
723
+ )
724
+
725
+ __hash__ = None
726
+
727
+
728
+ @dataclass(frozen=True, slots=True)
729
+ class ArchiveAwareDisjointParentPairPolicy:
730
+ """Select utility exploit first and independent structural coverage second."""
731
+
732
+ policy_id: ClassVar[str] = POLICY_ID
733
+ policy_version: ClassVar[int] = POLICY_VERSION
734
+
735
+ def select(
736
+ self,
737
+ eligible_pairs: Sequence[ReplayVerifiedDisjointPair],
738
+ *,
739
+ source_utilities: FrozenArchiveSourceUtilityReceipt,
740
+ ) -> ArchiveAwareDisjointPairSelectionDecision:
741
+ rows = _canonical_rows(eligible_pairs, source_utilities)
742
+ exploit, coverage = _select_rows(rows)
743
+ return ArchiveAwareDisjointPairSelectionDecision(
744
+ source_utilities=source_utilities,
745
+ eligible_rows=rows,
746
+ exploit_pair_ids=None if exploit is None else exploit.pair_ids,
747
+ coverage_pair_ids=None if coverage is None else coverage.pair_ids,
748
+ )
749
+
750
+
751
+ __all__ = [
752
+ "ArchiveAwareDisjointPairScoreRow",
753
+ "ArchiveAwareDisjointPairSelectionDecision",
754
+ "ArchiveAwareDisjointParentPairPolicy",
755
+ "FrozenArchiveBranchUtility",
756
+ "FrozenArchiveSourcePairUtility",
757
+ "FrozenArchiveSourceUtilityContext",
758
+ "FrozenArchiveSourceUtilityReceipt",
759
+ "ObservedSourceBranch",
760
+ "POLICY_ID",
761
+ "POLICY_VERSION",
762
+ ]