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,1027 @@
1
+ """Protected action-level aggregation of outcome-blind allocation policies.
2
+
3
+ Complete-slate policies are treated as ballots over a shared sealed action
4
+ market. The committee preserves a configurable floor from one forecast-neutral
5
+ ballot, samples a precommitted uniform disagreement audit with exact marginal
6
+ propensities, and fills the remaining exact-K slate by weighted ballot
7
+ consensus. It never observes current candidate outcomes.
8
+
9
+ This is intentionally a generic application policy. It knows no workload,
10
+ objective, model, provider, prompt, or simulator field.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import asyncio
16
+ from dataclasses import dataclass, field
17
+ import hashlib
18
+ from itertools import combinations
19
+ import json
20
+ import math
21
+
22
+ from agent_evolve.domain.typed_json import freeze_json
23
+
24
+ from .materialized_action_broker import (
25
+ MaterializedActionAllocationRequirement,
26
+ MaterializedActionDescriptor,
27
+ MaterializedSlateFeasibilityPort,
28
+ )
29
+ from .residual_portfolio_evolution import (
30
+ MaterializedActionAllocationPolicyPort,
31
+ MaterializedActionProposalBatch,
32
+ ResidualPortfolioDecisionRequest,
33
+ )
34
+
35
+
36
+ PROTECTED_ACTION_COMMITTEE_POLICY_ID = "protected_action_committee"
37
+ PROTECTED_ACTION_COMMITTEE_POLICY_VERSION = 1
38
+ _DEFINITION_DOMAIN = b"agent-evolve:protected-action-committee:v1\x00"
39
+ _AUDIT_PRIORITY_DOMAIN = b"agent-evolve:protected-action-committee-audit:v1\x00"
40
+ _AUDIT_SUBSET_PRIORITY_DOMAIN = (
41
+ b"agent-evolve:protected-action-committee-audit-subset:v1\x00"
42
+ )
43
+ _MAX_FEASIBILITY_REPAIR_TRIALS = 100_000
44
+
45
+
46
+ def _canonical_json(value: object) -> bytes:
47
+ return json.dumps(
48
+ value,
49
+ allow_nan=False,
50
+ ensure_ascii=True,
51
+ separators=(",", ":"),
52
+ sort_keys=True,
53
+ ).encode("ascii")
54
+
55
+
56
+ def _require_sha256(value: str, name: str) -> None:
57
+ if (
58
+ type(value) is not str
59
+ or len(value) != 64
60
+ or any(character not in "0123456789abcdef" for character in value)
61
+ ):
62
+ raise ValueError(f"{name} must be a lowercase SHA-256 hex digest")
63
+
64
+
65
+ @dataclass(frozen=True, slots=True)
66
+ class ActionCommitteeArmBinding:
67
+ """One outcome-blind complete-slate ballot and its prior trust weight."""
68
+
69
+ arm_id: str
70
+ policy: MaterializedActionAllocationPolicyPort = field(
71
+ repr=False,
72
+ compare=False,
73
+ )
74
+ weight: float
75
+ behavior_definition_sha256: str | None = None
76
+
77
+ def __post_init__(self) -> None:
78
+ if type(self.arm_id) is not str or not self.arm_id:
79
+ raise ValueError("arm_id must be non-empty")
80
+ if not isinstance(self.policy, MaterializedActionAllocationPolicyPort):
81
+ raise TypeError("policy must implement its allocation port")
82
+ if type(self.weight) is not float or not math.isfinite(self.weight):
83
+ raise TypeError("weight must be a finite exact float")
84
+ if self.weight <= 0.0:
85
+ raise ValueError("weight must be positive")
86
+ if self.behavior_definition_sha256 is not None:
87
+ _require_sha256(
88
+ self.behavior_definition_sha256,
89
+ "behavior_definition_sha256",
90
+ )
91
+
92
+ def identity_record(self) -> dict[str, object]:
93
+ self.__post_init__()
94
+ return {
95
+ "arm_id": self.arm_id,
96
+ "weight_hex": self.weight.hex(),
97
+ "behavior_definition_sha256": (
98
+ self.policy.definition_sha256
99
+ if self.behavior_definition_sha256 is None
100
+ else self.behavior_definition_sha256
101
+ ),
102
+ "policy": {
103
+ "policy_id": self.policy.policy_id,
104
+ "policy_version": self.policy.policy_version,
105
+ "definition_sha256": self.policy.definition_sha256,
106
+ },
107
+ }
108
+
109
+
110
+ @dataclass(frozen=True, slots=True)
111
+ class _CommitteeAction:
112
+ action: MaterializedActionDescriptor
113
+ arm_ids: tuple[str, ...]
114
+ normalized_weighted_support: float
115
+ effective_support: float
116
+ support_count: int
117
+ protected_member: bool
118
+
119
+ def consensus_key(self) -> tuple[float, float, int, str]:
120
+ return (
121
+ -self.normalized_weighted_support,
122
+ -self.effective_support,
123
+ self.action.native_rank,
124
+ self.action.action_sha256,
125
+ )
126
+
127
+
128
+ @dataclass(frozen=True, slots=True)
129
+ class ProtectedActionCommitteePolicy:
130
+ """Aggregate policy ballots into one protected, auditable exact-K slate.
131
+
132
+ The randomized audit is uniform over feasible audit subsets. Without an
133
+ additional slate constraint, every audit-pool representative has exact
134
+ marginal inclusion probability ``audit_slots / audit_pool_size``.
135
+ Constraint-filtered subset marginals are enumerated and logged exactly.
136
+ The precommitted seed makes the draw replayable while preserving the
137
+ declared randomization distribution.
138
+ """
139
+
140
+ arm_bindings: tuple[ActionCommitteeArmBinding, ...]
141
+ protected_arm_id: str
142
+ protected_slots: int
143
+ audit_slots: int
144
+ audit_seed_sha256: str
145
+ slate_feasibility: MaterializedSlateFeasibilityPort | None = field(
146
+ default=None,
147
+ repr=False,
148
+ compare=False,
149
+ )
150
+ policy_id: str = PROTECTED_ACTION_COMMITTEE_POLICY_ID
151
+ policy_version: int = PROTECTED_ACTION_COMMITTEE_POLICY_VERSION
152
+ definition_sha256: str = field(init=False)
153
+
154
+ def __post_init__(self) -> None:
155
+ if (
156
+ type(self.arm_bindings) is not tuple
157
+ or len(self.arm_bindings) < 2
158
+ or any(
159
+ type(value) is not ActionCommitteeArmBinding
160
+ for value in self.arm_bindings
161
+ )
162
+ ):
163
+ raise TypeError(
164
+ "arm_bindings must contain at least two exact bindings"
165
+ )
166
+ for value in self.arm_bindings:
167
+ value.__post_init__()
168
+ arm_ids = tuple(value.arm_id for value in self.arm_bindings)
169
+ if arm_ids != tuple(sorted(set(arm_ids))):
170
+ raise ValueError("arm bindings must be unique and canonical")
171
+ if (
172
+ type(self.protected_arm_id) is not str
173
+ or self.protected_arm_id not in arm_ids
174
+ ):
175
+ raise ValueError("protected_arm_id must name one bound arm")
176
+ for value, name in (
177
+ (self.protected_slots, "protected_slots"),
178
+ (self.audit_slots, "audit_slots"),
179
+ ):
180
+ if type(value) is not int or value < 0:
181
+ raise ValueError(f"{name} must be a non-negative exact integer")
182
+ _require_sha256(self.audit_seed_sha256, "audit_seed_sha256")
183
+ if self.slate_feasibility is not None:
184
+ if not isinstance(
185
+ self.slate_feasibility,
186
+ MaterializedSlateFeasibilityPort,
187
+ ):
188
+ raise TypeError(
189
+ "slate_feasibility must implement its application port"
190
+ )
191
+ _require_sha256(
192
+ self.slate_feasibility.definition_sha256,
193
+ "slate_feasibility definition_sha256",
194
+ )
195
+ if (
196
+ self.policy_id != PROTECTED_ACTION_COMMITTEE_POLICY_ID
197
+ or self.policy_version
198
+ != PROTECTED_ACTION_COMMITTEE_POLICY_VERSION
199
+ ):
200
+ raise ValueError("committee policy identity is immutable")
201
+ object.__setattr__(
202
+ self,
203
+ "definition_sha256",
204
+ hashlib.sha256(
205
+ _DEFINITION_DOMAIN
206
+ + _canonical_json(
207
+ {
208
+ "schema_version": 1,
209
+ "policy_id": self.policy_id,
210
+ "policy_version": self.policy_version,
211
+ "arms": [
212
+ value.identity_record()
213
+ for value in self.arm_bindings
214
+ ],
215
+ "protected_arm_id": self.protected_arm_id,
216
+ "protected_slots": self.protected_slots,
217
+ "audit_slots": self.audit_slots,
218
+ "audit_seed_sha256": self.audit_seed_sha256,
219
+ "slate_feasibility_definition_sha256": (
220
+ None
221
+ if self.slate_feasibility is None
222
+ else self.slate_feasibility.definition_sha256
223
+ ),
224
+ "consensus": (
225
+ "jaccard_redundancy_adjusted_normalized_weighted_"
226
+ "ballot_membership_then_effective_support_then_"
227
+ "native_rank"
228
+ ),
229
+ "audit": (
230
+ "uniform_over_feasible_disagreement_phenotype_"
231
+ "subsets_with_exact_marginals"
232
+ ),
233
+ "candidate_outcomes_observed": False,
234
+ "workload_model_provider_branches": False,
235
+ }
236
+ )
237
+ ).hexdigest(),
238
+ )
239
+
240
+ @staticmethod
241
+ def _action_market(
242
+ proposals: tuple[MaterializedActionProposalBatch, ...],
243
+ ) -> dict[str, MaterializedActionDescriptor]:
244
+ result: dict[str, MaterializedActionDescriptor] = {}
245
+ for proposal in proposals:
246
+ for action in proposal.actions:
247
+ if action.action_sha256 in result:
248
+ raise ValueError("proposal union repeats an action identity")
249
+ result[action.action_sha256] = action
250
+ return result
251
+
252
+ @staticmethod
253
+ def _phenotype_representatives(
254
+ values: list[_CommitteeAction],
255
+ *,
256
+ normalized_weight_by_arm: dict[str, float],
257
+ effective_vote_by_arm: dict[str, float],
258
+ ) -> list[_CommitteeAction]:
259
+ by_phenotype: dict[str, list[_CommitteeAction]] = {}
260
+ for value in values:
261
+ by_phenotype.setdefault(
262
+ value.action.phenotype_identity_sha256,
263
+ [],
264
+ ).append(value)
265
+ result: list[_CommitteeAction] = []
266
+ for phenotype_values in by_phenotype.values():
267
+ representative = min(
268
+ phenotype_values,
269
+ key=lambda item: item.consensus_key(),
270
+ )
271
+ arm_ids = tuple(
272
+ sorted(
273
+ {
274
+ arm_id
275
+ for value in phenotype_values
276
+ for arm_id in value.arm_ids
277
+ }
278
+ )
279
+ )
280
+ result.append(
281
+ _CommitteeAction(
282
+ action=representative.action,
283
+ arm_ids=arm_ids,
284
+ normalized_weighted_support=math.fsum(
285
+ normalized_weight_by_arm[arm_id]
286
+ for arm_id in arm_ids
287
+ ),
288
+ effective_support=math.fsum(
289
+ effective_vote_by_arm[arm_id]
290
+ for arm_id in arm_ids
291
+ ),
292
+ support_count=len(arm_ids),
293
+ protected_member=any(
294
+ value.protected_member
295
+ for value in phenotype_values
296
+ ),
297
+ )
298
+ )
299
+ return result
300
+
301
+ def _audit_priority(
302
+ self,
303
+ *,
304
+ request_sha256: str,
305
+ phenotype_identity_sha256: str,
306
+ ) -> str:
307
+ return hashlib.sha256(
308
+ _AUDIT_PRIORITY_DOMAIN
309
+ + bytes.fromhex(self.audit_seed_sha256)
310
+ + bytes.fromhex(request_sha256)
311
+ + bytes.fromhex(phenotype_identity_sha256)
312
+ ).hexdigest()
313
+
314
+ def _audit_subset_priority(
315
+ self,
316
+ *,
317
+ request_sha256: str,
318
+ values: tuple[_CommitteeAction, ...],
319
+ ) -> str:
320
+ return hashlib.sha256(
321
+ _AUDIT_SUBSET_PRIORITY_DOMAIN
322
+ + bytes.fromhex(self.audit_seed_sha256)
323
+ + bytes.fromhex(request_sha256)
324
+ + b"".join(
325
+ bytes.fromhex(
326
+ value.action.phenotype_identity_sha256
327
+ )
328
+ for value in sorted(
329
+ values,
330
+ key=lambda item: (
331
+ item.action.phenotype_identity_sha256,
332
+ item.action.action_sha256,
333
+ ),
334
+ )
335
+ )
336
+ ).hexdigest()
337
+
338
+ async def require(
339
+ self,
340
+ request: ResidualPortfolioDecisionRequest,
341
+ proposals: tuple[MaterializedActionProposalBatch, ...],
342
+ ) -> MaterializedActionAllocationRequirement:
343
+ self.__post_init__()
344
+ if type(request) is not ResidualPortfolioDecisionRequest:
345
+ raise TypeError("request must be exact")
346
+ request.__post_init__()
347
+ if type(proposals) is not tuple or not proposals:
348
+ raise ValueError("proposals must be a non-empty exact tuple")
349
+ for proposal in proposals:
350
+ if type(proposal) is not MaterializedActionProposalBatch:
351
+ raise TypeError("proposals must contain exact batches")
352
+ proposal.__post_init__()
353
+ proposal.require_request(request)
354
+ if self.protected_slots + self.audit_slots > request.evaluation_slots:
355
+ raise ValueError(
356
+ "protected and audit slots exceed the evaluation budget"
357
+ )
358
+
359
+ requirements = await asyncio.gather(
360
+ *(
361
+ binding.policy.require(request, proposals)
362
+ for binding in self.arm_bindings
363
+ )
364
+ )
365
+ market = self._action_market(proposals)
366
+ proposal_sha256s = tuple(
367
+ sorted(value.proposal_sha256 for value in proposals)
368
+ )
369
+ requirement_by_arm: dict[
370
+ str,
371
+ MaterializedActionAllocationRequirement,
372
+ ] = {}
373
+ for binding, requirement in zip(
374
+ self.arm_bindings,
375
+ requirements,
376
+ strict=True,
377
+ ):
378
+ if type(requirement) is not MaterializedActionAllocationRequirement:
379
+ raise TypeError("committee arm returned a foreign requirement")
380
+ requirement.__post_init__()
381
+ if (
382
+ requirement.policy_id,
383
+ requirement.policy_version,
384
+ requirement.policy_definition_sha256,
385
+ ) != (
386
+ binding.policy.policy_id,
387
+ binding.policy.policy_version,
388
+ binding.policy.definition_sha256,
389
+ ):
390
+ raise ValueError(
391
+ "committee arm requirement changed its policy identity"
392
+ )
393
+ if (
394
+ requirement.residual_request_sha256
395
+ != request.request_sha256
396
+ or requirement.proposal_sha256s != proposal_sha256s
397
+ ):
398
+ raise ValueError("committee arm requirement changed its cutoff")
399
+ if not set(requirement.required_action_sha256s) <= set(market):
400
+ raise ValueError("committee arm selected outside the market")
401
+ if not requirement.required_action_sha256s:
402
+ raise ValueError("committee arm returned an empty ballot")
403
+ requirement_by_arm[binding.arm_id] = requirement
404
+
405
+ phenotype_ballot_by_arm = {
406
+ binding.arm_id: frozenset(
407
+ market[action_id].phenotype_identity_sha256
408
+ for action_id in requirement_by_arm[
409
+ binding.arm_id
410
+ ].required_action_sha256s
411
+ )
412
+ for binding in self.arm_bindings
413
+ }
414
+
415
+ def ballot_similarity(left_arm: str, right_arm: str) -> float:
416
+ left = phenotype_ballot_by_arm[left_arm]
417
+ right = phenotype_ballot_by_arm[right_arm]
418
+ union = left | right
419
+ if not union:
420
+ raise RuntimeError("committee arm has an empty phenotype ballot")
421
+ return len(left & right) / len(union)
422
+
423
+ similarity_by_arm = {
424
+ binding.arm_id: {
425
+ other.arm_id: ballot_similarity(
426
+ binding.arm_id,
427
+ other.arm_id,
428
+ )
429
+ for other in self.arm_bindings
430
+ }
431
+ for binding in self.arm_bindings
432
+ }
433
+ redundancy_by_arm = {
434
+ binding.arm_id: math.fsum(
435
+ similarity_by_arm[binding.arm_id].values()
436
+ )
437
+ for binding in self.arm_bindings
438
+ }
439
+ effective_weight_by_arm = {
440
+ binding.arm_id: (
441
+ binding.weight / redundancy_by_arm[binding.arm_id]
442
+ )
443
+ for binding in self.arm_bindings
444
+ }
445
+ effective_vote_by_arm = {
446
+ binding.arm_id: 1.0 / redundancy_by_arm[binding.arm_id]
447
+ for binding in self.arm_bindings
448
+ }
449
+ total_weight = math.fsum(effective_weight_by_arm.values())
450
+ normalized_weight_by_arm = {
451
+ arm_id: weight / total_weight
452
+ for arm_id, weight in effective_weight_by_arm.items()
453
+ }
454
+ actions: list[_CommitteeAction] = []
455
+ for action_id, action in sorted(market.items()):
456
+ memberships = tuple(
457
+ binding.arm_id
458
+ for binding in self.arm_bindings
459
+ if action_id
460
+ in requirement_by_arm[
461
+ binding.arm_id
462
+ ].required_action_sha256s
463
+ )
464
+ if not memberships:
465
+ continue
466
+ weighted_support = math.fsum(
467
+ effective_weight_by_arm[arm_id]
468
+ for arm_id in memberships
469
+ )
470
+ effective_support = math.fsum(
471
+ effective_vote_by_arm[arm_id]
472
+ for arm_id in memberships
473
+ )
474
+ actions.append(
475
+ _CommitteeAction(
476
+ action=action,
477
+ arm_ids=memberships,
478
+ normalized_weighted_support=(
479
+ weighted_support / total_weight
480
+ ),
481
+ effective_support=effective_support,
482
+ support_count=len(memberships),
483
+ protected_member=(
484
+ self.protected_arm_id in memberships
485
+ ),
486
+ )
487
+ )
488
+
489
+ representatives = self._phenotype_representatives(
490
+ actions,
491
+ normalized_weight_by_arm=normalized_weight_by_arm,
492
+ effective_vote_by_arm=effective_vote_by_arm,
493
+ )
494
+ if len(representatives) < request.evaluation_slots:
495
+ raise ValueError(
496
+ "committee ballot union has too few unique phenotypes"
497
+ )
498
+ selected: list[_CommitteeAction] = []
499
+ selected_phenotypes: set[str] = set()
500
+ selection_kind: dict[str, str] = {}
501
+
502
+ def append(value: _CommitteeAction, kind: str) -> None:
503
+ phenotype = value.action.phenotype_identity_sha256
504
+ if phenotype in selected_phenotypes:
505
+ raise RuntimeError("committee selected one phenotype twice")
506
+ selected.append(value)
507
+ selected_phenotypes.add(phenotype)
508
+ selection_kind[value.action.action_sha256] = kind
509
+
510
+ protected = sorted(
511
+ (
512
+ value
513
+ for value in representatives
514
+ if value.protected_member
515
+ ),
516
+ key=lambda value: value.consensus_key(),
517
+ )
518
+ if len(protected) < self.protected_slots:
519
+ raise ValueError("protected ballot cannot satisfy its floor")
520
+ for value in protected[: self.protected_slots]:
521
+ append(value, "protected_floor")
522
+
523
+ for value in sorted(
524
+ representatives,
525
+ key=lambda item: item.consensus_key(),
526
+ ):
527
+ if len(selected) == request.evaluation_slots:
528
+ break
529
+ if (
530
+ value.action.phenotype_identity_sha256
531
+ in selected_phenotypes
532
+ ):
533
+ continue
534
+ append(value, "weighted_consensus")
535
+ if len(selected) != request.evaluation_slots:
536
+ raise RuntimeError(
537
+ "committee failed to construct its deterministic baseline"
538
+ )
539
+ feasibility_replacements: list[dict[str, object]] = []
540
+
541
+ def slate_permitted(values: list[_CommitteeAction]) -> bool:
542
+ return (
543
+ self.slate_feasibility is None
544
+ or self.slate_feasibility.permits(
545
+ tuple(value.action for value in values)
546
+ )
547
+ )
548
+
549
+ if not slate_permitted(selected):
550
+ repairable = tuple(
551
+ value
552
+ for value in selected
553
+ if selection_kind[value.action.action_sha256]
554
+ != "protected_floor"
555
+ )
556
+ repair_candidates = tuple(
557
+ sorted(
558
+ (
559
+ value
560
+ for value in representatives
561
+ if value.action.phenotype_identity_sha256
562
+ not in selected_phenotypes
563
+ ),
564
+ key=lambda value: value.consensus_key(),
565
+ )
566
+ )
567
+ repaired: tuple[
568
+ tuple[_CommitteeAction, ...],
569
+ tuple[_CommitteeAction, ...],
570
+ list[_CommitteeAction],
571
+ ] | None = None
572
+ repair_trials = 0
573
+ for swap_count in range(
574
+ 1,
575
+ min(len(repairable), len(repair_candidates)) + 1,
576
+ ):
577
+ for removed in combinations(repairable, swap_count):
578
+ removed_ids = {
579
+ value.action.action_sha256 for value in removed
580
+ }
581
+ fixed = [
582
+ value
583
+ for value in selected
584
+ if value.action.action_sha256 not in removed_ids
585
+ ]
586
+ fixed_phenotypes = {
587
+ value.action.phenotype_identity_sha256
588
+ for value in fixed
589
+ }
590
+ eligible_candidates = tuple(
591
+ value
592
+ for value in repair_candidates
593
+ if value.action.phenotype_identity_sha256
594
+ not in fixed_phenotypes
595
+ )
596
+ for inserted in combinations(
597
+ eligible_candidates,
598
+ swap_count,
599
+ ):
600
+ repair_trials += 1
601
+ if (
602
+ repair_trials
603
+ > _MAX_FEASIBILITY_REPAIR_TRIALS
604
+ ):
605
+ raise ValueError(
606
+ "committee feasibility repair exceeded "
607
+ "its declared trial bound"
608
+ )
609
+ trial = [*fixed, *inserted]
610
+ if len(
611
+ {
612
+ value.action.phenotype_identity_sha256
613
+ for value in trial
614
+ }
615
+ ) != request.evaluation_slots:
616
+ continue
617
+ if slate_permitted(trial):
618
+ repaired = (removed, inserted, trial)
619
+ break
620
+ if repaired is not None:
621
+ break
622
+ if repaired is not None:
623
+ break
624
+ if repaired is None:
625
+ raise ValueError(
626
+ "committee cannot satisfy final slate feasibility "
627
+ "without displacing its protected floor"
628
+ )
629
+ removed, inserted, selected = repaired
630
+ for value in removed:
631
+ selection_kind.pop(value.action.action_sha256)
632
+ for value in inserted:
633
+ selection_kind[
634
+ value.action.action_sha256
635
+ ] = "feasibility_repair"
636
+ selected_phenotypes = {
637
+ value.action.phenotype_identity_sha256
638
+ for value in selected
639
+ }
640
+ feasibility_replacements.append(
641
+ {
642
+ "removed_action_sha256s": sorted(
643
+ value.action.action_sha256
644
+ for value in removed
645
+ ),
646
+ "inserted_action_sha256s": sorted(
647
+ value.action.action_sha256
648
+ for value in inserted
649
+ ),
650
+ "swap_count": len(removed),
651
+ "trials": repair_trials,
652
+ }
653
+ )
654
+ baseline_action_sha256s = tuple(
655
+ sorted(value.action.action_sha256 for value in selected)
656
+ )
657
+
658
+ audit_pool = sorted(
659
+ (
660
+ value
661
+ for value in representatives
662
+ if (
663
+ value.action.phenotype_identity_sha256
664
+ not in selected_phenotypes
665
+ and value.support_count < len(self.arm_bindings)
666
+ )
667
+ ),
668
+ key=lambda value: value.action.action_sha256,
669
+ )
670
+ replaceable = [
671
+ value
672
+ for value in selected
673
+ if selection_kind[value.action.action_sha256]
674
+ != "protected_floor"
675
+ ]
676
+ effective_audit_slots = min(
677
+ self.audit_slots,
678
+ len(audit_pool),
679
+ len(replaceable),
680
+ )
681
+ audit_priority = {
682
+ value.action.action_sha256: self._audit_priority(
683
+ request_sha256=request.request_sha256,
684
+ phenotype_identity_sha256=(
685
+ value.action.phenotype_identity_sha256
686
+ ),
687
+ )
688
+ for value in audit_pool
689
+ }
690
+ sampled_audit: tuple[_CommitteeAction, ...] = ()
691
+ replaced_baseline: list[_CommitteeAction] = []
692
+ valid_audit_subset_count = 1
693
+ audit_marginal_by_action = {
694
+ value.action.action_sha256: 0.0 for value in audit_pool
695
+ }
696
+ sampled_subset_priority = self._audit_subset_priority(
697
+ request_sha256=request.request_sha256,
698
+ values=(),
699
+ )
700
+ while True:
701
+ replaced_baseline = sorted(
702
+ replaceable,
703
+ key=lambda item: item.consensus_key(),
704
+ reverse=True,
705
+ )[:effective_audit_slots]
706
+ replaced_ids_for_trial = {
707
+ value.action.action_sha256
708
+ for value in replaced_baseline
709
+ }
710
+ fixed_for_trial = [
711
+ value
712
+ for value in selected
713
+ if value.action.action_sha256
714
+ not in replaced_ids_for_trial
715
+ ]
716
+ if self.slate_feasibility is None:
717
+ valid_audit_subset_count = math.comb(
718
+ len(audit_pool),
719
+ effective_audit_slots,
720
+ )
721
+ sampled_audit = tuple(
722
+ sorted(
723
+ audit_pool,
724
+ key=lambda item: (
725
+ audit_priority[
726
+ item.action.action_sha256
727
+ ],
728
+ item.action.action_sha256,
729
+ ),
730
+ )[:effective_audit_slots]
731
+ )
732
+ marginal = (
733
+ 0.0
734
+ if not audit_pool
735
+ else effective_audit_slots / len(audit_pool)
736
+ )
737
+ audit_marginal_by_action = {
738
+ value.action.action_sha256: marginal
739
+ for value in audit_pool
740
+ }
741
+ sampled_subset_priority = (
742
+ self._audit_subset_priority(
743
+ request_sha256=request.request_sha256,
744
+ values=sampled_audit,
745
+ )
746
+ )
747
+ break
748
+
749
+ subset_count = math.comb(
750
+ len(audit_pool),
751
+ effective_audit_slots,
752
+ )
753
+ if subset_count > _MAX_FEASIBILITY_REPAIR_TRIALS:
754
+ raise ValueError(
755
+ "feasibility-constrained audit subset count exceeds "
756
+ "its declared exact-enumeration bound"
757
+ )
758
+ valid_subsets = tuple(
759
+ subset
760
+ for subset in combinations(
761
+ audit_pool,
762
+ effective_audit_slots,
763
+ )
764
+ if slate_permitted(
765
+ [*fixed_for_trial, *subset]
766
+ )
767
+ )
768
+ if valid_subsets:
769
+ valid_audit_subset_count = len(valid_subsets)
770
+ sampled_audit = min(
771
+ valid_subsets,
772
+ key=lambda subset: (
773
+ self._audit_subset_priority(
774
+ request_sha256=request.request_sha256,
775
+ values=subset,
776
+ ),
777
+ tuple(
778
+ value.action.action_sha256
779
+ for value in subset
780
+ ),
781
+ ),
782
+ )
783
+ sampled_subset_priority = (
784
+ self._audit_subset_priority(
785
+ request_sha256=request.request_sha256,
786
+ values=sampled_audit,
787
+ )
788
+ )
789
+ audit_marginal_by_action = {
790
+ value.action.action_sha256: (
791
+ sum(
792
+ value in subset
793
+ for subset in valid_subsets
794
+ )
795
+ / valid_audit_subset_count
796
+ )
797
+ for value in audit_pool
798
+ }
799
+ break
800
+ if effective_audit_slots == 0:
801
+ raise RuntimeError(
802
+ "feasible deterministic baseline became infeasible"
803
+ )
804
+ effective_audit_slots -= 1
805
+
806
+ audit_probabilities = set(
807
+ audit_marginal_by_action.values()
808
+ )
809
+ common_audit_probability = (
810
+ next(iter(audit_probabilities))
811
+ if len(audit_probabilities) == 1
812
+ else None
813
+ )
814
+ replaced_ids = {
815
+ value.action.action_sha256 for value in replaced_baseline
816
+ }
817
+ selected = [
818
+ value
819
+ for value in selected
820
+ if value.action.action_sha256 not in replaced_ids
821
+ ]
822
+ for value in replaced_baseline:
823
+ selected_phenotypes.remove(
824
+ value.action.phenotype_identity_sha256
825
+ )
826
+ selection_kind.pop(value.action.action_sha256)
827
+ for value in sampled_audit:
828
+ append(value, "randomized_disagreement_audit")
829
+ if len(selected) != request.evaluation_slots:
830
+ raise RuntimeError("committee failed to fill the exact-K slate")
831
+ if not slate_permitted(selected):
832
+ raise RuntimeError("committee emitted an infeasible final slate")
833
+
834
+ selected_ids = tuple(
835
+ sorted(value.action.action_sha256 for value in selected)
836
+ )
837
+ selected_order = {
838
+ value.action.action_sha256: ordinal
839
+ for ordinal, value in enumerate(selected, start=1)
840
+ }
841
+ evidence = freeze_json(
842
+ {
843
+ "schema_version": 1,
844
+ "candidate_outcomes_observed": False,
845
+ "workload_model_provider_branches": False,
846
+ "selection_trace": [
847
+ {
848
+ "ordinal": selected_order[
849
+ value.action.action_sha256
850
+ ],
851
+ "action_sha256": value.action.action_sha256,
852
+ "allocation_kind": selection_kind[
853
+ value.action.action_sha256
854
+ ],
855
+ "support_count": value.support_count,
856
+ "arm_ids": list(value.arm_ids),
857
+ "audit_marginal_inclusion_probability_hex": (
858
+ audit_marginal_by_action[
859
+ value.action.action_sha256
860
+ ].hex()
861
+ if value in audit_pool
862
+ else (0.0).hex()
863
+ ),
864
+ "candidate_outcomes_observed": False,
865
+ }
866
+ for value in sorted(
867
+ selected,
868
+ key=lambda item: selected_order[
869
+ item.action.action_sha256
870
+ ],
871
+ )
872
+ ],
873
+ "committee": {
874
+ "protected_arm_id": self.protected_arm_id,
875
+ "configured_protected_slots": self.protected_slots,
876
+ "configured_audit_slots": self.audit_slots,
877
+ "effective_audit_slots": effective_audit_slots,
878
+ "audit_pool_size": len(audit_pool),
879
+ "audit_marginal_inclusion_probability_hex": (
880
+ None
881
+ if common_audit_probability is None
882
+ else common_audit_probability.hex()
883
+ ),
884
+ "valid_audit_subset_count": (
885
+ valid_audit_subset_count
886
+ ),
887
+ "audit_seed_sha256": self.audit_seed_sha256,
888
+ "sampled_audit_subset_priority_sha256": (
889
+ sampled_subset_priority
890
+ ),
891
+ "audit_randomization_distribution": (
892
+ "uniform_over_feasible_unselected_disagreement_"
893
+ "phenotype_subsets_with_fixed_baseline_swaps"
894
+ ),
895
+ "deterministic_baseline_action_sha256s": list(
896
+ baseline_action_sha256s
897
+ ),
898
+ "feasibility_replacements": (
899
+ feasibility_replacements
900
+ ),
901
+ "slate_feasibility_definition_sha256": (
902
+ None
903
+ if self.slate_feasibility is None
904
+ else self.slate_feasibility.definition_sha256
905
+ ),
906
+ "replaced_baseline_action_sha256s": sorted(replaced_ids),
907
+ "exact_action_set_propensity": (
908
+ 1.0 / valid_audit_subset_count
909
+ ).hex(),
910
+ },
911
+ "arms": [
912
+ {
913
+ **binding.identity_record(),
914
+ "phenotype_ballot_size": len(
915
+ phenotype_ballot_by_arm[binding.arm_id]
916
+ ),
917
+ "behavioral_redundancy_hex": (
918
+ redundancy_by_arm[binding.arm_id].hex()
919
+ ),
920
+ "effective_weight_hex": (
921
+ effective_weight_by_arm[binding.arm_id].hex()
922
+ ),
923
+ "pairwise_jaccard_similarity_hex": {
924
+ other_arm_id: similarity.hex()
925
+ for other_arm_id, similarity in sorted(
926
+ similarity_by_arm[
927
+ binding.arm_id
928
+ ].items()
929
+ )
930
+ },
931
+ "requirement_sha256": requirement_by_arm[
932
+ binding.arm_id
933
+ ].requirement_sha256,
934
+ "required_action_sha256s": list(
935
+ requirement_by_arm[
936
+ binding.arm_id
937
+ ].required_action_sha256s
938
+ ),
939
+ }
940
+ for binding in self.arm_bindings
941
+ ],
942
+ "ballot_union": [
943
+ {
944
+ "action_sha256": value.action.action_sha256,
945
+ "phenotype_identity_sha256": (
946
+ value.action.phenotype_identity_sha256
947
+ ),
948
+ "arm_ids": list(value.arm_ids),
949
+ "normalized_weighted_support_hex": (
950
+ value.normalized_weighted_support.hex()
951
+ ),
952
+ "effective_support_hex": (
953
+ value.effective_support.hex()
954
+ ),
955
+ "support_count": value.support_count,
956
+ "protected_member": value.protected_member,
957
+ "audit_eligible": (
958
+ value in audit_pool
959
+ and audit_marginal_by_action[
960
+ value.action.action_sha256
961
+ ]
962
+ > 0.0
963
+ ),
964
+ "audit_priority_sha256": audit_priority.get(
965
+ value.action.action_sha256
966
+ ),
967
+ "audit_marginal_inclusion_probability_hex": (
968
+ audit_marginal_by_action[
969
+ value.action.action_sha256
970
+ ].hex()
971
+ if value in audit_pool
972
+ else (0.0).hex()
973
+ ),
974
+ "final_marginal_inclusion_probability_hex": (
975
+ audit_marginal_by_action[
976
+ value.action.action_sha256
977
+ ].hex()
978
+ if value in audit_pool
979
+ else (
980
+ 0.0
981
+ if value.action.action_sha256 in replaced_ids
982
+ else (
983
+ 1.0
984
+ if value.action.action_sha256
985
+ in baseline_action_sha256s
986
+ else 0.0
987
+ )
988
+ ).hex()
989
+ ),
990
+ "selected": (
991
+ value.action.action_sha256 in selected_order
992
+ ),
993
+ "selected_ordinal": selected_order.get(
994
+ value.action.action_sha256
995
+ ),
996
+ "selection_kind": selection_kind.get(
997
+ value.action.action_sha256
998
+ ),
999
+ }
1000
+ for value in sorted(
1001
+ representatives,
1002
+ key=lambda item: item.action.action_sha256,
1003
+ )
1004
+ ],
1005
+ "exact_k": request.evaluation_slots,
1006
+ "unique_phenotype_selection": True,
1007
+ "unselected_candidate_outcomes_observed": False,
1008
+ }
1009
+ )
1010
+ return MaterializedActionAllocationRequirement(
1011
+ policy_id=self.policy_id,
1012
+ policy_version=self.policy_version,
1013
+ policy_definition_sha256=self.definition_sha256,
1014
+ residual_request_sha256=request.request_sha256,
1015
+ proposal_sha256s=proposal_sha256s,
1016
+ required_action_sha256s=selected_ids,
1017
+ candidate_outcomes_observed=False,
1018
+ evidence=evidence,
1019
+ )
1020
+
1021
+
1022
+ __all__ = [
1023
+ "ActionCommitteeArmBinding",
1024
+ "PROTECTED_ACTION_COMMITTEE_POLICY_ID",
1025
+ "PROTECTED_ACTION_COMMITTEE_POLICY_VERSION",
1026
+ "ProtectedActionCommitteePolicy",
1027
+ ]