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,479 @@
1
+ """Deterministic exploit/coverage choice over replay-verified disjoint pairs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import math
8
+ import re
9
+ from dataclasses import dataclass
10
+ from numbers import Real
11
+ from typing import ClassVar, Sequence
12
+
13
+ from agent_evolve.domain.ids import CandidateId
14
+ from agent_evolve.domain.patch import require_sha256
15
+
16
+
17
+ POLICY_ID = "disjoint_parent_pair_exploit_coverage"
18
+ POLICY_VERSION = 1
19
+ _DECISION_DOMAIN = b"agent-evolve:disjoint-parent-pair-decision:v1\x00"
20
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
21
+ _MAX_EXPOSURE = (1 << 63) - 1
22
+
23
+
24
+ def _token(value: str, *, name: str) -> None:
25
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
26
+ raise ValueError(f"{name} must use the closed lowercase token grammar")
27
+
28
+
29
+ def _finite_float(value: Real, *, name: str) -> float:
30
+ if isinstance(value, bool) or not isinstance(value, Real):
31
+ raise TypeError(f"{name} must be a real number")
32
+ result = float(value)
33
+ if not math.isfinite(result):
34
+ raise ValueError(f"{name} must be finite")
35
+ return result
36
+
37
+
38
+ def _count(value: int, *, name: str) -> None:
39
+ if type(value) is not int or not 0 <= value <= _MAX_EXPOSURE:
40
+ raise ValueError(f"{name} must be an exact non-negative int63")
41
+
42
+
43
+ @dataclass(frozen=True, slots=True)
44
+ class DisjointBranchFacts:
45
+ """Pre-outcome facts for one valid, operator-compliant G1 branch."""
46
+
47
+ candidate_id: CandidateId
48
+ reward: float
49
+ role: str
50
+ family: str
51
+ path_family_exposure: int
52
+
53
+ def __post_init__(self) -> None:
54
+ if type(self.candidate_id) is not CandidateId:
55
+ raise TypeError("candidate_id must be an exact CandidateId")
56
+ CandidateId.__post_init__(self.candidate_id)
57
+ canonical_reward = _finite_float(self.reward, name="branch reward")
58
+ if type(self.reward) is not float or self.reward != canonical_reward:
59
+ raise TypeError("branch reward must already be a canonical float")
60
+ _token(self.role, name="role")
61
+ _token(self.family, name="family")
62
+ _count(self.path_family_exposure, name="path_family_exposure")
63
+
64
+ def revalidate(self) -> None:
65
+ if type(self) is not DisjointBranchFacts:
66
+ raise TypeError("branch facts must be exact DisjointBranchFacts")
67
+ DisjointBranchFacts.__post_init__(self)
68
+
69
+ def to_trace_record(self) -> dict[str, object]:
70
+ self.revalidate()
71
+ return {
72
+ "candidate_id": self.candidate_id.value,
73
+ "reward": self.reward,
74
+ "role": self.role,
75
+ "family": self.family,
76
+ "path_family_exposure": self.path_family_exposure,
77
+ }
78
+
79
+
80
+ @dataclass(frozen=True, slots=True)
81
+ class ReplayVerifiedDisjointPair:
82
+ """One safe pair plus the exact materialization evidence it produced."""
83
+
84
+ left: DisjointBranchFacts
85
+ right: DisjointBranchFacts
86
+ target_configuration_sha256: str
87
+ materialization_receipt_sha256: str
88
+
89
+ def __post_init__(self) -> None:
90
+ if type(self.left) is not DisjointBranchFacts:
91
+ raise TypeError("left must be exact DisjointBranchFacts")
92
+ if type(self.right) is not DisjointBranchFacts:
93
+ raise TypeError("right must be exact DisjointBranchFacts")
94
+ self.left.revalidate()
95
+ self.right.revalidate()
96
+ if self.left.candidate_id >= self.right.candidate_id:
97
+ raise ValueError(
98
+ "pair branches must be distinct and canonically ordered by candidate ID"
99
+ )
100
+ require_sha256(
101
+ self.target_configuration_sha256,
102
+ "target_configuration_sha256",
103
+ )
104
+ require_sha256(
105
+ self.materialization_receipt_sha256,
106
+ "materialization_receipt_sha256",
107
+ )
108
+
109
+ def revalidate(self) -> None:
110
+ if type(self) is not ReplayVerifiedDisjointPair:
111
+ raise TypeError("eligible pair must be an exact ReplayVerifiedDisjointPair")
112
+ ReplayVerifiedDisjointPair.__post_init__(self)
113
+
114
+ @property
115
+ def pair_ids(self) -> tuple[CandidateId, CandidateId]:
116
+ self.revalidate()
117
+ return self.left.candidate_id, self.right.candidate_id
118
+
119
+ def to_trace_record(self) -> dict[str, object]:
120
+ self.revalidate()
121
+ return {
122
+ "left": self.left.to_trace_record(),
123
+ "right": self.right.to_trace_record(),
124
+ "target_configuration_sha256": self.target_configuration_sha256,
125
+ "materialization_receipt_sha256": (self.materialization_receipt_sha256),
126
+ }
127
+
128
+
129
+ def _pair_key(pair: ReplayVerifiedDisjointPair) -> tuple[str, str]:
130
+ pair.revalidate()
131
+ return pair.left.candidate_id.value, pair.right.candidate_id.value
132
+
133
+
134
+ @dataclass(frozen=True, slots=True, eq=False)
135
+ class DisjointPairScoreRow:
136
+ """Complete score row under both frozen G2 selection rules."""
137
+
138
+ pair: ReplayVerifiedDisjointPair
139
+ branch_reward_sum: float
140
+ distinct_role_count: int
141
+ distinct_family_count: int
142
+ path_family_exposure_sum: int
143
+
144
+ def __post_init__(self) -> None:
145
+ if type(self.pair) is not ReplayVerifiedDisjointPair:
146
+ raise TypeError("pair must be an exact ReplayVerifiedDisjointPair")
147
+ self.pair.revalidate()
148
+ expected_reward = self.pair.left.reward + self.pair.right.reward
149
+ if not math.isfinite(expected_reward):
150
+ raise ValueError("branch reward sum must be finite")
151
+ if type(self.branch_reward_sum) is not float:
152
+ raise TypeError("branch_reward_sum must be a canonical float")
153
+ if self.branch_reward_sum != expected_reward:
154
+ raise ValueError("branch_reward_sum does not match the branch facts")
155
+ expected_roles = len({self.pair.left.role, self.pair.right.role})
156
+ if (
157
+ type(self.distinct_role_count) is not int
158
+ or self.distinct_role_count != expected_roles
159
+ ):
160
+ raise ValueError("distinct_role_count does not match the branch facts")
161
+ expected_families = len({self.pair.left.family, self.pair.right.family})
162
+ if (
163
+ type(self.distinct_family_count) is not int
164
+ or self.distinct_family_count != expected_families
165
+ ):
166
+ raise ValueError("distinct_family_count does not match the branch facts")
167
+ expected_exposure = (
168
+ self.pair.left.path_family_exposure + self.pair.right.path_family_exposure
169
+ )
170
+ _count(expected_exposure, name="aggregated pair exposure")
171
+ if (
172
+ type(self.path_family_exposure_sum) is not int
173
+ or self.path_family_exposure_sum != expected_exposure
174
+ ):
175
+ raise ValueError("path_family_exposure_sum does not match the branch facts")
176
+
177
+ def revalidate(self) -> None:
178
+ if type(self) is not DisjointPairScoreRow:
179
+ raise TypeError("score row must be an exact DisjointPairScoreRow")
180
+ DisjointPairScoreRow.__post_init__(self)
181
+
182
+ @property
183
+ def pair_ids(self) -> tuple[CandidateId, CandidateId]:
184
+ self.revalidate()
185
+ return self.pair.pair_ids
186
+
187
+ def _key(self) -> tuple[object, ...]:
188
+ self.revalidate()
189
+ return (
190
+ *_pair_key(self.pair),
191
+ self.pair.target_configuration_sha256,
192
+ self.pair.materialization_receipt_sha256,
193
+ self.branch_reward_sum,
194
+ self.distinct_role_count,
195
+ self.distinct_family_count,
196
+ self.path_family_exposure_sum,
197
+ )
198
+
199
+ def __eq__(self, other: object) -> bool:
200
+ return (
201
+ type(self) is DisjointPairScoreRow
202
+ and type(other) is DisjointPairScoreRow
203
+ and self._key() == other._key()
204
+ )
205
+
206
+ __hash__ = None
207
+
208
+ def to_trace_record(
209
+ self,
210
+ *,
211
+ exploit_target_configuration_sha256: str | None,
212
+ ) -> dict[str, object]:
213
+ self.revalidate()
214
+ if exploit_target_configuration_sha256 is not None:
215
+ require_sha256(
216
+ exploit_target_configuration_sha256,
217
+ "exploit_target_configuration_sha256",
218
+ )
219
+ return {
220
+ **self.pair.to_trace_record(),
221
+ "branch_reward_sum": self.branch_reward_sum,
222
+ "distinct_role_count": self.distinct_role_count,
223
+ "distinct_family_count": self.distinct_family_count,
224
+ "path_family_exposure_sum": self.path_family_exposure_sum,
225
+ "target_distinct_from_exploit": (
226
+ None
227
+ if exploit_target_configuration_sha256 is None
228
+ else self.pair.target_configuration_sha256
229
+ != exploit_target_configuration_sha256
230
+ ),
231
+ "exploit_tie_key": [
232
+ -self.branch_reward_sum,
233
+ -self.distinct_role_count,
234
+ self.pair.left.candidate_id.value,
235
+ self.pair.right.candidate_id.value,
236
+ ],
237
+ "coverage_tie_key": [
238
+ -self.distinct_family_count,
239
+ -self.distinct_role_count,
240
+ self.path_family_exposure_sum,
241
+ self.pair.left.candidate_id.value,
242
+ self.pair.right.candidate_id.value,
243
+ ],
244
+ }
245
+
246
+
247
+ def _score_row(pair: ReplayVerifiedDisjointPair) -> DisjointPairScoreRow:
248
+ pair.revalidate()
249
+ reward_sum = pair.left.reward + pair.right.reward
250
+ if not math.isfinite(reward_sum):
251
+ raise ValueError("branch reward sum must be finite")
252
+ exposure_sum = pair.left.path_family_exposure + pair.right.path_family_exposure
253
+ _count(exposure_sum, name="aggregated pair exposure")
254
+ return DisjointPairScoreRow(
255
+ pair=pair,
256
+ branch_reward_sum=float(reward_sum),
257
+ distinct_role_count=len({pair.left.role, pair.right.role}),
258
+ distinct_family_count=len({pair.left.family, pair.right.family}),
259
+ path_family_exposure_sum=exposure_sum,
260
+ )
261
+
262
+
263
+ def _canonical_rows(
264
+ pairs: Sequence[ReplayVerifiedDisjointPair],
265
+ ) -> tuple[DisjointPairScoreRow, ...]:
266
+ if isinstance(pairs, (str, bytes)):
267
+ raise TypeError("eligible_pairs must be a finite pair sequence")
268
+ values = tuple(pairs)
269
+ for pair in values:
270
+ if type(pair) is not ReplayVerifiedDisjointPair:
271
+ raise TypeError(
272
+ "eligible_pairs must contain exact ReplayVerifiedDisjointPair values"
273
+ )
274
+ pair.revalidate()
275
+ keys = [_pair_key(pair) for pair in values]
276
+ if len(set(keys)) != len(keys):
277
+ raise ValueError("eligible pair candidate-ID sets must be unique")
278
+ receipts = [pair.materialization_receipt_sha256 for pair in values]
279
+ if len(set(receipts)) != len(receipts):
280
+ raise ValueError("materialization receipts must be unique across pairs")
281
+
282
+ candidate_facts: dict[str, DisjointBranchFacts] = {}
283
+ for pair in values:
284
+ for branch in (pair.left, pair.right):
285
+ candidate_key = branch.candidate_id.value
286
+ existing = candidate_facts.get(candidate_key)
287
+ if existing is not None and existing != branch:
288
+ raise ValueError(
289
+ "one candidate has inconsistent branch facts across eligible pairs"
290
+ )
291
+ candidate_facts[candidate_key] = branch
292
+ return tuple(
293
+ sorted(
294
+ (_score_row(pair) for pair in values), key=lambda row: _pair_key(row.pair)
295
+ )
296
+ )
297
+
298
+
299
+ def _select_rows(
300
+ rows: tuple[DisjointPairScoreRow, ...],
301
+ ) -> tuple[DisjointPairScoreRow | None, DisjointPairScoreRow | None]:
302
+ if not rows:
303
+ return None, None
304
+ exploit = min(
305
+ rows,
306
+ key=lambda row: (
307
+ -row.branch_reward_sum,
308
+ -row.distinct_role_count,
309
+ *_pair_key(row.pair),
310
+ ),
311
+ )
312
+ coverage_pool = tuple(
313
+ row
314
+ for row in rows
315
+ if row.pair.target_configuration_sha256
316
+ != exploit.pair.target_configuration_sha256
317
+ )
318
+ if not coverage_pool:
319
+ return exploit, None
320
+ coverage = min(
321
+ coverage_pool,
322
+ key=lambda row: (
323
+ -row.distinct_family_count,
324
+ -row.distinct_role_count,
325
+ row.path_family_exposure_sum,
326
+ *_pair_key(row.pair),
327
+ ),
328
+ )
329
+ return exploit, coverage
330
+
331
+
332
+ @dataclass(frozen=True, slots=True, eq=False)
333
+ class DisjointPairSelectionDecision:
334
+ """All eligible score rows and the exact exploit/coverage selections."""
335
+
336
+ eligible_rows: tuple[DisjointPairScoreRow, ...]
337
+ exploit_pair_ids: tuple[CandidateId, CandidateId] | None
338
+ coverage_pair_ids: tuple[CandidateId, CandidateId] | None
339
+
340
+ policy_id: ClassVar[str] = POLICY_ID
341
+ policy_version: ClassVar[int] = POLICY_VERSION
342
+
343
+ def __post_init__(self) -> None:
344
+ if type(self.eligible_rows) is not tuple or any(
345
+ type(row) is not DisjointPairScoreRow for row in self.eligible_rows
346
+ ):
347
+ raise TypeError(
348
+ "eligible_rows must contain exact DisjointPairScoreRow values"
349
+ )
350
+ expected_rows = _canonical_rows(tuple(row.pair for row in self.eligible_rows))
351
+ if self.eligible_rows != expected_rows:
352
+ raise ValueError("eligible_rows must be complete and canonically ordered")
353
+ exploit, coverage = _select_rows(expected_rows)
354
+ expected_exploit = None if exploit is None else exploit.pair_ids
355
+ expected_coverage = None if coverage is None else coverage.pair_ids
356
+ if self.exploit_pair_ids != expected_exploit:
357
+ raise ValueError("exploit_pair_ids do not match the exploit rule")
358
+ if self.coverage_pair_ids != expected_coverage:
359
+ raise ValueError("coverage_pair_ids do not match the coverage rule")
360
+
361
+ def revalidate(self) -> None:
362
+ if type(self) is not DisjointPairSelectionDecision:
363
+ raise TypeError("decision must be an exact DisjointPairSelectionDecision")
364
+ DisjointPairSelectionDecision.__post_init__(self)
365
+
366
+ def _row_for(
367
+ self,
368
+ pair_ids: tuple[CandidateId, CandidateId] | None,
369
+ ) -> DisjointPairScoreRow | None:
370
+ if pair_ids is None:
371
+ return None
372
+ return next(row for row in self.eligible_rows if row.pair_ids == pair_ids)
373
+
374
+ @property
375
+ def exploit(self) -> DisjointPairScoreRow | None:
376
+ self.revalidate()
377
+ return self._row_for(self.exploit_pair_ids)
378
+
379
+ @property
380
+ def coverage(self) -> DisjointPairScoreRow | None:
381
+ self.revalidate()
382
+ return self._row_for(self.coverage_pair_ids)
383
+
384
+ def _trace_payload(self) -> dict[str, object]:
385
+ exploit = self._row_for(self.exploit_pair_ids)
386
+ coverage = self._row_for(self.coverage_pair_ids)
387
+ exploit_target = (
388
+ None if exploit is None else exploit.pair.target_configuration_sha256
389
+ )
390
+ return {
391
+ "event_type": "recombination_pair_selected",
392
+ "policy_id": self.policy_id,
393
+ "policy_version": self.policy_version,
394
+ "eligible_rows": [
395
+ row.to_trace_record(
396
+ exploit_target_configuration_sha256=exploit_target,
397
+ )
398
+ for row in self.eligible_rows
399
+ ],
400
+ "exploit_pair_ids": (
401
+ None
402
+ if exploit is None
403
+ else [candidate_id.value for candidate_id in exploit.pair_ids]
404
+ ),
405
+ "exploit_target_configuration_sha256": exploit_target,
406
+ "coverage_pair_ids": (
407
+ None
408
+ if coverage is None
409
+ else [candidate_id.value for candidate_id in coverage.pair_ids]
410
+ ),
411
+ "coverage_target_configuration_sha256": (
412
+ None if coverage is None else coverage.pair.target_configuration_sha256
413
+ ),
414
+ "exploit_rule": (
415
+ "maximum branch reward sum; maximum distinct roles; "
416
+ "canonical candidate IDs"
417
+ ),
418
+ "coverage_rule": (
419
+ "target configuration distinct from exploit; maximum distinct "
420
+ "families; maximum distinct roles; minimum prior path/family "
421
+ "exposure; canonical candidate IDs"
422
+ ),
423
+ }
424
+
425
+ @property
426
+ def decision_sha256(self) -> str:
427
+ self.revalidate()
428
+ encoded = json.dumps(
429
+ self._trace_payload(),
430
+ allow_nan=False,
431
+ ensure_ascii=True,
432
+ separators=(",", ":"),
433
+ sort_keys=True,
434
+ ).encode("ascii")
435
+ return hashlib.sha256(_DECISION_DOMAIN + encoded).hexdigest()
436
+
437
+ def to_trace_record(self) -> dict[str, object]:
438
+ self.revalidate()
439
+ return {**self._trace_payload(), "decision_sha256": self.decision_sha256}
440
+
441
+ def __eq__(self, other: object) -> bool:
442
+ return (
443
+ type(self) is DisjointPairSelectionDecision
444
+ and type(other) is DisjointPairSelectionDecision
445
+ and self.decision_sha256 == other.decision_sha256
446
+ )
447
+
448
+ __hash__ = None
449
+
450
+
451
+ @dataclass(frozen=True, slots=True)
452
+ class DisjointParentPairPolicy:
453
+ """Select exploit first and a target-distinct coverage pair second."""
454
+
455
+ policy_id: ClassVar[str] = POLICY_ID
456
+ policy_version: ClassVar[int] = POLICY_VERSION
457
+
458
+ def select(
459
+ self,
460
+ eligible_pairs: Sequence[ReplayVerifiedDisjointPair],
461
+ ) -> DisjointPairSelectionDecision:
462
+ rows = _canonical_rows(eligible_pairs)
463
+ exploit, coverage = _select_rows(rows)
464
+ return DisjointPairSelectionDecision(
465
+ eligible_rows=rows,
466
+ exploit_pair_ids=None if exploit is None else exploit.pair_ids,
467
+ coverage_pair_ids=None if coverage is None else coverage.pair_ids,
468
+ )
469
+
470
+
471
+ __all__ = [
472
+ "DisjointBranchFacts",
473
+ "DisjointPairScoreRow",
474
+ "DisjointPairSelectionDecision",
475
+ "DisjointParentPairPolicy",
476
+ "POLICY_ID",
477
+ "POLICY_VERSION",
478
+ "ReplayVerifiedDisjointPair",
479
+ ]