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,827 @@
1
+ """Provider- and workload-neutral contextual allocation contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import re
8
+ from dataclasses import dataclass, field
9
+
10
+ from agent_evolve.domain.patch import require_sha256
11
+
12
+
13
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
14
+ _CONTRACT_DOMAIN = b"agent-evolve:contextual-portfolio-allocation-contract:v1\x00"
15
+ _REALIZATION_DOMAIN = b"agent-evolve:contextual-portfolio-allocation-realization:v1\x00"
16
+ _CAPABILITY_WITNESS_DOMAIN = (
17
+ b"agent-evolve:contextual-arm-count-capability-witness:v1\x00"
18
+ )
19
+ _CAPABILITY_DOMAIN = b"agent-evolve:contextual-arm-count-capability:v1\x00"
20
+ _JOINT_VECTOR_DOMAIN = b"agent-evolve:contextual-joint-count-vector:v1\x00"
21
+ _LANE_JOINT_CAPABILITY_DOMAIN = (
22
+ b"agent-evolve:contextual-lane-joint-count-capability:v1\x00"
23
+ )
24
+
25
+
26
+ def _canonical_json(value: object) -> bytes:
27
+ return json.dumps(
28
+ value,
29
+ allow_nan=False,
30
+ ensure_ascii=True,
31
+ separators=(",", ":"),
32
+ sort_keys=True,
33
+ ).encode("ascii", errors="strict")
34
+
35
+
36
+ def _require_token(value: str, *, name: str) -> None:
37
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
38
+ raise ValueError(f"{name} must use the closed token grammar")
39
+
40
+
41
+ def _validate_counts(
42
+ values: tuple[tuple[str, int], ...],
43
+ *,
44
+ name: str,
45
+ expected_slots: int,
46
+ ) -> None:
47
+ if type(values) is not tuple or not values:
48
+ raise ValueError(f"{name} must be a non-empty exact tuple")
49
+ for arm_id, count in values:
50
+ _require_token(arm_id, name=f"{name}.arm_id")
51
+ if type(count) is not int or count < 0:
52
+ raise ValueError(f"{name} counts must be non-negative")
53
+ if values != tuple(sorted(values)) or len({value[0] for value in values}) != len(
54
+ values
55
+ ):
56
+ raise ValueError(f"{name} must use canonical unique arms")
57
+ if sum(value[1] for value in values) != expected_slots:
58
+ raise ValueError(f"{name} must allocate every evaluation slot")
59
+
60
+
61
+ @dataclass(frozen=True, slots=True)
62
+ class ContextualArmCountCapabilityWitness:
63
+ """One prior, actually realized stage-level arm-count vector.
64
+
65
+ A witness says only that an allocation was realizable under an earlier
66
+ prior-wave candidate set. It is deliberately weaker than a promise about
67
+ the current wave. Keeping that distinction explicit lets a controller use
68
+ the evidence conservatively without smuggling workload rules into the
69
+ application layer.
70
+ """
71
+
72
+ controller_wave_index: int
73
+ evaluation_slots: int
74
+ realized_target_counts: tuple[tuple[str, int], ...]
75
+ allocation_realization_sha256s: tuple[str, ...]
76
+ witness_sha256: str = field(init=False)
77
+
78
+ def __post_init__(self) -> None:
79
+ if (
80
+ type(self.controller_wave_index) is not int
81
+ or self.controller_wave_index <= 0
82
+ ):
83
+ raise ValueError("controller_wave_index must be positive")
84
+ if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
85
+ raise ValueError("evaluation_slots must be positive")
86
+ _validate_counts(
87
+ self.realized_target_counts,
88
+ name="realized_target_counts",
89
+ expected_slots=self.evaluation_slots,
90
+ )
91
+ if (
92
+ type(self.allocation_realization_sha256s) is not tuple
93
+ or not self.allocation_realization_sha256s
94
+ or self.allocation_realization_sha256s
95
+ != tuple(sorted(set(self.allocation_realization_sha256s)))
96
+ ):
97
+ raise ValueError(
98
+ "allocation realization hashes must be non-empty and canonical"
99
+ )
100
+ for value in self.allocation_realization_sha256s:
101
+ require_sha256(value, "allocation_realization_sha256")
102
+ object.__setattr__(
103
+ self,
104
+ "witness_sha256",
105
+ hashlib.sha256(
106
+ _CAPABILITY_WITNESS_DOMAIN + _canonical_json(self._unsigned_record())
107
+ ).hexdigest(),
108
+ )
109
+
110
+ def _unsigned_record(self) -> dict[str, object]:
111
+ return {
112
+ "schema_version": 1,
113
+ "controller_wave_index": self.controller_wave_index,
114
+ "evaluation_slots": self.evaluation_slots,
115
+ "realized_target_counts": [
116
+ list(value) for value in self.realized_target_counts
117
+ ],
118
+ "allocation_realization_sha256s": list(self.allocation_realization_sha256s),
119
+ "interpretation": "prior_realized_witness_not_current_capacity_promise",
120
+ "objective_values_consulted": False,
121
+ "workload_identifiers_consulted": False,
122
+ }
123
+
124
+ def to_record(self) -> dict[str, object]:
125
+ self.__post_init__()
126
+ return {**self._unsigned_record(), "witness_sha256": self.witness_sha256}
127
+
128
+
129
+ @dataclass(frozen=True, slots=True)
130
+ class ContextualArmCountCapability:
131
+ """A workload-blind empirical feasible-count set for one arm kind."""
132
+
133
+ kind: str
134
+ evaluation_slots: int
135
+ arm_ids: tuple[str, ...]
136
+ witnesses: tuple[ContextualArmCountCapabilityWitness, ...]
137
+ capability_sha256: str = field(init=False)
138
+
139
+ def __post_init__(self) -> None:
140
+ if self.kind not in {"source", "operator"}:
141
+ raise ValueError("kind must be source or operator")
142
+ if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
143
+ raise ValueError("evaluation_slots must be positive")
144
+ if type(self.arm_ids) is not tuple or not self.arm_ids:
145
+ raise ValueError("arm_ids must be a non-empty exact tuple")
146
+ for value in self.arm_ids:
147
+ _require_token(value, name="arm_id")
148
+ if self.arm_ids != tuple(sorted(set(self.arm_ids))):
149
+ raise ValueError("arm_ids must be unique and canonical")
150
+ if (
151
+ type(self.witnesses) is not tuple
152
+ or not self.witnesses
153
+ or any(
154
+ type(value) is not ContextualArmCountCapabilityWitness
155
+ for value in self.witnesses
156
+ )
157
+ ):
158
+ raise ValueError("witnesses must contain exact capability witnesses")
159
+ for value in self.witnesses:
160
+ value.__post_init__()
161
+ if value.evaluation_slots != self.evaluation_slots:
162
+ raise ValueError("capability witness has a different stage width")
163
+ if tuple(arm_id for arm_id, _ in value.realized_target_counts) != (
164
+ self.arm_ids
165
+ ):
166
+ raise ValueError("capability witness has different arms")
167
+ if tuple(value.witness_sha256 for value in self.witnesses) != tuple(
168
+ sorted({value.witness_sha256 for value in self.witnesses})
169
+ ):
170
+ raise ValueError("capability witnesses must be unique and canonical")
171
+ object.__setattr__(
172
+ self,
173
+ "capability_sha256",
174
+ hashlib.sha256(
175
+ _CAPABILITY_DOMAIN + _canonical_json(self._unsigned_record())
176
+ ).hexdigest(),
177
+ )
178
+
179
+ @property
180
+ def feasible_count_vectors(self) -> tuple[tuple[tuple[str, int], ...], ...]:
181
+ """Return unique witnessed vectors in deterministic count order."""
182
+
183
+ return tuple(sorted({value.realized_target_counts for value in self.witnesses}))
184
+
185
+ @property
186
+ def allocation_realization_sha256s(self) -> tuple[str, ...]:
187
+ return tuple(
188
+ sorted(
189
+ {
190
+ receipt
191
+ for witness in self.witnesses
192
+ for receipt in witness.allocation_realization_sha256s
193
+ }
194
+ )
195
+ )
196
+
197
+ def _unsigned_record(self) -> dict[str, object]:
198
+ return {
199
+ "schema_version": 1,
200
+ "kind": self.kind,
201
+ "evaluation_slots": self.evaluation_slots,
202
+ "arm_ids": list(self.arm_ids),
203
+ "witnesses": [value.to_record() for value in self.witnesses],
204
+ "feasible_count_vectors": [
205
+ [list(value) for value in vector]
206
+ for vector in self.feasible_count_vectors
207
+ ],
208
+ "current_capacity_guaranteed": False,
209
+ "objective_values_consulted": False,
210
+ "workload_identifiers_consulted": False,
211
+ }
212
+
213
+ def to_record(self) -> dict[str, object]:
214
+ self.__post_init__()
215
+ return {
216
+ **self._unsigned_record(),
217
+ "capability_sha256": self.capability_sha256,
218
+ }
219
+
220
+
221
+ @dataclass(frozen=True, slots=True)
222
+ class ContextualJointCountVector:
223
+ """One prospectively witnessed source x operator marginal pair.
224
+
225
+ The vector deliberately carries only arm counts and immutable finite-option
226
+ identities. Objective values, ranks, model outputs, and workload names are
227
+ outside this port. A lane capability may retain one canonical witness for
228
+ each distinct marginal pair even when many option subsets realize it.
229
+ """
230
+
231
+ source_target_counts: tuple[tuple[str, int], ...]
232
+ operator_target_counts: tuple[tuple[str, int], ...]
233
+ feasibility_witness_option_identity_sha256s: tuple[str, ...]
234
+ vector_sha256: str = field(init=False)
235
+
236
+ def __post_init__(self) -> None:
237
+ slots = sum(value[1] for value in self.source_target_counts)
238
+ if slots <= 0:
239
+ raise ValueError("joint count vector must cover positive capacity")
240
+ _validate_counts(
241
+ self.source_target_counts,
242
+ name="source_target_counts",
243
+ expected_slots=slots,
244
+ )
245
+ _validate_counts(
246
+ self.operator_target_counts,
247
+ name="operator_target_counts",
248
+ expected_slots=slots,
249
+ )
250
+ witnesses = self.feasibility_witness_option_identity_sha256s
251
+ if (
252
+ type(witnesses) is not tuple
253
+ or len(witnesses) != slots
254
+ or witnesses != tuple(sorted(set(witnesses)))
255
+ ):
256
+ raise ValueError(
257
+ "joint count vector requires one canonical unique witness per slot"
258
+ )
259
+ for value in witnesses:
260
+ require_sha256(value, "feasibility_witness_option_identity_sha256")
261
+ object.__setattr__(
262
+ self,
263
+ "vector_sha256",
264
+ hashlib.sha256(
265
+ _JOINT_VECTOR_DOMAIN + _canonical_json(self._unsigned_record())
266
+ ).hexdigest(),
267
+ )
268
+
269
+ @property
270
+ def evaluation_slots(self) -> int:
271
+ return sum(value[1] for value in self.source_target_counts)
272
+
273
+ def _unsigned_record(self) -> dict[str, object]:
274
+ return {
275
+ "schema_version": 1,
276
+ "source_target_counts": [
277
+ list(value) for value in self.source_target_counts
278
+ ],
279
+ "operator_target_counts": [
280
+ list(value) for value in self.operator_target_counts
281
+ ],
282
+ "feasibility_witness_option_identity_sha256s": list(
283
+ self.feasibility_witness_option_identity_sha256s
284
+ ),
285
+ "objective_values_consulted": False,
286
+ "workload_identifiers_consulted": False,
287
+ }
288
+
289
+ def to_record(self) -> dict[str, object]:
290
+ self.__post_init__()
291
+ return {**self._unsigned_record(), "vector_sha256": self.vector_sha256}
292
+
293
+
294
+ @dataclass(frozen=True, slots=True)
295
+ class ContextualLaneJointCountCapability:
296
+ """Exact finite-contract marginal capability for one concurrent lane."""
297
+
298
+ slice_id: str
299
+ finite_contract_identity_sha256: str
300
+ structural_constraint_sha256: str
301
+ evaluation_slots: int
302
+ source_arm_ids: tuple[str, ...]
303
+ operator_arm_ids: tuple[str, ...]
304
+ feasible_vectors: tuple[ContextualJointCountVector, ...]
305
+ minimum_single_path_interventions: int = 0
306
+ minimum_disjoint_parent_patch_pairs: int = 0
307
+ capability_sha256: str = field(init=False)
308
+
309
+ def __post_init__(self) -> None:
310
+ _require_token(self.slice_id, name="slice_id")
311
+ require_sha256(
312
+ self.finite_contract_identity_sha256,
313
+ "finite_contract_identity_sha256",
314
+ )
315
+ require_sha256(
316
+ self.structural_constraint_sha256,
317
+ "structural_constraint_sha256",
318
+ )
319
+ if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
320
+ raise ValueError("evaluation_slots must be positive")
321
+ if (
322
+ type(self.minimum_single_path_interventions) is not int
323
+ or not 0
324
+ <= self.minimum_single_path_interventions
325
+ <= self.evaluation_slots
326
+ ):
327
+ raise ValueError(
328
+ "minimum_single_path_interventions must lie in lane capacity"
329
+ )
330
+ maximum_pairs = self.evaluation_slots * (self.evaluation_slots - 1) // 2
331
+ if (
332
+ type(self.minimum_disjoint_parent_patch_pairs) is not int
333
+ or not 0
334
+ <= self.minimum_disjoint_parent_patch_pairs
335
+ <= maximum_pairs
336
+ ):
337
+ raise ValueError(
338
+ "minimum_disjoint_parent_patch_pairs must lie in lane pair capacity"
339
+ )
340
+ for name in ("source_arm_ids", "operator_arm_ids"):
341
+ values = getattr(self, name)
342
+ if type(values) is not tuple or not values:
343
+ raise ValueError(f"{name} must be a non-empty exact tuple")
344
+ for value in values:
345
+ _require_token(value, name=name)
346
+ if values != tuple(sorted(set(values))):
347
+ raise ValueError(f"{name} must be unique and canonical")
348
+ if (
349
+ type(self.feasible_vectors) is not tuple
350
+ or not self.feasible_vectors
351
+ or any(
352
+ type(value) is not ContextualJointCountVector
353
+ for value in self.feasible_vectors
354
+ )
355
+ ):
356
+ raise ValueError("feasible_vectors must contain exact joint vectors")
357
+ for value in self.feasible_vectors:
358
+ value.__post_init__()
359
+ if value.evaluation_slots != self.evaluation_slots:
360
+ raise ValueError("joint vector has a different lane capacity")
361
+ if tuple(arm_id for arm_id, _ in value.source_target_counts) != (
362
+ self.source_arm_ids
363
+ ):
364
+ raise ValueError("joint vector has different source arms")
365
+ if tuple(arm_id for arm_id, _ in value.operator_target_counts) != (
366
+ self.operator_arm_ids
367
+ ):
368
+ raise ValueError("joint vector has different operator arms")
369
+ vector_hashes = tuple(value.vector_sha256 for value in self.feasible_vectors)
370
+ if vector_hashes != tuple(sorted(set(vector_hashes))):
371
+ raise ValueError("joint vectors must be unique and hash-canonical")
372
+ marginal_pairs = tuple(
373
+ (value.source_target_counts, value.operator_target_counts)
374
+ for value in self.feasible_vectors
375
+ )
376
+ if len(set(marginal_pairs)) != len(marginal_pairs):
377
+ raise ValueError("joint capability repeats one marginal pair")
378
+ object.__setattr__(
379
+ self,
380
+ "capability_sha256",
381
+ hashlib.sha256(
382
+ _LANE_JOINT_CAPABILITY_DOMAIN
383
+ + _canonical_json(self._unsigned_record())
384
+ ).hexdigest(),
385
+ )
386
+
387
+ def resolve_vector(self, vector_sha256: str) -> ContextualJointCountVector:
388
+ require_sha256(vector_sha256, "vector_sha256")
389
+ try:
390
+ return next(
391
+ value
392
+ for value in self.feasible_vectors
393
+ if value.vector_sha256 == vector_sha256
394
+ )
395
+ except StopIteration as error:
396
+ raise ValueError(
397
+ "joint vector is absent from this lane capability"
398
+ ) from error
399
+
400
+ def _unsigned_record(self) -> dict[str, object]:
401
+ record: dict[str, object] = {
402
+ "schema_version": (
403
+ 3
404
+ if self.minimum_disjoint_parent_patch_pairs
405
+ else 2
406
+ if self.minimum_single_path_interventions
407
+ else 1
408
+ ),
409
+ "slice_id": self.slice_id,
410
+ "finite_contract_identity_sha256": self.finite_contract_identity_sha256,
411
+ "structural_constraint_sha256": self.structural_constraint_sha256,
412
+ "evaluation_slots": self.evaluation_slots,
413
+ "source_arm_ids": list(self.source_arm_ids),
414
+ "operator_arm_ids": list(self.operator_arm_ids),
415
+ "feasible_vectors": [value.to_record() for value in self.feasible_vectors],
416
+ "current_capacity_guaranteed": True,
417
+ "objective_values_consulted": False,
418
+ "workload_identifiers_consulted": False,
419
+ }
420
+ if self.minimum_single_path_interventions:
421
+ record["minimum_single_path_interventions"] = (
422
+ self.minimum_single_path_interventions
423
+ )
424
+ record["intervention_axis"] = (
425
+ "exact_parent_relative_changed_json_path_count"
426
+ )
427
+ if self.minimum_disjoint_parent_patch_pairs:
428
+ record["minimum_disjoint_parent_patch_pairs"] = (
429
+ self.minimum_disjoint_parent_patch_pairs
430
+ )
431
+ record["offspring_opportunity_axis"] = (
432
+ "pairwise_disjoint_parent_relative_patch_pairs"
433
+ )
434
+ return record
435
+
436
+ def to_record(self) -> dict[str, object]:
437
+ self.__post_init__()
438
+ return {**self._unsigned_record(), "capability_sha256": self.capability_sha256}
439
+
440
+
441
+ @dataclass(frozen=True, slots=True)
442
+ class ContextualPortfolioAllocationContract:
443
+ """Exact request-local exposure targets from a prior-only controller."""
444
+
445
+ campaign_scope_sha256: str
446
+ query_sha256: str
447
+ decision_sha256: str
448
+ campaign_generation: int
449
+ controller_wave_index: int
450
+ phase_id: str
451
+ slice_id: str
452
+ evaluation_slots: int
453
+ source_target_counts: tuple[tuple[str, int], ...]
454
+ operator_target_counts: tuple[tuple[str, int], ...]
455
+ minimum_single_path_interventions: int = 0
456
+ minimum_disjoint_parent_patch_pairs: int = 0
457
+ feasibility_witness_option_identity_sha256s: tuple[str, ...] = ()
458
+ contract_sha256: str = field(init=False)
459
+
460
+ def __post_init__(self) -> None:
461
+ for name in (
462
+ "campaign_scope_sha256",
463
+ "query_sha256",
464
+ "decision_sha256",
465
+ ):
466
+ require_sha256(getattr(self, name), name)
467
+ for name in ("campaign_generation", "controller_wave_index"):
468
+ value = getattr(self, name)
469
+ if type(value) is not int or value <= 0:
470
+ raise ValueError(f"{name} must be positive")
471
+ _require_token(self.phase_id, name="phase_id")
472
+ _require_token(self.slice_id, name="slice_id")
473
+ if type(self.evaluation_slots) is not int or self.evaluation_slots <= 0:
474
+ raise ValueError("evaluation_slots must be positive")
475
+ if (
476
+ type(self.minimum_single_path_interventions) is not int
477
+ or not 0
478
+ <= self.minimum_single_path_interventions
479
+ <= self.evaluation_slots
480
+ ):
481
+ raise ValueError(
482
+ "minimum_single_path_interventions must lie in allocation capacity"
483
+ )
484
+ maximum_pairs = self.evaluation_slots * (self.evaluation_slots - 1) // 2
485
+ if (
486
+ type(self.minimum_disjoint_parent_patch_pairs) is not int
487
+ or not 0
488
+ <= self.minimum_disjoint_parent_patch_pairs
489
+ <= maximum_pairs
490
+ ):
491
+ raise ValueError(
492
+ "minimum_disjoint_parent_patch_pairs must lie in allocation pair "
493
+ "capacity"
494
+ )
495
+ _validate_counts(
496
+ self.source_target_counts,
497
+ name="source_target_counts",
498
+ expected_slots=self.evaluation_slots,
499
+ )
500
+ _validate_counts(
501
+ self.operator_target_counts,
502
+ name="operator_target_counts",
503
+ expected_slots=self.evaluation_slots,
504
+ )
505
+ witnesses = self.feasibility_witness_option_identity_sha256s
506
+ if type(witnesses) is not tuple:
507
+ raise TypeError(
508
+ "feasibility_witness_option_identity_sha256s must be an exact tuple"
509
+ )
510
+ if witnesses:
511
+ if len(witnesses) != self.evaluation_slots or witnesses != tuple(
512
+ sorted(set(witnesses))
513
+ ):
514
+ raise ValueError(
515
+ "allocation feasibility witness must contain one canonical "
516
+ "unique option identity per evaluation slot"
517
+ )
518
+ for value in witnesses:
519
+ require_sha256(value, "feasibility_witness_option_identity_sha256")
520
+ object.__setattr__(
521
+ self,
522
+ "contract_sha256",
523
+ hashlib.sha256(
524
+ _CONTRACT_DOMAIN + _canonical_json(self._unsigned_record())
525
+ ).hexdigest(),
526
+ )
527
+
528
+ def _unsigned_record(self) -> dict[str, object]:
529
+ record: dict[str, object] = {
530
+ "schema_version": (
531
+ 4
532
+ if self.feasibility_witness_option_identity_sha256s
533
+ else 3
534
+ if self.minimum_disjoint_parent_patch_pairs
535
+ else 2
536
+ if self.minimum_single_path_interventions
537
+ else 1
538
+ ),
539
+ "campaign_scope_sha256": self.campaign_scope_sha256,
540
+ "query_sha256": self.query_sha256,
541
+ "decision_sha256": self.decision_sha256,
542
+ "campaign_generation": self.campaign_generation,
543
+ "controller_wave_index": self.controller_wave_index,
544
+ "phase_id": self.phase_id,
545
+ "slice_id": self.slice_id,
546
+ "evaluation_slots": self.evaluation_slots,
547
+ "source_target_counts": [
548
+ list(value) for value in self.source_target_counts
549
+ ],
550
+ "operator_target_counts": [
551
+ list(value) for value in self.operator_target_counts
552
+ ],
553
+ }
554
+ if self.minimum_single_path_interventions:
555
+ record["minimum_single_path_interventions"] = (
556
+ self.minimum_single_path_interventions
557
+ )
558
+ record["intervention_axis"] = (
559
+ "exact_parent_relative_changed_json_path_count"
560
+ )
561
+ if self.minimum_disjoint_parent_patch_pairs:
562
+ record["minimum_disjoint_parent_patch_pairs"] = (
563
+ self.minimum_disjoint_parent_patch_pairs
564
+ )
565
+ record["offspring_opportunity_axis"] = (
566
+ "pairwise_disjoint_parent_relative_patch_pairs"
567
+ )
568
+ if self.feasibility_witness_option_identity_sha256s:
569
+ record["feasibility_witness_option_identity_sha256s"] = list(
570
+ self.feasibility_witness_option_identity_sha256s
571
+ )
572
+ record["feasibility_witness_semantics"] = (
573
+ "current_finite_contract_exact_joint_count_and_structural_witness"
574
+ )
575
+ return record
576
+
577
+ def to_record(self) -> dict[str, object]:
578
+ self.__post_init__()
579
+ return {**self._unsigned_record(), "contract_sha256": self.contract_sha256}
580
+
581
+ def target_count(self, *, kind: str, arm_id: str) -> int:
582
+ if kind not in {"source", "operator"}:
583
+ raise ValueError("kind must be source or operator")
584
+ _require_token(arm_id, name="arm_id")
585
+ values = (
586
+ self.source_target_counts
587
+ if kind == "source"
588
+ else self.operator_target_counts
589
+ )
590
+ try:
591
+ return dict(values)[arm_id]
592
+ except KeyError as error:
593
+ raise ValueError("arm is absent from this allocation contract") from error
594
+
595
+
596
+ @dataclass(frozen=True, slots=True)
597
+ class ContextualPortfolioAllocationRealization:
598
+ """Objective-blind requested-to-realized exposure evidence.
599
+
600
+ This is an inward-facing application port: an integration may solve a
601
+ workload-specific finite feasibility problem, but the controller receives
602
+ only canonical arm counts and the identity of the prospective contract.
603
+ Candidate fields, objective values, workload IDs, model IDs, and provider
604
+ metadata are deliberately absent.
605
+ """
606
+
607
+ campaign_scope_sha256: str
608
+ query_sha256: str
609
+ decision_sha256: str
610
+ contract_sha256: str
611
+ controller_wave_index: int
612
+ slice_id: str
613
+ requested_source_target_counts: tuple[tuple[str, int], ...]
614
+ requested_operator_target_counts: tuple[tuple[str, int], ...]
615
+ realized_source_target_counts: tuple[tuple[str, int], ...]
616
+ realized_operator_target_counts: tuple[tuple[str, int], ...]
617
+ requested_minimum_single_path_interventions: int = 0
618
+ realized_single_path_interventions: int = 0
619
+ requested_minimum_disjoint_parent_patch_pairs: int = 0
620
+ realized_disjoint_parent_patch_pairs: int = 0
621
+ realization_sha256: str = field(init=False)
622
+
623
+ def __post_init__(self) -> None:
624
+ for name in (
625
+ "campaign_scope_sha256",
626
+ "query_sha256",
627
+ "decision_sha256",
628
+ "contract_sha256",
629
+ ):
630
+ require_sha256(getattr(self, name), name)
631
+ if (
632
+ type(self.controller_wave_index) is not int
633
+ or self.controller_wave_index <= 0
634
+ ):
635
+ raise ValueError("controller_wave_index must be positive")
636
+ _require_token(self.slice_id, name="slice_id")
637
+ slots = sum(value[1] for value in self.requested_source_target_counts)
638
+ if slots <= 0:
639
+ raise ValueError("allocation realization must cover positive capacity")
640
+ for name in (
641
+ "requested_source_target_counts",
642
+ "requested_operator_target_counts",
643
+ "realized_source_target_counts",
644
+ "realized_operator_target_counts",
645
+ ):
646
+ _validate_counts(
647
+ getattr(self, name),
648
+ name=name,
649
+ expected_slots=slots,
650
+ )
651
+ if tuple(value[0] for value in self.requested_source_target_counts) != tuple(
652
+ value[0] for value in self.realized_source_target_counts
653
+ ):
654
+ raise ValueError("realized source arms differ from requested arms")
655
+ if tuple(value[0] for value in self.requested_operator_target_counts) != tuple(
656
+ value[0] for value in self.realized_operator_target_counts
657
+ ):
658
+ raise ValueError("realized operator arms differ from requested arms")
659
+ if (
660
+ type(self.requested_minimum_single_path_interventions) is not int
661
+ or not 0
662
+ <= self.requested_minimum_single_path_interventions
663
+ <= slots
664
+ ):
665
+ raise ValueError(
666
+ "requested minimum single-path interventions is invalid"
667
+ )
668
+ if (
669
+ type(self.realized_single_path_interventions) is not int
670
+ or not 0 <= self.realized_single_path_interventions <= slots
671
+ ):
672
+ raise ValueError("realized single-path interventions is invalid")
673
+ if self.realized_single_path_interventions < (
674
+ self.requested_minimum_single_path_interventions
675
+ ):
676
+ raise ValueError("realized portfolio violated its single-path floor")
677
+ maximum_pairs = slots * (slots - 1) // 2
678
+ if (
679
+ type(self.requested_minimum_disjoint_parent_patch_pairs) is not int
680
+ or not 0
681
+ <= self.requested_minimum_disjoint_parent_patch_pairs
682
+ <= maximum_pairs
683
+ ):
684
+ raise ValueError(
685
+ "requested minimum disjoint parent-patch pairs is invalid"
686
+ )
687
+ if (
688
+ type(self.realized_disjoint_parent_patch_pairs) is not int
689
+ or not 0 <= self.realized_disjoint_parent_patch_pairs <= maximum_pairs
690
+ ):
691
+ raise ValueError("realized disjoint parent-patch pair count is invalid")
692
+ if self.realized_disjoint_parent_patch_pairs < (
693
+ self.requested_minimum_disjoint_parent_patch_pairs
694
+ ):
695
+ raise ValueError(
696
+ "realized portfolio violated its disjoint parent-pair floor"
697
+ )
698
+ object.__setattr__(
699
+ self,
700
+ "realization_sha256",
701
+ hashlib.sha256(
702
+ _REALIZATION_DOMAIN + _canonical_json(self._unsigned_record())
703
+ ).hexdigest(),
704
+ )
705
+
706
+ @staticmethod
707
+ def _l1(
708
+ requested: tuple[tuple[str, int], ...],
709
+ realized: tuple[tuple[str, int], ...],
710
+ ) -> int:
711
+ return sum(
712
+ abs(left[1] - right[1])
713
+ for left, right in zip(requested, realized, strict=True)
714
+ )
715
+
716
+ @property
717
+ def source_l1_deviation(self) -> int:
718
+ return self._l1(
719
+ self.requested_source_target_counts,
720
+ self.realized_source_target_counts,
721
+ )
722
+
723
+ @property
724
+ def operator_l1_deviation(self) -> int:
725
+ return self._l1(
726
+ self.requested_operator_target_counts,
727
+ self.realized_operator_target_counts,
728
+ )
729
+
730
+ @property
731
+ def exact(self) -> bool:
732
+ return self.source_l1_deviation == 0 and self.operator_l1_deviation == 0
733
+
734
+ def _unsigned_record(self) -> dict[str, object]:
735
+ intervention_bound = self.requested_minimum_single_path_interventions > 0
736
+ offspring_opportunity_bound = (
737
+ self.requested_minimum_disjoint_parent_patch_pairs > 0
738
+ )
739
+ record: dict[str, object] = {
740
+ "schema_version": (
741
+ 3 if offspring_opportunity_bound else 2 if intervention_bound else 1
742
+ ),
743
+ "campaign_scope_sha256": self.campaign_scope_sha256,
744
+ "query_sha256": self.query_sha256,
745
+ "decision_sha256": self.decision_sha256,
746
+ "contract_sha256": self.contract_sha256,
747
+ "controller_wave_index": self.controller_wave_index,
748
+ "slice_id": self.slice_id,
749
+ "requested_source_target_counts": [
750
+ list(value) for value in self.requested_source_target_counts
751
+ ],
752
+ "requested_operator_target_counts": [
753
+ list(value) for value in self.requested_operator_target_counts
754
+ ],
755
+ "realized_source_target_counts": [
756
+ list(value) for value in self.realized_source_target_counts
757
+ ],
758
+ "realized_operator_target_counts": [
759
+ list(value) for value in self.realized_operator_target_counts
760
+ ],
761
+ "source_l1_deviation": self.source_l1_deviation,
762
+ "operator_l1_deviation": self.operator_l1_deviation,
763
+ "exact": self.exact,
764
+ "objective_values_consulted": False,
765
+ "workload_identifiers_consulted": False,
766
+ }
767
+ if intervention_bound:
768
+ record["requested_minimum_single_path_interventions"] = (
769
+ self.requested_minimum_single_path_interventions
770
+ )
771
+ record["realized_single_path_interventions"] = (
772
+ self.realized_single_path_interventions
773
+ )
774
+ record["intervention_axis"] = (
775
+ "exact_parent_relative_changed_json_path_count"
776
+ )
777
+ if offspring_opportunity_bound:
778
+ record["requested_minimum_disjoint_parent_patch_pairs"] = (
779
+ self.requested_minimum_disjoint_parent_patch_pairs
780
+ )
781
+ record["realized_disjoint_parent_patch_pairs"] = (
782
+ self.realized_disjoint_parent_patch_pairs
783
+ )
784
+ record["offspring_opportunity_axis"] = (
785
+ "pairwise_disjoint_parent_relative_patch_pairs"
786
+ )
787
+ return record
788
+
789
+ def to_record(self) -> dict[str, object]:
790
+ self.__post_init__()
791
+ return {
792
+ **self._unsigned_record(),
793
+ "realization_sha256": self.realization_sha256,
794
+ }
795
+
796
+ def require_contract(
797
+ self,
798
+ contract: ContextualPortfolioAllocationContract,
799
+ ) -> None:
800
+ if type(contract) is not ContextualPortfolioAllocationContract:
801
+ raise TypeError("contract must be exact")
802
+ contract.__post_init__()
803
+ if (
804
+ self.campaign_scope_sha256 != contract.campaign_scope_sha256
805
+ or self.query_sha256 != contract.query_sha256
806
+ or self.decision_sha256 != contract.decision_sha256
807
+ or self.contract_sha256 != contract.contract_sha256
808
+ or self.controller_wave_index != contract.controller_wave_index
809
+ or self.slice_id != contract.slice_id
810
+ or self.requested_source_target_counts != contract.source_target_counts
811
+ or self.requested_operator_target_counts != contract.operator_target_counts
812
+ or self.requested_minimum_single_path_interventions
813
+ != contract.minimum_single_path_interventions
814
+ or self.requested_minimum_disjoint_parent_patch_pairs
815
+ != contract.minimum_disjoint_parent_patch_pairs
816
+ ):
817
+ raise ValueError("allocation realization differs from its contract")
818
+
819
+
820
+ __all__ = [
821
+ "ContextualArmCountCapability",
822
+ "ContextualArmCountCapabilityWitness",
823
+ "ContextualJointCountVector",
824
+ "ContextualLaneJointCountCapability",
825
+ "ContextualPortfolioAllocationContract",
826
+ "ContextualPortfolioAllocationRealization",
827
+ ]