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,640 @@
1
+ """Authenticated inner-policy inputs for calibrated portfolio allocation.
2
+
3
+ The provider adapter must freeze this binding before it sends a prompt. It
4
+ therefore cannot choose structural evidence after observing the model's slate,
5
+ and the model cannot author calibration, objective, or archive facts.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import hashlib
11
+ import json
12
+ import re
13
+ from collections.abc import Callable
14
+ from dataclasses import dataclass
15
+
16
+ from agent_evolve.domain.finite_variation import FiniteVariationOption
17
+ from agent_evolve.domain.patch import require_sha256
18
+ from agent_evolve.policies.selection.calibrated_slate import (
19
+ SlateMetricObjective,
20
+ SlateStructuralEvidence,
21
+ )
22
+ from agent_evolve.policies.selection.forecast_calibration import (
23
+ ForecastCalibrationScope,
24
+ ForecastCalibrationSnapshot,
25
+ )
26
+ from agent_evolve.policies.selection.proposal_support import (
27
+ ProposalSupportCandidate,
28
+ ProposalSupportDecision,
29
+ StructuralProposalSupportPolicy,
30
+ )
31
+ from agent_evolve.policies.selection.finite_option_prompt_projection import (
32
+ FiniteOptionPromptProjection,
33
+ )
34
+ from agent_evolve.policies.selection.common_candidate_pool import (
35
+ CommonCandidatePoolDecision,
36
+ TaskKeyedCommonCandidatePoolPolicy,
37
+ )
38
+ from agent_evolve.policies.variation.compositional_finite_catalog import (
39
+ COMPOSITION_REQUIRED_PROPOSALS_METADATA_KEY,
40
+ COMPOSITION_SELECTION_EXPOSURE_METADATA_KEY,
41
+ CompositionSelectionExposure,
42
+ )
43
+ from agent_evolve.policies.variation.source_union_finite_catalog import (
44
+ required_source_evaluation_option_ids,
45
+ )
46
+ from agent_evolve.ports.portfolio_selection import PortfolioSelectionRequest
47
+ from agent_evolve.ports.contextual_search_allocation import (
48
+ ContextualPortfolioAllocationContract,
49
+ )
50
+ from agent_evolve.ports.variation_source import (
51
+ finite_variation_candidate_pool_required_option_ids,
52
+ )
53
+
54
+
55
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
56
+ _OPTION_ID = re.compile(r"^[a-z][a-z0-9_.-]{0,255}$")
57
+ _BINDING_DOMAIN = b"agent-evolve:calibrated-portfolio-input-binding:v1\x00"
58
+ _PROJECTED_BINDING_DOMAIN = (
59
+ b"agent-evolve:calibrated-portfolio-input-binding:v2\x00"
60
+ )
61
+ _COMMON_POOL_BINDING_DOMAIN = (
62
+ b"agent-evolve:calibrated-portfolio-input-binding:v4-common-pool-required\x00"
63
+ )
64
+ _PROPOSAL_SUPPORT_BINDING_DOMAIN = (
65
+ b"agent-evolve:calibrated-portfolio-input-binding:v5-proposal-support\x00"
66
+ )
67
+ _CONTEXTUAL_ALLOCATION_BINDING_DOMAIN = (
68
+ b"agent-evolve:calibrated-portfolio-input-binding:v6-contextual-allocation\x00"
69
+ )
70
+ _HIERARCHICAL_POOL_SUPPORT_DOMAIN = (
71
+ b"agent-evolve:calibrated-hierarchical-pool-support:v1\x00"
72
+ )
73
+
74
+
75
+ def _canonical_json(value: object) -> bytes:
76
+ return json.dumps(
77
+ value,
78
+ allow_nan=False,
79
+ ensure_ascii=True,
80
+ separators=(",", ":"),
81
+ sort_keys=True,
82
+ ).encode("ascii", errors="strict")
83
+
84
+
85
+ def _canonical_card_keys(values: tuple[str, ...], *, name: str) -> None:
86
+ if type(values) is not tuple or any(
87
+ type(value) is not str or _TOKEN.fullmatch(value) is None for value in values
88
+ ):
89
+ raise TypeError(f"{name} must be an exact tuple of closed card keys")
90
+ if values != tuple(sorted(set(values))):
91
+ raise ValueError(f"{name} must be unique and canonical")
92
+
93
+
94
+ def common_pool_required_option_ids(
95
+ request: PortfolioSelectionRequest,
96
+ ) -> tuple[str, ...]:
97
+ """Return every precommitted action required in the common candidate pool.
98
+
99
+ Advisory cards do not alter pool membership. A bounded dose, however,
100
+ cannot be an honest provider constraint when all of its compatible finite
101
+ actions were removed by an earlier model-blind pool sample. Binding the
102
+ complete support union into the pool decision closes that failure mode.
103
+ Scientific matched arms may also name the same explicit pool actions in M
104
+ and N, preventing candidate-availability leakage when the neutral view has
105
+ no prompt-visible action evidence. Both sources remain workload-, model-,
106
+ provider-, and outcome-neutral.
107
+ """
108
+
109
+ if type(request) is not PortfolioSelectionRequest:
110
+ raise TypeError("request must be an exact PortfolioSelectionRequest")
111
+ request.__post_init__()
112
+ hierarchical: list[tuple[str, int]] = []
113
+ for option in request.finite_variation_contract.options:
114
+ metadata = dict(option.metadata)
115
+ if metadata.get(COMPOSITION_SELECTION_EXPOSURE_METADATA_KEY) != (
116
+ CompositionSelectionExposure.HIERARCHICAL_RANKED_UNION.value
117
+ ):
118
+ continue
119
+ try:
120
+ required = int(metadata[COMPOSITION_REQUIRED_PROPOSALS_METADATA_KEY])
121
+ except (KeyError, ValueError) as error:
122
+ raise ValueError(
123
+ "hierarchical finite option omitted its pool-support count"
124
+ ) from error
125
+ hierarchical.append((option.option_id, required))
126
+ topology_support: tuple[str, ...] = ()
127
+ if hierarchical:
128
+ counts = {value[1] for value in hierarchical}
129
+ if len(counts) != 1:
130
+ raise ValueError("hierarchical finite options disagree on support count")
131
+ required = next(iter(counts))
132
+ if not 1 <= required < 8 or len(hierarchical) < required:
133
+ raise ValueError("hierarchical finite contract has invalid pool support")
134
+ contract_sha256 = request.finite_variation_contract.identity_sha256
135
+ topology_support = tuple(
136
+ option_id
137
+ for option_id, _count in sorted(
138
+ hierarchical,
139
+ key=lambda value: (
140
+ hashlib.sha256(
141
+ _HIERARCHICAL_POOL_SUPPORT_DOMAIN
142
+ + bytes.fromhex(contract_sha256)
143
+ + value[0].encode("ascii", errors="strict")
144
+ ).digest(),
145
+ value[0],
146
+ ),
147
+ )[:required]
148
+ )
149
+ return tuple(
150
+ sorted(
151
+ {
152
+ *request.candidate_pool_required_option_ids,
153
+ *finite_variation_candidate_pool_required_option_ids(
154
+ request.finite_variation_contract
155
+ ),
156
+ *topology_support,
157
+ *required_source_evaluation_option_ids(
158
+ request.finite_variation_contract
159
+ ),
160
+ *(
161
+ option_id
162
+ for support in (
163
+ ()
164
+ if request.memory_dose_contract is None
165
+ else request.memory_dose_contract.card_supports
166
+ )
167
+ for option_id, _option_identity_sha256 in support.compatible_options
168
+ ),
169
+ }
170
+ )
171
+ )
172
+
173
+
174
+ @dataclass(frozen=True, slots=True)
175
+ class CalibratedPortfolioAllocationContext:
176
+ """Prior-only engine facts frozen before one current-wave model call."""
177
+
178
+ scope: ForecastCalibrationScope
179
+ wave_index: int
180
+ parent_candidate_identity_sha256: str
181
+ objectives: tuple[SlateMetricObjective, ...]
182
+ assigned_card_keys: tuple[str, ...]
183
+ calibration_snapshot: ForecastCalibrationSnapshot
184
+
185
+ def __post_init__(self) -> None:
186
+ if type(self.scope) is not ForecastCalibrationScope:
187
+ raise TypeError("scope must be exact ForecastCalibrationScope")
188
+ self.scope.revalidate()
189
+ if type(self.wave_index) is not int or self.wave_index <= 0:
190
+ raise ValueError("wave_index must be a positive exact integer")
191
+ require_sha256(
192
+ self.parent_candidate_identity_sha256,
193
+ "parent_candidate_identity_sha256",
194
+ )
195
+ if (
196
+ type(self.objectives) is not tuple
197
+ or not self.objectives
198
+ or any(type(value) is not SlateMetricObjective for value in self.objectives)
199
+ ):
200
+ raise ValueError("objectives must contain exact metric objectives")
201
+ for value in self.objectives:
202
+ value.__post_init__()
203
+ objective_ids = tuple(value.metric_id for value in self.objectives)
204
+ if objective_ids != tuple(sorted(set(objective_ids))):
205
+ raise ValueError("objectives must use unique canonical metric order")
206
+ _canonical_card_keys(self.assigned_card_keys, name="assigned_card_keys")
207
+ if type(self.calibration_snapshot) is not ForecastCalibrationSnapshot:
208
+ raise TypeError("calibration_snapshot must be exact")
209
+ self.calibration_snapshot.revalidate()
210
+ if self.calibration_snapshot.scope != self.scope:
211
+ raise ValueError("calibration snapshot has a foreign scope")
212
+ if self.calibration_snapshot.cutoff_wave_index_exclusive > self.wave_index:
213
+ raise ValueError(
214
+ "current/future-wave calibration evidence cannot allocate this wave"
215
+ )
216
+ if any(
217
+ value.prediction.wave_index >= self.wave_index
218
+ for value in self.calibration_snapshot.observations
219
+ ):
220
+ raise ValueError(
221
+ "current/future-wave calibration evidence cannot allocate this wave"
222
+ )
223
+
224
+ def revalidate(self) -> None:
225
+ if type(self) is not CalibratedPortfolioAllocationContext:
226
+ raise TypeError("context must be exact CalibratedPortfolioAllocationContext")
227
+ CalibratedPortfolioAllocationContext.__post_init__(self)
228
+
229
+ def to_record(self) -> dict[str, object]:
230
+ self.revalidate()
231
+ return {
232
+ "schema_version": 1,
233
+ "scope": self.scope.to_record(),
234
+ "wave_index": self.wave_index,
235
+ "parent_candidate_identity_sha256": (
236
+ self.parent_candidate_identity_sha256
237
+ ),
238
+ "objectives": [value.to_record() for value in self.objectives],
239
+ "assigned_card_keys": list(self.assigned_card_keys),
240
+ "calibration_snapshot": self.calibration_snapshot.to_record(),
241
+ }
242
+
243
+
244
+ @dataclass(frozen=True, slots=True)
245
+ class CalibratedPortfolioOptionEvidence:
246
+ """Workload-owned structural projection for one exact sealed option."""
247
+
248
+ option_id: str
249
+ option_identity_sha256: str
250
+ locus_key: str
251
+ phenotype_identity_sha256: str
252
+ structural_evidence: SlateStructuralEvidence
253
+
254
+ def __post_init__(self) -> None:
255
+ if (
256
+ type(self.option_id) is not str
257
+ or _OPTION_ID.fullmatch(self.option_id) is None
258
+ ):
259
+ raise ValueError("option_id must use the closed token grammar")
260
+ require_sha256(self.option_identity_sha256, "option_identity_sha256")
261
+ if type(self.locus_key) is not str or _TOKEN.fullmatch(self.locus_key) is None:
262
+ raise ValueError("locus_key must use the closed token grammar")
263
+ require_sha256(
264
+ self.phenotype_identity_sha256,
265
+ "phenotype_identity_sha256",
266
+ )
267
+ if type(self.structural_evidence) is not SlateStructuralEvidence:
268
+ raise TypeError("structural_evidence must be exact")
269
+ self.structural_evidence.__post_init__()
270
+
271
+ def revalidate(self) -> None:
272
+ if type(self) is not CalibratedPortfolioOptionEvidence:
273
+ raise TypeError("evidence must be exact CalibratedPortfolioOptionEvidence")
274
+ CalibratedPortfolioOptionEvidence.__post_init__(self)
275
+
276
+ def to_record(self) -> dict[str, object]:
277
+ self.revalidate()
278
+ return {
279
+ "option_id": self.option_id,
280
+ "option_identity_sha256": self.option_identity_sha256,
281
+ "locus_key": self.locus_key,
282
+ "phenotype_identity_sha256": self.phenotype_identity_sha256,
283
+ "structural_evidence": self.structural_evidence.to_record(),
284
+ }
285
+
286
+
287
+ def proposal_support_candidates(
288
+ request: PortfolioSelectionRequest,
289
+ option_evidence: tuple[CalibratedPortfolioOptionEvidence, ...],
290
+ common_candidate_pool: CommonCandidatePoolDecision,
291
+ ) -> tuple[ProposalSupportCandidate, ...]:
292
+ """Project the exact model-visible common pool into structural rows."""
293
+
294
+ if type(request) is not PortfolioSelectionRequest:
295
+ raise TypeError("request must be an exact PortfolioSelectionRequest")
296
+ request.__post_init__()
297
+ if type(option_evidence) is not tuple or any(
298
+ type(value) is not CalibratedPortfolioOptionEvidence
299
+ for value in option_evidence
300
+ ):
301
+ raise TypeError("option_evidence must contain exact evidence rows")
302
+ for value in option_evidence:
303
+ value.revalidate()
304
+ if type(common_candidate_pool) is not CommonCandidatePoolDecision:
305
+ raise TypeError("common_candidate_pool must be an exact decision")
306
+ common_candidate_pool.__post_init__()
307
+ evidence_by_id = {value.option_id: value for value in option_evidence}
308
+ if not set(common_candidate_pool.option_ids).issubset(evidence_by_id):
309
+ raise ValueError("common candidate pool escapes the structural evidence")
310
+ contract = request.finite_variation_contract
311
+ # ``request.__post_init__`` above authenticates the complete finite
312
+ # contract once at this trust boundary. Resolving every common-pool row
313
+ # through ``contract.resolve`` would revalidate that complete contract for
314
+ # every option, making this projection quadratic for large finite spaces.
315
+ option_by_id = {value.option_id: value for value in contract.options}
316
+ if not set(common_candidate_pool.option_ids).issubset(option_by_id):
317
+ raise ValueError("common candidate pool escapes the sealed finite contract")
318
+ return tuple(
319
+ ProposalSupportCandidate(
320
+ option_id=option_id,
321
+ option_identity_sha256=evidence_by_id[option_id].option_identity_sha256,
322
+ family=option_by_id[option_id].family,
323
+ locus_key=evidence_by_id[option_id].locus_key,
324
+ phenotype_identity_sha256=(
325
+ evidence_by_id[option_id].phenotype_identity_sha256
326
+ ),
327
+ frozen_archive_snapshot_sha256=(
328
+ evidence_by_id[
329
+ option_id
330
+ ].structural_evidence.frozen_archive_snapshot_sha256
331
+ ),
332
+ structural_evidence_receipt_sha256=(
333
+ evidence_by_id[
334
+ option_id
335
+ ].structural_evidence.evidence_receipt_sha256
336
+ ),
337
+ archive_novelty_score=(
338
+ evidence_by_id[option_id].structural_evidence.archive_novelty_score
339
+ ),
340
+ structural_coverage_score=(
341
+ evidence_by_id[
342
+ option_id
343
+ ].structural_evidence.structural_coverage_score
344
+ ),
345
+ )
346
+ for option_id in common_candidate_pool.option_ids
347
+ )
348
+
349
+
350
+ @dataclass(frozen=True, slots=True, eq=False)
351
+ class CalibratedPortfolioInputBinding:
352
+ """One request-bound immutable context and all-option evidence snapshot."""
353
+
354
+ request_sha256: str
355
+ context: CalibratedPortfolioAllocationContext
356
+ option_evidence: tuple[CalibratedPortfolioOptionEvidence, ...]
357
+ option_prompt_projection: FiniteOptionPromptProjection | None = None
358
+ common_candidate_pool: CommonCandidatePoolDecision | None = None
359
+ proposal_support: ProposalSupportDecision | None = None
360
+ contextual_allocation: ContextualPortfolioAllocationContract | None = None
361
+
362
+ def __post_init__(self) -> None:
363
+ require_sha256(self.request_sha256, "request_sha256")
364
+ if type(self.context) is not CalibratedPortfolioAllocationContext:
365
+ raise TypeError("context must be exact CalibratedPortfolioAllocationContext")
366
+ self.context.revalidate()
367
+ if type(self.option_evidence) is not tuple or any(
368
+ type(value) is not CalibratedPortfolioOptionEvidence
369
+ for value in self.option_evidence
370
+ ):
371
+ raise TypeError("option_evidence must contain exact evidence values")
372
+ if not self.option_evidence:
373
+ raise ValueError("option_evidence must be non-empty")
374
+ for value in self.option_evidence:
375
+ value.revalidate()
376
+ option_ids = tuple(value.option_id for value in self.option_evidence)
377
+ if option_ids != tuple(sorted(set(option_ids))):
378
+ raise ValueError("option_evidence must use unique canonical option order")
379
+ archive_snapshots = {
380
+ value.structural_evidence.frozen_archive_snapshot_sha256
381
+ for value in self.option_evidence
382
+ }
383
+ if len(archive_snapshots) != 1:
384
+ raise ValueError("all option evidence must share one frozen archive")
385
+ if self.option_prompt_projection is not None:
386
+ if type(self.option_prompt_projection) is not FiniteOptionPromptProjection:
387
+ raise TypeError(
388
+ "option_prompt_projection must be exact prompt projection"
389
+ )
390
+ self.option_prompt_projection.__post_init__()
391
+ if self.common_candidate_pool is not None:
392
+ if type(self.common_candidate_pool) is not CommonCandidatePoolDecision:
393
+ raise TypeError(
394
+ "common_candidate_pool must be an exact decision or None"
395
+ )
396
+ self.common_candidate_pool.__post_init__()
397
+ if self.proposal_support is not None:
398
+ if type(self.proposal_support) is not ProposalSupportDecision:
399
+ raise TypeError(
400
+ "proposal_support must be an exact decision or None"
401
+ )
402
+ self.proposal_support.__post_init__()
403
+ if self.common_candidate_pool is None:
404
+ raise ValueError(
405
+ "proposal support requires a task-keyed common candidate pool"
406
+ )
407
+ if self.contextual_allocation is not None:
408
+ if type(self.contextual_allocation) is not (
409
+ ContextualPortfolioAllocationContract
410
+ ):
411
+ raise TypeError(
412
+ "contextual_allocation must be an exact contract or None"
413
+ )
414
+ self.contextual_allocation.__post_init__()
415
+ if (
416
+ self.contextual_allocation.campaign_generation
417
+ != self.context.wave_index
418
+ ):
419
+ raise ValueError(
420
+ "contextual allocation differs from the campaign generation"
421
+ )
422
+
423
+ def revalidate(self) -> None:
424
+ if type(self) is not CalibratedPortfolioInputBinding:
425
+ raise TypeError("binding must be exact CalibratedPortfolioInputBinding")
426
+ CalibratedPortfolioInputBinding.__post_init__(self)
427
+
428
+ def require_request(self, request: PortfolioSelectionRequest) -> None:
429
+ """Authenticate the complete binding against one exact public request."""
430
+
431
+ self.revalidate()
432
+ if type(request) is not PortfolioSelectionRequest:
433
+ raise TypeError("request must be exact PortfolioSelectionRequest")
434
+ request.__post_init__()
435
+ if self.request_sha256 != request.request_sha256:
436
+ raise ValueError("calibrated input binding names a foreign request")
437
+ contract = request.finite_variation_contract
438
+ if (
439
+ self.context.parent_candidate_identity_sha256
440
+ != contract.parent_configuration_sha256
441
+ ):
442
+ raise ValueError("allocation context names a foreign parent")
443
+ if tuple(value.metric_id for value in self.context.objectives) != (
444
+ request.required_metric_ids
445
+ ):
446
+ raise ValueError("allocation objectives differ from requested metrics")
447
+ request_card_keys = {value.card_key for value in request.cards}
448
+ if not set(self.context.assigned_card_keys).issubset(request_card_keys):
449
+ raise ValueError("assigned cards escape the request snapshot")
450
+ expected = {
451
+ value.option_id: value.identity_sha256 for value in contract.options
452
+ }
453
+ observed = {
454
+ value.option_id: value.option_identity_sha256
455
+ for value in self.option_evidence
456
+ }
457
+ if observed != expected:
458
+ raise ValueError("option evidence differs from the sealed finite contract")
459
+ if self.option_prompt_projection is not None:
460
+ self.option_prompt_projection.require_contract(contract)
461
+ if self.common_candidate_pool is not None:
462
+ policy = TaskKeyedCommonCandidatePoolPolicy(
463
+ replicate_seed=self.common_candidate_pool.replicate_seed,
464
+ candidate_pool_size=(
465
+ self.common_candidate_pool.candidate_pool_size
466
+ ),
467
+ model_selection_size=(
468
+ self.common_candidate_pool.model_selection_size
469
+ ),
470
+ )
471
+ policy.require_decision(
472
+ self.common_candidate_pool,
473
+ benchmark_sha256=self.context.scope.benchmark_sha256,
474
+ wave_index=self.context.wave_index,
475
+ parent_configuration_sha256=(
476
+ self.context.parent_candidate_identity_sha256
477
+ ),
478
+ contract=contract,
479
+ evaluation_size=request.portfolio_size,
480
+ min_distinct_families=request.min_distinct_families,
481
+ require_pairwise_disjoint_parent_patches=(
482
+ request.require_pairwise_disjoint_parent_patches
483
+ ),
484
+ required_option_ids=common_pool_required_option_ids(request),
485
+ certified_feasibility_witness_option_ids=(
486
+ self.common_candidate_pool.certified_feasibility_witness_option_ids
487
+ ),
488
+ )
489
+ if self.proposal_support is not None:
490
+ assert self.common_candidate_pool is not None
491
+ candidates = proposal_support_candidates(
492
+ request,
493
+ self.option_evidence,
494
+ self.common_candidate_pool,
495
+ )
496
+ expected_support = StructuralProposalSupportPolicy().select(
497
+ request_sha256=request.request_sha256,
498
+ common_candidate_pool_decision_sha256=(
499
+ self.common_candidate_pool.decision_sha256
500
+ ),
501
+ model_selection_size=(
502
+ self.common_candidate_pool.model_selection_size
503
+ ),
504
+ candidates=candidates,
505
+ )
506
+ if self.proposal_support != expected_support:
507
+ raise ValueError(
508
+ "proposal-support decision differs from the sealed input binding"
509
+ )
510
+ if self.contextual_allocation is not None:
511
+ if self.contextual_allocation.evaluation_slots != request.portfolio_size:
512
+ raise ValueError(
513
+ "contextual allocation differs from the evaluation width"
514
+ )
515
+
516
+ def prompt_records_for(
517
+ self,
518
+ request: PortfolioSelectionRequest,
519
+ ) -> tuple[dict[str, object], ...]:
520
+ """Return only this binding's authenticated model-visible option view."""
521
+
522
+ self.require_request(request)
523
+ records = (
524
+ request.finite_variation_contract.prompt_records()
525
+ if self.option_prompt_projection is None
526
+ else self.option_prompt_projection.prompt_records()
527
+ )
528
+ if self.common_candidate_pool is None:
529
+ return records
530
+ by_id = {str(value["option_id"]): value for value in records}
531
+ return tuple(
532
+ by_id[option_id]
533
+ for option_id in self.common_candidate_pool.option_ids
534
+ )
535
+
536
+ def prompt_projection_contract_for(
537
+ self,
538
+ request: PortfolioSelectionRequest,
539
+ ) -> dict[str, object] | None:
540
+ """Return the compact projection receipt, if this binding opted in."""
541
+
542
+ self.require_request(request)
543
+ if self.option_prompt_projection is None:
544
+ return None
545
+ return self.option_prompt_projection.to_prompt_contract_record()
546
+
547
+ def evidence_for(
548
+ self,
549
+ request: PortfolioSelectionRequest,
550
+ option: FiniteVariationOption,
551
+ ) -> CalibratedPortfolioOptionEvidence:
552
+ self.require_request(request)
553
+ if type(option) is not FiniteVariationOption:
554
+ raise TypeError("option must be exact FiniteVariationOption")
555
+ resolved = request.finite_variation_contract.resolve(option.option_id)
556
+ if resolved != option:
557
+ raise ValueError("option belongs to a foreign finite contract")
558
+ evidence = next(
559
+ value for value in self.option_evidence if value.option_id == option.option_id
560
+ )
561
+ if evidence.option_identity_sha256 != option.identity_sha256:
562
+ raise ValueError("structural evidence belongs to a foreign option")
563
+ return evidence
564
+
565
+ def _unsigned_record(self) -> dict[str, object]:
566
+ self.revalidate()
567
+ record: dict[str, object] = {
568
+ "schema_version": (
569
+ 6
570
+ if self.contextual_allocation is not None
571
+ else 5
572
+ if self.proposal_support is not None
573
+ else 4
574
+ if self.common_candidate_pool is not None
575
+ else (1 if self.option_prompt_projection is None else 2)
576
+ ),
577
+ "request_sha256": self.request_sha256,
578
+ "context": self.context.to_record(),
579
+ "option_evidence": [value.to_record() for value in self.option_evidence],
580
+ }
581
+ # Absence is the legacy representation. Do not add a null field: that
582
+ # would silently invalidate every finalized v2/four-role binding.
583
+ if self.option_prompt_projection is not None:
584
+ record["option_prompt_projection"] = (
585
+ self.option_prompt_projection.to_binding_record()
586
+ )
587
+ if self.common_candidate_pool is not None:
588
+ record["common_candidate_pool"] = self.common_candidate_pool.to_record()
589
+ if self.proposal_support is not None:
590
+ record["proposal_support"] = self.proposal_support.to_record()
591
+ if self.contextual_allocation is not None:
592
+ record["contextual_allocation"] = (
593
+ self.contextual_allocation.to_record()
594
+ )
595
+ return record
596
+
597
+ @property
598
+ def binding_sha256(self) -> str:
599
+ domain = (
600
+ _CONTEXTUAL_ALLOCATION_BINDING_DOMAIN
601
+ if self.contextual_allocation is not None
602
+ else _PROPOSAL_SUPPORT_BINDING_DOMAIN
603
+ if self.proposal_support is not None
604
+ else _COMMON_POOL_BINDING_DOMAIN
605
+ if self.common_candidate_pool is not None
606
+ else (
607
+ _BINDING_DOMAIN
608
+ if self.option_prompt_projection is None
609
+ else _PROJECTED_BINDING_DOMAIN
610
+ )
611
+ )
612
+ return hashlib.sha256(
613
+ domain + _canonical_json(self._unsigned_record())
614
+ ).hexdigest()
615
+
616
+ def to_record(self) -> dict[str, object]:
617
+ return {**self._unsigned_record(), "binding_sha256": self.binding_sha256}
618
+
619
+ def __eq__(self, other: object) -> bool:
620
+ return (
621
+ type(other) is CalibratedPortfolioInputBinding
622
+ and self.binding_sha256 == other.binding_sha256
623
+ )
624
+
625
+ __hash__ = None
626
+
627
+
628
+ CalibratedPortfolioBindingProvider = Callable[
629
+ [PortfolioSelectionRequest], CalibratedPortfolioInputBinding
630
+ ]
631
+
632
+
633
+ __all__ = [
634
+ "CalibratedPortfolioAllocationContext",
635
+ "CalibratedPortfolioBindingProvider",
636
+ "CalibratedPortfolioInputBinding",
637
+ "CalibratedPortfolioOptionEvidence",
638
+ "common_pool_required_option_ids",
639
+ "proposal_support_candidates",
640
+ ]