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,940 @@
1
+ """Generic propose-once, evaluate-pilot, choose-branch residual evolution.
2
+
3
+ Every proposal, score, semantic cell, pilot action, and complete continuation
4
+ branch is sealed before the first current candidate is evaluated. A typed
5
+ pilot projector then exposes only real marginal archive contribution to a
6
+ small gate. The chosen pre-existing branch is evaluated without re-querying a
7
+ model or regenerating the universe.
8
+
9
+ This service is workload-, objective-, model-, provider-, and prompt-blind.
10
+ Those concerns remain behind proposal experts, the pilot-outcome projector,
11
+ and the already established archive/evaluator ports.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import hashlib
17
+ import json
18
+ import re
19
+ from dataclasses import dataclass, field
20
+ from enum import Enum
21
+ from typing import Protocol, runtime_checkable
22
+
23
+ from agent_evolve.application.materialized_action_broker import (
24
+ MaterializedActionBrokerRequest,
25
+ MaterializedSlateFeasibilityPort,
26
+ MaterializedSlateValuePort,
27
+ RegretBrokeredMaterializedActionPolicy,
28
+ )
29
+ from agent_evolve.application.residual_portfolio_evolution import (
30
+ DISJOINT_ACTION_EVALUATION_WAVES_V1,
31
+ MaterializedActionEvaluation,
32
+ MaterializedActionEvaluationBatch,
33
+ MaterializedActionProposalBatch,
34
+ MaterializedActionProposalExpertPort,
35
+ ResidualPortfolioDecisionRequest,
36
+ ResidualPortfolioEvolutionResult,
37
+ evaluate_materialized_action_subset,
38
+ propose_materialized_action_batches,
39
+ )
40
+ from agent_evolve.application.sequential_lineage_allocation import (
41
+ AnyPositiveSequentialLineageGate,
42
+ SequentialAllocationGateDecisionPort,
43
+ SequentialAllocationGatePort,
44
+ SequentialAllocationPlanPort,
45
+ SequentialLineageAllocationPlannerPort,
46
+ SequentialPilotOutcomeBatch,
47
+ SequentialPilotOutcomeProjectorPort,
48
+ )
49
+ from agent_evolve.domain.patch import require_sha256
50
+ from agent_evolve.domain.typed_json import (
51
+ FrozenJsonObject,
52
+ freeze_json,
53
+ thaw_json,
54
+ typed_json_sha256,
55
+ )
56
+
57
+
58
+ SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_ID = (
59
+ "sequential_residual_portfolio_evolution"
60
+ )
61
+ SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_VERSION = 4
62
+ SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_DEFINITION_SHA256 = hashlib.sha256(
63
+ b"agent-evolve:sequential-residual-portfolio-evolution:v4;"
64
+ b"proposal-universe=sealed-once-before-current-outcomes;"
65
+ b"branches=one-or-more-complete-slates-frozen-before-pilot;"
66
+ b"pilot=planner-authenticated-action-subset;"
67
+ b"gate=injected-precommitted-branch-decision-port;"
68
+ b"continuation=no-regeneration-no-rescoring-no-provider-call;"
69
+ b"execution=pilot-then-chosen-remaining-actions;"
70
+ b"exactly-once-boundary=disjoint-actions-not-proposal-batches;"
71
+ b"failed-wave-reservation=fail-closed;"
72
+ b"archive-publication=combined-final-slate-only;"
73
+ b"durability=optional-or-required-plan-pilot-evaluated-adjudicated-final-commit-port;"
74
+ b"workload-objective-model-provider-prompt-branches=false"
75
+ ).hexdigest()
76
+
77
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
78
+ _PHASE_RECEIPT_DOMAIN = (
79
+ b"agent-evolve:sequential-residual-phase-receipt:v1\x00"
80
+ )
81
+ _PHASE_ACK_DOMAIN = b"agent-evolve:sequential-residual-phase-ack:v1\x00"
82
+ _RESULT_DOMAIN = b"agent-evolve:sequential-residual-result:v1\x00"
83
+
84
+
85
+ def _canonical_json(value: object) -> bytes:
86
+ return json.dumps(
87
+ value,
88
+ allow_nan=False,
89
+ ensure_ascii=True,
90
+ separators=(",", ":"),
91
+ sort_keys=True,
92
+ ).encode("ascii", errors="strict")
93
+
94
+
95
+ def _hash(domain: bytes, value: object) -> str:
96
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
97
+
98
+
99
+ def _require_token(value: str, *, name: str) -> None:
100
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
101
+ raise ValueError(f"{name} must use the closed token grammar")
102
+
103
+
104
+ def _planner_identity(
105
+ value: SequentialLineageAllocationPlannerPort,
106
+ ) -> tuple[str, int, str]:
107
+ if not isinstance(value, SequentialLineageAllocationPlannerPort):
108
+ raise TypeError("planner must implement its application port")
109
+ identity = (
110
+ getattr(value, "planner_id", None),
111
+ getattr(value, "planner_version", None),
112
+ getattr(value, "definition_sha256", None),
113
+ )
114
+ _require_token(identity[0], name="planner_id")
115
+ if type(identity[1]) is not int or identity[1] <= 0:
116
+ raise ValueError("planner_version must be positive")
117
+ require_sha256(identity[2], "planner definition_sha256")
118
+ return identity # type: ignore[return-value]
119
+
120
+
121
+ def _projector_identity(
122
+ value: SequentialPilotOutcomeProjectorPort,
123
+ ) -> tuple[str, int, str]:
124
+ if not isinstance(value, SequentialPilotOutcomeProjectorPort):
125
+ raise TypeError("pilot projector must implement its application port")
126
+ identity = (
127
+ getattr(value, "projector_id", None),
128
+ getattr(value, "projector_version", None),
129
+ getattr(value, "definition_sha256", None),
130
+ )
131
+ _require_token(identity[0], name="projector_id")
132
+ if type(identity[1]) is not int or identity[1] <= 0:
133
+ raise ValueError("projector_version must be positive")
134
+ require_sha256(identity[2], "projector definition_sha256")
135
+ return identity # type: ignore[return-value]
136
+
137
+
138
+ def _gate_identity(
139
+ value: SequentialAllocationGatePort,
140
+ ) -> tuple[str, int, str]:
141
+ if not isinstance(value, SequentialAllocationGatePort):
142
+ raise TypeError("gate must implement its application port")
143
+ identity = (
144
+ getattr(value, "gate_id", None),
145
+ getattr(value, "gate_version", None),
146
+ getattr(value, "definition_sha256", None),
147
+ )
148
+ _require_token(identity[0], name="gate_id")
149
+ if type(identity[1]) is not int or identity[1] <= 0:
150
+ raise ValueError("gate_version must be positive")
151
+ require_sha256(identity[2], "gate definition_sha256")
152
+ return identity # type: ignore[return-value]
153
+
154
+
155
+ class SequentialResidualPhase(str, Enum):
156
+ PLAN_FROZEN = "plan_frozen"
157
+ PILOT_EVALUATED = "pilot_evaluated"
158
+ PILOT_ADJUDICATED = "pilot_adjudicated"
159
+ FINALIZED = "finalized"
160
+
161
+
162
+ @dataclass(frozen=True, slots=True)
163
+ class SequentialResidualPhaseReceipt:
164
+ """One hash-bound interception boundary in a sequential stage."""
165
+
166
+ phase: SequentialResidualPhase
167
+ residual_request_sha256: str
168
+ plan_sha256: str
169
+ product_sha256s: tuple[str, ...]
170
+ evidence: FrozenJsonObject
171
+ receipt_sha256: str = field(init=False)
172
+
173
+ def __post_init__(self) -> None:
174
+ if type(self.phase) is not SequentialResidualPhase:
175
+ raise TypeError("phase must be an exact SequentialResidualPhase")
176
+ require_sha256(
177
+ self.residual_request_sha256,
178
+ "residual_request_sha256",
179
+ )
180
+ require_sha256(self.plan_sha256, "plan_sha256")
181
+ if (
182
+ type(self.product_sha256s) is not tuple
183
+ or not self.product_sha256s
184
+ ):
185
+ raise ValueError("product_sha256s must be a non-empty exact tuple")
186
+ for value in self.product_sha256s:
187
+ require_sha256(value, "product_sha256")
188
+ if (
189
+ type(self.evidence) is not FrozenJsonObject
190
+ or freeze_json(self.evidence) is not self.evidence
191
+ ):
192
+ raise TypeError("phase evidence must be an exact frozen object")
193
+ object.__setattr__(
194
+ self,
195
+ "receipt_sha256",
196
+ _hash(_PHASE_RECEIPT_DOMAIN, self._unsigned_record()),
197
+ )
198
+
199
+ def _unsigned_record(self) -> dict[str, object]:
200
+ return {
201
+ "schema_version": 1,
202
+ "phase": self.phase.value,
203
+ "residual_request_sha256": self.residual_request_sha256,
204
+ "plan_sha256": self.plan_sha256,
205
+ "product_sha256s": list(self.product_sha256s),
206
+ "evidence_sha256": typed_json_sha256(self.evidence),
207
+ }
208
+
209
+ def to_record(self, *, include_evidence: bool = False) -> dict[str, object]:
210
+ self.__post_init__()
211
+ record = {
212
+ **self._unsigned_record(),
213
+ "receipt_sha256": self.receipt_sha256,
214
+ }
215
+ if include_evidence:
216
+ record["evidence"] = thaw_json(self.evidence)
217
+ return record
218
+
219
+
220
+ @dataclass(frozen=True, slots=True)
221
+ class SequentialResidualPhaseCommitAck:
222
+ """Proof that a supplied interception boundary accepted one receipt."""
223
+
224
+ committer_id: str
225
+ committer_version: int
226
+ committer_definition_sha256: str
227
+ phase_receipt_sha256: str
228
+ durable: bool
229
+ evidence: FrozenJsonObject
230
+ ack_sha256: str = field(init=False)
231
+
232
+ def __post_init__(self) -> None:
233
+ _require_token(self.committer_id, name="committer_id")
234
+ if type(self.committer_version) is not int or self.committer_version <= 0:
235
+ raise ValueError("committer_version must be positive")
236
+ require_sha256(
237
+ self.committer_definition_sha256,
238
+ "committer_definition_sha256",
239
+ )
240
+ require_sha256(
241
+ self.phase_receipt_sha256,
242
+ "phase_receipt_sha256",
243
+ )
244
+ if type(self.durable) is not bool:
245
+ raise TypeError("durable must be an exact bool")
246
+ if (
247
+ type(self.evidence) is not FrozenJsonObject
248
+ or freeze_json(self.evidence) is not self.evidence
249
+ ):
250
+ raise TypeError("commit evidence must be an exact frozen object")
251
+ object.__setattr__(
252
+ self,
253
+ "ack_sha256",
254
+ _hash(_PHASE_ACK_DOMAIN, self._unsigned_record()),
255
+ )
256
+
257
+ def _unsigned_record(self) -> dict[str, object]:
258
+ return {
259
+ "schema_version": 1,
260
+ "committer": {
261
+ "committer_id": self.committer_id,
262
+ "committer_version": self.committer_version,
263
+ "definition_sha256": self.committer_definition_sha256,
264
+ },
265
+ "phase_receipt_sha256": self.phase_receipt_sha256,
266
+ "durable": self.durable,
267
+ "evidence_sha256": typed_json_sha256(self.evidence),
268
+ }
269
+
270
+ def to_record(self, *, include_evidence: bool = False) -> dict[str, object]:
271
+ self.__post_init__()
272
+ record = {**self._unsigned_record(), "ack_sha256": self.ack_sha256}
273
+ if include_evidence:
274
+ record["evidence"] = thaw_json(self.evidence)
275
+ return record
276
+
277
+
278
+ @runtime_checkable
279
+ class SequentialResidualPhaseCommitPort(Protocol):
280
+ """Durably intercept a sequential phase before later evaluation authority."""
281
+
282
+ committer_id: str
283
+ committer_version: int
284
+ definition_sha256: str
285
+
286
+ async def commit(
287
+ self,
288
+ receipt: SequentialResidualPhaseReceipt,
289
+ ) -> SequentialResidualPhaseCommitAck: ...
290
+
291
+
292
+ def _committer_identity(
293
+ value: SequentialResidualPhaseCommitPort,
294
+ ) -> tuple[str, int, str]:
295
+ if not isinstance(value, SequentialResidualPhaseCommitPort):
296
+ raise TypeError("phase committer must implement its application port")
297
+ identity = (
298
+ getattr(value, "committer_id", None),
299
+ getattr(value, "committer_version", None),
300
+ getattr(value, "definition_sha256", None),
301
+ )
302
+ _require_token(identity[0], name="committer_id")
303
+ if type(identity[1]) is not int or identity[1] <= 0:
304
+ raise ValueError("committer_version must be positive")
305
+ require_sha256(identity[2], "committer definition_sha256")
306
+ return identity # type: ignore[return-value]
307
+
308
+
309
+ def _flatten_evaluations(
310
+ batches: tuple[MaterializedActionEvaluationBatch, ...],
311
+ ) -> tuple[MaterializedActionEvaluation, ...]:
312
+ by_action = {
313
+ value.action.action_sha256: value
314
+ for batch in batches
315
+ for value in batch.evaluations
316
+ }
317
+ return tuple(by_action[value] for value in sorted(by_action))
318
+
319
+
320
+ def _merge_evaluation_waves(
321
+ proposals: tuple[MaterializedActionProposalBatch, ...],
322
+ pilot: tuple[MaterializedActionEvaluationBatch, ...],
323
+ continuation: tuple[MaterializedActionEvaluationBatch, ...],
324
+ ) -> tuple[MaterializedActionEvaluationBatch, ...]:
325
+ """Merge per-wave expert batches without erasing their source receipts."""
326
+
327
+ proposal_by_expert = {value.expert_id: value for value in proposals}
328
+ batches_by_expert: dict[
329
+ str, list[MaterializedActionEvaluationBatch]
330
+ ] = {}
331
+ for batch in (*pilot, *continuation):
332
+ batches_by_expert.setdefault(batch.expert_id, []).append(batch)
333
+ merged: list[MaterializedActionEvaluationBatch] = []
334
+ for expert_id in sorted(batches_by_expert):
335
+ source = batches_by_expert[expert_id]
336
+ proposal = proposal_by_expert[expert_id]
337
+ evaluations = tuple(
338
+ sorted(
339
+ (
340
+ value
341
+ for batch in source
342
+ for value in batch.evaluations
343
+ ),
344
+ key=lambda value: value.action.action_sha256,
345
+ )
346
+ )
347
+ action_ids = tuple(
348
+ value.action.action_sha256 for value in evaluations
349
+ )
350
+ if len(action_ids) != len(set(action_ids)):
351
+ raise ValueError("pilot and continuation repeat an evaluation")
352
+ merged.append(
353
+ MaterializedActionEvaluationBatch(
354
+ proposal_sha256=proposal.proposal_sha256,
355
+ expert_id=proposal.expert_id,
356
+ expert_version=proposal.expert_version,
357
+ expert_definition_sha256=(
358
+ proposal.expert_definition_sha256
359
+ ),
360
+ selected_action_sha256s=action_ids,
361
+ evaluations=evaluations,
362
+ evidence=freeze_json(
363
+ {
364
+ "sequential_wave_batch_sha256s": [
365
+ value.batch_sha256 for value in source
366
+ ],
367
+ "pilot_then_continuation": True,
368
+ "candidate_outcomes_reused": False,
369
+ }
370
+ ),
371
+ )
372
+ )
373
+ return tuple(merged)
374
+
375
+
376
+ @dataclass(frozen=True, slots=True)
377
+ class SequentialResidualPortfolioEvolutionResult:
378
+ """Full sequential trace plus the standard combined downstream result."""
379
+
380
+ result: ResidualPortfolioEvolutionResult
381
+ allocation_plan: SequentialAllocationPlanPort
382
+ pilot_evaluation_batches: tuple[
383
+ MaterializedActionEvaluationBatch, ...
384
+ ]
385
+ pilot_outcomes: SequentialPilotOutcomeBatch
386
+ gate_decision: SequentialAllocationGateDecisionPort
387
+ continuation_evaluation_batches: tuple[
388
+ MaterializedActionEvaluationBatch, ...
389
+ ]
390
+ phase_receipts: tuple[SequentialResidualPhaseReceipt, ...]
391
+ phase_commit_acks: tuple[SequentialResidualPhaseCommitAck, ...]
392
+ method_definition_sha256: str = (
393
+ SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_DEFINITION_SHA256
394
+ )
395
+ sequential_result_sha256: str = field(init=False)
396
+
397
+ def __post_init__(self) -> None:
398
+ if type(self.result) is not ResidualPortfolioEvolutionResult:
399
+ raise TypeError("result must be exact")
400
+ self.result.__post_init__()
401
+ if not isinstance(
402
+ self.allocation_plan,
403
+ SequentialAllocationPlanPort,
404
+ ):
405
+ raise TypeError(
406
+ "allocation_plan must implement its application port"
407
+ )
408
+ if (
409
+ self.allocation_plan.residual_request_sha256
410
+ != self.result.request.request_sha256
411
+ or self.allocation_plan.proposal_sha256s
412
+ != tuple(
413
+ sorted(
414
+ value.proposal_sha256 for value in self.result.proposals
415
+ )
416
+ )
417
+ ):
418
+ raise ValueError("allocation plan differs from the combined result")
419
+ for batches, name in (
420
+ (self.pilot_evaluation_batches, "pilot_evaluation_batches"),
421
+ (
422
+ self.continuation_evaluation_batches,
423
+ "continuation_evaluation_batches",
424
+ ),
425
+ ):
426
+ if type(batches) is not tuple:
427
+ raise TypeError(f"{name} must be an exact tuple")
428
+ for value in batches:
429
+ if type(value) is not MaterializedActionEvaluationBatch:
430
+ raise TypeError(f"{name} must contain exact batches")
431
+ value.__post_init__()
432
+ if type(self.pilot_outcomes) is not SequentialPilotOutcomeBatch:
433
+ raise TypeError("pilot_outcomes must be exact")
434
+ self.pilot_outcomes.__post_init__()
435
+ if not isinstance(
436
+ self.gate_decision,
437
+ SequentialAllocationGateDecisionPort,
438
+ ):
439
+ raise TypeError(
440
+ "gate_decision must implement its application port"
441
+ )
442
+ if (
443
+ self.pilot_outcomes.plan_sha256
444
+ != self.allocation_plan.plan_sha256
445
+ or self.gate_decision.plan_sha256
446
+ != self.allocation_plan.plan_sha256
447
+ or self.gate_decision.pilot_outcome_batch_sha256
448
+ != self.pilot_outcomes.batch_sha256
449
+ ):
450
+ raise ValueError("pilot outcome/gate trace does not join the plan")
451
+ selected_requirement = self.allocation_plan.requirement_for(
452
+ self.gate_decision.selected_branch_id
453
+ )
454
+ if (
455
+ self.gate_decision.selected_requirement_sha256
456
+ != selected_requirement.requirement_sha256
457
+ or self.result.broker_decision.allocation_requirement
458
+ != selected_requirement
459
+ ):
460
+ raise ValueError("combined broker result differs from gate branch")
461
+ pilot_ids = {
462
+ value.action.action_sha256
463
+ for value in _flatten_evaluations(
464
+ self.pilot_evaluation_batches
465
+ )
466
+ }
467
+ continuation_ids = {
468
+ value.action.action_sha256
469
+ for value in _flatten_evaluations(
470
+ self.continuation_evaluation_batches
471
+ )
472
+ }
473
+ if pilot_ids != set(self.allocation_plan.pilot_action_sha256s):
474
+ raise ValueError("pilot evaluations differ from the plan")
475
+ if pilot_ids & continuation_ids:
476
+ raise ValueError("continuation reevaluates a pilot")
477
+ if pilot_ids | continuation_ids != set(
478
+ selected_requirement.required_action_sha256s
479
+ ):
480
+ raise ValueError("two evaluation waves do not close the branch")
481
+ if (
482
+ type(self.phase_receipts) is not tuple
483
+ or tuple(value.phase for value in self.phase_receipts)
484
+ != tuple(SequentialResidualPhase)
485
+ ):
486
+ raise ValueError("phase receipts must cover canonical phase order")
487
+ for value in self.phase_receipts:
488
+ value.__post_init__()
489
+ if value.plan_sha256 != self.allocation_plan.plan_sha256:
490
+ raise ValueError("phase receipt names another plan")
491
+ if type(self.phase_commit_acks) is not tuple:
492
+ raise TypeError("phase_commit_acks must be an exact tuple")
493
+ for value in self.phase_commit_acks:
494
+ value.__post_init__()
495
+ if self.phase_commit_acks and tuple(
496
+ value.phase_receipt_sha256
497
+ for value in self.phase_commit_acks
498
+ ) != tuple(value.receipt_sha256 for value in self.phase_receipts):
499
+ raise ValueError("phase commit acknowledgements do not close")
500
+ require_sha256(
501
+ self.method_definition_sha256,
502
+ "method_definition_sha256",
503
+ )
504
+ object.__setattr__(
505
+ self,
506
+ "sequential_result_sha256",
507
+ _hash(_RESULT_DOMAIN, self._unsigned_record()),
508
+ )
509
+
510
+ def _unsigned_record(self) -> dict[str, object]:
511
+ return {
512
+ "schema_version": 1,
513
+ "method": {
514
+ "method_id": SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_ID,
515
+ "method_version": (
516
+ SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_VERSION
517
+ ),
518
+ "definition_sha256": self.method_definition_sha256,
519
+ },
520
+ "combined_result_sha256": self.result.result_sha256,
521
+ "allocation_plan_sha256": self.allocation_plan.plan_sha256,
522
+ "pilot_evaluation_batch_sha256s": [
523
+ value.batch_sha256
524
+ for value in self.pilot_evaluation_batches
525
+ ],
526
+ "pilot_outcome_batch_sha256": self.pilot_outcomes.batch_sha256,
527
+ "gate_decision_sha256": self.gate_decision.decision_sha256,
528
+ "continuation_evaluation_batch_sha256s": [
529
+ value.batch_sha256
530
+ for value in self.continuation_evaluation_batches
531
+ ],
532
+ "phase_receipt_sha256s": [
533
+ value.receipt_sha256 for value in self.phase_receipts
534
+ ],
535
+ "phase_commit_ack_sha256s": [
536
+ value.ack_sha256 for value in self.phase_commit_acks
537
+ ],
538
+ "archive_credit_in_combined_result": False,
539
+ "workload_objective_model_provider_prompt_branches": False,
540
+ }
541
+
542
+ def to_record(self, *, include_evidence: bool = False) -> dict[str, object]:
543
+ self.__post_init__()
544
+ return {
545
+ **self._unsigned_record(),
546
+ "allocation_plan": self.allocation_plan.to_record(
547
+ include_evidence=include_evidence
548
+ ),
549
+ "pilot_evaluation_batches": [
550
+ value.to_record(include_evidence=include_evidence)
551
+ for value in self.pilot_evaluation_batches
552
+ ],
553
+ "pilot_outcomes": self.pilot_outcomes.to_record(
554
+ include_evidence=include_evidence
555
+ ),
556
+ "gate_decision": self.gate_decision.to_record(
557
+ include_evidence=include_evidence
558
+ ),
559
+ "continuation_evaluation_batches": [
560
+ value.to_record(include_evidence=include_evidence)
561
+ for value in self.continuation_evaluation_batches
562
+ ],
563
+ "phase_receipts": [
564
+ value.to_record(include_evidence=include_evidence)
565
+ for value in self.phase_receipts
566
+ ],
567
+ "phase_commit_acks": [
568
+ value.to_record(include_evidence=include_evidence)
569
+ for value in self.phase_commit_acks
570
+ ],
571
+ "combined_result": self.result.to_record(),
572
+ "sequential_result_sha256": self.sequential_result_sha256,
573
+ }
574
+
575
+
576
+ @dataclass(frozen=True, slots=True)
577
+ class SequentialResidualPortfolioEvolution:
578
+ """Execute one proposal universe through a K-pilot plus K-rest gate."""
579
+
580
+ experts: tuple[MaterializedActionProposalExpertPort, ...]
581
+ broker: RegretBrokeredMaterializedActionPolicy
582
+ planner: SequentialLineageAllocationPlannerPort = field(
583
+ repr=False,
584
+ compare=False,
585
+ )
586
+ pilot_outcome_projector: SequentialPilotOutcomeProjectorPort = field(
587
+ repr=False,
588
+ compare=False,
589
+ )
590
+ slate_value: MaterializedSlateValuePort = field(
591
+ repr=False,
592
+ compare=False,
593
+ )
594
+ slate_feasibility: MaterializedSlateFeasibilityPort = field(
595
+ repr=False,
596
+ compare=False,
597
+ )
598
+ gate: SequentialAllocationGatePort = field(
599
+ default_factory=AnyPositiveSequentialLineageGate,
600
+ repr=False,
601
+ compare=False,
602
+ )
603
+ phase_committer: SequentialResidualPhaseCommitPort | None = field(
604
+ default=None,
605
+ repr=False,
606
+ compare=False,
607
+ )
608
+ require_durable_phase_commits: bool = False
609
+
610
+ def __post_init__(self) -> None:
611
+ if type(self.experts) is not tuple or not self.experts:
612
+ raise ValueError("experts must be a non-empty exact tuple")
613
+ if any(
614
+ getattr(value, "evaluation_wave_semantics", None)
615
+ != DISJOINT_ACTION_EVALUATION_WAVES_V1
616
+ for value in self.experts
617
+ ):
618
+ raise ValueError(
619
+ "sequential experts must support disjoint action "
620
+ "evaluation waves"
621
+ )
622
+ if type(self.broker) is not RegretBrokeredMaterializedActionPolicy:
623
+ raise TypeError("broker must be an exact regret-broker policy")
624
+ self.broker.__post_init__()
625
+ _planner_identity(self.planner)
626
+ _projector_identity(self.pilot_outcome_projector)
627
+ if not isinstance(self.slate_value, MaterializedSlateValuePort):
628
+ raise TypeError("slate_value must implement its application port")
629
+ if not isinstance(
630
+ self.slate_feasibility,
631
+ MaterializedSlateFeasibilityPort,
632
+ ):
633
+ raise TypeError(
634
+ "slate_feasibility must implement its application port"
635
+ )
636
+ require_sha256(
637
+ self.slate_value.definition_sha256,
638
+ "slate value definition_sha256",
639
+ )
640
+ require_sha256(
641
+ self.slate_feasibility.definition_sha256,
642
+ "slate feasibility definition_sha256",
643
+ )
644
+ _gate_identity(self.gate)
645
+ if self.phase_committer is not None:
646
+ _committer_identity(self.phase_committer)
647
+ if type(self.require_durable_phase_commits) is not bool:
648
+ raise TypeError("require_durable_phase_commits must be exact")
649
+ if (
650
+ self.require_durable_phase_commits
651
+ and self.phase_committer is None
652
+ ):
653
+ raise ValueError(
654
+ "required durable phase commits need a committer"
655
+ )
656
+
657
+ async def _commit(
658
+ self,
659
+ receipt: SequentialResidualPhaseReceipt,
660
+ ) -> SequentialResidualPhaseCommitAck | None:
661
+ if self.phase_committer is None:
662
+ return None
663
+ identity = _committer_identity(self.phase_committer)
664
+ ack = await self.phase_committer.commit(receipt)
665
+ if type(ack) is not SequentialResidualPhaseCommitAck:
666
+ raise TypeError("phase committer returned a foreign ack")
667
+ ack.__post_init__()
668
+ if (
669
+ ack.committer_id,
670
+ ack.committer_version,
671
+ ack.committer_definition_sha256,
672
+ ) != identity:
673
+ raise ValueError("phase commit ack has a foreign identity")
674
+ if ack.phase_receipt_sha256 != receipt.receipt_sha256:
675
+ raise ValueError("phase commit ack targets another receipt")
676
+ if self.require_durable_phase_commits and not ack.durable:
677
+ raise ValueError("required phase commit was not durable")
678
+ return ack
679
+
680
+ async def run(
681
+ self,
682
+ request: ResidualPortfolioDecisionRequest,
683
+ ) -> SequentialResidualPortfolioEvolutionResult:
684
+ self.__post_init__()
685
+ if type(request) is not ResidualPortfolioDecisionRequest:
686
+ raise TypeError("request must be exact")
687
+ request.__post_init__()
688
+ proposals = await propose_materialized_action_batches(
689
+ experts=self.experts,
690
+ request=request,
691
+ )
692
+ plan = await self.planner.plan(request, proposals)
693
+ if not isinstance(plan, SequentialAllocationPlanPort):
694
+ raise TypeError(
695
+ "planner returned a value outside the plan port"
696
+ )
697
+ plan_receipt = SequentialResidualPhaseReceipt(
698
+ phase=SequentialResidualPhase.PLAN_FROZEN,
699
+ residual_request_sha256=request.request_sha256,
700
+ plan_sha256=plan.plan_sha256,
701
+ product_sha256s=(
702
+ plan.pilot_requirement.requirement_sha256,
703
+ *(
704
+ value.requirement_sha256
705
+ for value in plan.frozen_requirements
706
+ ),
707
+ ),
708
+ evidence=freeze_json(
709
+ {
710
+ "proposal_sha256s": list(plan.proposal_sha256s),
711
+ "complete_branch_count": len(
712
+ plan.frozen_requirements
713
+ ),
714
+ "all_complete_branches_frozen": True,
715
+ "current_candidate_outcomes_observed": False,
716
+ "allocation_plan": plan.to_record(
717
+ include_evidence=True
718
+ ),
719
+ }
720
+ ),
721
+ )
722
+ phase_receipts = [plan_receipt]
723
+ phase_acks: list[SequentialResidualPhaseCommitAck] = []
724
+ plan_ack = await self._commit(plan_receipt)
725
+ if plan_ack is not None:
726
+ phase_acks.append(plan_ack)
727
+
728
+ pilot_batches: tuple[MaterializedActionEvaluationBatch, ...]
729
+ if plan.pilot_action_sha256s:
730
+ pilot_batches = await evaluate_materialized_action_subset(
731
+ experts=self.experts,
732
+ proposals=proposals,
733
+ selected_action_sha256s=plan.pilot_action_sha256s,
734
+ )
735
+ else:
736
+ pilot_batches = ()
737
+ pilot_evaluations = _flatten_evaluations(pilot_batches)
738
+ pilot_outcomes = self.pilot_outcome_projector.project(
739
+ plan,
740
+ pilot_evaluations,
741
+ )
742
+ pilot_evaluated_receipt = SequentialResidualPhaseReceipt(
743
+ phase=SequentialResidualPhase.PILOT_EVALUATED,
744
+ residual_request_sha256=request.request_sha256,
745
+ plan_sha256=plan.plan_sha256,
746
+ product_sha256s=(
747
+ *(
748
+ value.batch_sha256 for value in pilot_batches
749
+ ),
750
+ pilot_outcomes.batch_sha256,
751
+ ),
752
+ evidence=freeze_json(
753
+ {
754
+ "pilot_action_sha256s": list(
755
+ plan.pilot_action_sha256s
756
+ ),
757
+ "pilot_evaluation_count": len(
758
+ pilot_evaluations
759
+ ),
760
+ "later_candidate_outcomes_observed": False,
761
+ "gate_decision_observed": False,
762
+ "pilot_evaluation_batches": [
763
+ value.to_record(include_evidence=True)
764
+ for value in pilot_batches
765
+ ],
766
+ "pilot_outcomes": pilot_outcomes.to_record(
767
+ include_evidence=True
768
+ ),
769
+ }
770
+ ),
771
+ )
772
+ phase_receipts.append(pilot_evaluated_receipt)
773
+ pilot_evaluated_ack = await self._commit(
774
+ pilot_evaluated_receipt
775
+ )
776
+ if pilot_evaluated_ack is not None:
777
+ phase_acks.append(pilot_evaluated_ack)
778
+
779
+ gate_decision = self.gate.decide(plan, pilot_outcomes)
780
+ if not isinstance(
781
+ gate_decision,
782
+ SequentialAllocationGateDecisionPort,
783
+ ):
784
+ raise TypeError("gate returned a value outside its decision port")
785
+ selected_requirement = plan.requirement_for(
786
+ gate_decision.selected_branch_id
787
+ )
788
+ if (
789
+ gate_decision.plan_sha256 != plan.plan_sha256
790
+ or gate_decision.pilot_outcome_batch_sha256
791
+ != pilot_outcomes.batch_sha256
792
+ or gate_decision.selected_requirement_sha256
793
+ != selected_requirement.requirement_sha256
794
+ ):
795
+ raise ValueError("gate decision does not close the frozen plan")
796
+ pilot_receipt = SequentialResidualPhaseReceipt(
797
+ phase=SequentialResidualPhase.PILOT_ADJUDICATED,
798
+ residual_request_sha256=request.request_sha256,
799
+ plan_sha256=plan.plan_sha256,
800
+ product_sha256s=(
801
+ pilot_evaluated_receipt.receipt_sha256,
802
+ gate_decision.decision_sha256,
803
+ selected_requirement.requirement_sha256,
804
+ ),
805
+ evidence=freeze_json(
806
+ {
807
+ "pilot_action_sha256s": list(
808
+ plan.pilot_action_sha256s
809
+ ),
810
+ "positive_pilot_count": (
811
+ gate_decision.positive_pilot_count
812
+ ),
813
+ "selected_branch": (
814
+ gate_decision.selected_branch_id
815
+ ),
816
+ "later_candidate_outcomes_observed": False,
817
+ "pilot_evaluated_receipt_sha256": (
818
+ pilot_evaluated_receipt.receipt_sha256
819
+ ),
820
+ "gate_decision": gate_decision.to_record(
821
+ include_evidence=True
822
+ ),
823
+ "selected_requirement": (
824
+ selected_requirement.to_record(
825
+ include_evidence=True
826
+ )
827
+ ),
828
+ }
829
+ ),
830
+ )
831
+ phase_receipts.append(pilot_receipt)
832
+ pilot_ack = await self._commit(pilot_receipt)
833
+ if pilot_ack is not None:
834
+ phase_acks.append(pilot_ack)
835
+
836
+ pilot_ids = set(plan.pilot_action_sha256s)
837
+ continuation_ids = tuple(
838
+ value
839
+ for value in selected_requirement.required_action_sha256s
840
+ if value not in pilot_ids
841
+ )
842
+ if not continuation_ids:
843
+ raise ValueError("sequential branch leaves no continuation wave")
844
+ continuation_batches = await evaluate_materialized_action_subset(
845
+ experts=self.experts,
846
+ proposals=proposals,
847
+ selected_action_sha256s=continuation_ids,
848
+ )
849
+ actions = tuple(
850
+ action for proposal in proposals for action in proposal.actions
851
+ )
852
+ final_decision = self.broker.select(
853
+ MaterializedActionBrokerRequest(
854
+ actions=actions,
855
+ evaluation_slots=request.evaluation_slots,
856
+ slate_value=self.slate_value,
857
+ slate_feasibility=self.slate_feasibility,
858
+ reference_escrow_slots=request.reference_escrow_slots,
859
+ allocation_requirement=selected_requirement,
860
+ )
861
+ )
862
+ if tuple(
863
+ value.action_sha256 for value in final_decision.selected_actions
864
+ ) != selected_requirement.required_action_sha256s:
865
+ raise ValueError("final broker did not honor the complete branch")
866
+ merged = _merge_evaluation_waves(
867
+ proposals,
868
+ pilot_batches,
869
+ continuation_batches,
870
+ )
871
+ combined = ResidualPortfolioEvolutionResult(
872
+ request=request,
873
+ proposals=proposals,
874
+ broker_decision=final_decision,
875
+ evaluation_batches=merged,
876
+ slate_value_definition_sha256=self.slate_value.definition_sha256,
877
+ slate_feasibility_definition_sha256=(
878
+ self.slate_feasibility.definition_sha256
879
+ ),
880
+ )
881
+ final_receipt = SequentialResidualPhaseReceipt(
882
+ phase=SequentialResidualPhase.FINALIZED,
883
+ residual_request_sha256=request.request_sha256,
884
+ plan_sha256=plan.plan_sha256,
885
+ product_sha256s=(
886
+ *(
887
+ value.batch_sha256
888
+ for value in continuation_batches
889
+ ),
890
+ final_decision.decision_sha256,
891
+ combined.result_sha256,
892
+ ),
893
+ evidence=freeze_json(
894
+ {
895
+ "selected_branch": (
896
+ gate_decision.selected_branch_id
897
+ ),
898
+ "selected_action_sha256s": list(
899
+ selected_requirement.required_action_sha256s
900
+ ),
901
+ "pilot_evaluation_count": len(pilot_evaluations),
902
+ "continuation_evaluation_count": len(
903
+ _flatten_evaluations(continuation_batches)
904
+ ),
905
+ "continuation_evaluation_batches": [
906
+ value.to_record(include_evidence=True)
907
+ for value in continuation_batches
908
+ ],
909
+ "final_broker_decision": final_decision.to_record(),
910
+ "real_evaluation_budget_preserved": True,
911
+ }
912
+ ),
913
+ )
914
+ phase_receipts.append(final_receipt)
915
+ final_ack = await self._commit(final_receipt)
916
+ if final_ack is not None:
917
+ phase_acks.append(final_ack)
918
+ return SequentialResidualPortfolioEvolutionResult(
919
+ result=combined,
920
+ allocation_plan=plan,
921
+ pilot_evaluation_batches=pilot_batches,
922
+ pilot_outcomes=pilot_outcomes,
923
+ gate_decision=gate_decision,
924
+ continuation_evaluation_batches=continuation_batches,
925
+ phase_receipts=tuple(phase_receipts),
926
+ phase_commit_acks=tuple(phase_acks),
927
+ )
928
+
929
+
930
+ __all__ = [
931
+ "SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_DEFINITION_SHA256",
932
+ "SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_ID",
933
+ "SEQUENTIAL_RESIDUAL_PORTFOLIO_EVOLUTION_VERSION",
934
+ "SequentialResidualPhase",
935
+ "SequentialResidualPhaseCommitAck",
936
+ "SequentialResidualPhaseCommitPort",
937
+ "SequentialResidualPhaseReceipt",
938
+ "SequentialResidualPortfolioEvolution",
939
+ "SequentialResidualPortfolioEvolutionResult",
940
+ ]