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,814 @@
1
+ """Workload-neutral projection of evaluated portfolio actions into evidence.
2
+
3
+ This module performs the structural join shared by every finite-action
4
+ benchmark: an exact parent, ranked option, engine materialization, successful
5
+ child, and objective transition become one authenticated hypothesis
6
+ observation. Candidate-attributable infeasibility instead becomes an explicit
7
+ no-resampling exclusion receipt. Benchmark-specific interpretation is
8
+ inverted behind two small
9
+ ports: metric-effect projection and action-semantics compilation.
10
+
11
+ Randomized insight exposure is intentionally not relabelled as randomized
12
+ action administration. These observations audit whether a semantic claim is
13
+ consistent with evaluated actions; causal credit for a card remains the
14
+ whole-wave memory treatment maintained elsewhere.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import hashlib
20
+ import json
21
+ import math
22
+ import re
23
+ from dataclasses import dataclass, field
24
+ from enum import Enum
25
+ from typing import Protocol, runtime_checkable
26
+
27
+ from agent_evolve.application.agentic_evolution import (
28
+ EvolutionCandidate,
29
+ InvocationOutcome,
30
+ OperatorKind,
31
+ )
32
+ from agent_evolve.application.portfolio_evolution import (
33
+ PortfolioCandidateFailureEvidence,
34
+ PortfolioMemberDisposition,
35
+ PortfolioVariationMemberReceipt,
36
+ PortfolioVariationWaveRequest,
37
+ PortfolioVariationWaveResult,
38
+ )
39
+ from agent_evolve.domain.patch import require_sha256
40
+ from agent_evolve.domain.typed_json import (
41
+ FrozenJsonObject,
42
+ freeze_json,
43
+ thaw_json,
44
+ )
45
+ from agent_evolve.policies.memory.global_falsification import (
46
+ AuthenticatedHypothesisObservation,
47
+ CausalEstimandUnit,
48
+ EvidenceCausalBoundary,
49
+ EvidenceProvenance,
50
+ InterventionIdentifiability,
51
+ ObservedMetricEffect,
52
+ )
53
+ from agent_evolve.ports.agentic_generator import MetricEffectDirection
54
+
55
+
56
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
57
+ _PARENT_OUTCOME_DOMAIN = b"agent-evolve:campaign-parent-outcome:v1\x00"
58
+ _SEMANTICS_DOMAIN = b"agent-evolve:campaign-observed-action-semantics:v1\x00"
59
+ _LINEAGE_DOMAIN = b"agent-evolve:campaign-observation-lineage:v1\x00"
60
+ _BLOCK_DOMAIN = b"agent-evolve:campaign-observation-block:v1\x00"
61
+ _EXCLUSION_DOMAIN = b"agent-evolve:campaign-observation-exclusion:v1\x00"
62
+ _PROJECTION_DOMAIN = b"agent-evolve:campaign-observation-projection:v1\x00"
63
+
64
+
65
+ def _canonical_json(value: object) -> bytes:
66
+ return json.dumps(
67
+ value,
68
+ allow_nan=False,
69
+ ensure_ascii=True,
70
+ separators=(",", ":"),
71
+ sort_keys=True,
72
+ ).encode("ascii", errors="strict")
73
+
74
+
75
+ def _hash(domain: bytes, value: object) -> str:
76
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
77
+
78
+
79
+ def _object(value: dict[str, object]) -> FrozenJsonObject:
80
+ frozen = freeze_json(value)
81
+ if type(frozen) is not FrozenJsonObject: # pragma: no cover - closed root.
82
+ raise AssertionError("campaign action semantics did not freeze to an object")
83
+ return frozen
84
+
85
+
86
+ def _require_token(value: str, *, name: str) -> None:
87
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
88
+ raise ValueError(f"{name} must use the closed token grammar")
89
+
90
+
91
+ def campaign_candidate_outcome_sha256(candidate: EvolutionCandidate) -> str:
92
+ """Stable evidence identity for a parent candidate's evaluated state."""
93
+
94
+ if type(candidate) is not EvolutionCandidate:
95
+ raise TypeError("candidate must be exact")
96
+ EvolutionCandidate.__post_init__(candidate)
97
+ return _hash(
98
+ _PARENT_OUTCOME_DOMAIN,
99
+ {
100
+ "candidate_id": candidate.candidate_id.value,
101
+ "configuration_sha256": candidate.occurrence.configuration_hash,
102
+ "objectives": [
103
+ [metric_id, value.hex()] for metric_id, value in candidate.objectives
104
+ ],
105
+ "valid": candidate.valid,
106
+ "detailed_evaluation_sha256": (
107
+ None
108
+ if candidate.detailed_evaluation is None
109
+ else candidate.detailed_evaluation.evidence_sha256
110
+ ),
111
+ "objective_resolution_receipt_sha256": (
112
+ None
113
+ if candidate.objective_resolution_receipt is None
114
+ else candidate.objective_resolution_receipt.receipt_sha256
115
+ ),
116
+ },
117
+ )
118
+
119
+
120
+ @dataclass(frozen=True, slots=True)
121
+ class CampaignEvaluatedActionContext:
122
+ """Exact finite-action facts offered to a semantic compiler."""
123
+
124
+ option_id: str
125
+ option_identity_sha256: str
126
+ option_family: str
127
+ operator_family: str
128
+ changed_paths: tuple[str, ...]
129
+ parent_configuration: FrozenJsonObject
130
+ child_configuration: FrozenJsonObject
131
+ materialization_receipt_sha256: str
132
+ outcome_sha256: str
133
+ finite_contract_identity_sha256: str
134
+
135
+ def __post_init__(self) -> None:
136
+ for name in ("option_id", "option_family", "operator_family"):
137
+ _require_token(getattr(self, name), name=name)
138
+ for name in (
139
+ "option_identity_sha256",
140
+ "materialization_receipt_sha256",
141
+ "outcome_sha256",
142
+ "finite_contract_identity_sha256",
143
+ ):
144
+ require_sha256(getattr(self, name), name)
145
+ if (
146
+ type(self.changed_paths) is not tuple
147
+ or not self.changed_paths
148
+ or any(
149
+ type(value) is not str or not value.startswith("$.")
150
+ for value in self.changed_paths
151
+ )
152
+ or self.changed_paths != tuple(sorted(set(self.changed_paths)))
153
+ ):
154
+ raise ValueError("changed_paths must be a canonical non-empty tuple")
155
+ for name in ("parent_configuration", "child_configuration"):
156
+ value = getattr(self, name)
157
+ if type(value) is not FrozenJsonObject or freeze_json(value) is not value:
158
+ raise TypeError(f"{name} must be an exact frozen object")
159
+
160
+
161
+ @dataclass(frozen=True, slots=True)
162
+ class CampaignObservedActionSemantics:
163
+ """Compiler-issued interpretation bound into an observation payload."""
164
+
165
+ observed_action: FrozenJsonObject
166
+ intervention_identifiability: InterventionIdentifiability
167
+ mechanism_identifying_design: bool
168
+ compiler_id: str
169
+ compiler_version: int
170
+ compiler_definition_sha256: str
171
+ semantics_sha256: str = field(init=False)
172
+
173
+ def __post_init__(self) -> None:
174
+ if (
175
+ type(self.observed_action) is not FrozenJsonObject
176
+ or freeze_json(self.observed_action) is not self.observed_action
177
+ ):
178
+ raise TypeError("observed_action must be an exact frozen object")
179
+ if type(self.intervention_identifiability) is not InterventionIdentifiability:
180
+ raise TypeError("intervention_identifiability must be exact")
181
+ if type(self.mechanism_identifying_design) is not bool:
182
+ raise TypeError("mechanism_identifying_design must be exact bool")
183
+ _require_token(self.compiler_id, name="compiler_id")
184
+ if type(self.compiler_version) is not int or self.compiler_version <= 0:
185
+ raise ValueError("compiler_version must be positive")
186
+ require_sha256(
187
+ self.compiler_definition_sha256,
188
+ "compiler_definition_sha256",
189
+ )
190
+ object.__setattr__(
191
+ self,
192
+ "semantics_sha256",
193
+ _hash(
194
+ _SEMANTICS_DOMAIN,
195
+ {
196
+ "schema_version": 1,
197
+ "observed_action": thaw_json(self.observed_action),
198
+ "intervention_identifiability": (
199
+ self.intervention_identifiability.value
200
+ ),
201
+ "mechanism_identifying_design": (self.mechanism_identifying_design),
202
+ "compiler": {
203
+ "compiler_id": self.compiler_id,
204
+ "compiler_version": self.compiler_version,
205
+ "definition_sha256": self.compiler_definition_sha256,
206
+ },
207
+ },
208
+ ),
209
+ )
210
+
211
+
212
+ @runtime_checkable
213
+ class CampaignActionSemanticsCompiler(Protocol):
214
+ compiler_id: str
215
+ compiler_version: int
216
+ definition_sha256: str
217
+
218
+ def compile(
219
+ self,
220
+ context: CampaignEvaluatedActionContext,
221
+ ) -> CampaignObservedActionSemantics: ...
222
+
223
+
224
+ @runtime_checkable
225
+ class CampaignMetricEffectProjector(Protocol):
226
+ projector_id: str
227
+ projector_version: int
228
+ definition_sha256: str
229
+
230
+ def project(
231
+ self,
232
+ parent: EvolutionCandidate,
233
+ child: EvolutionCandidate,
234
+ ) -> tuple[ObservedMetricEffect, ...]: ...
235
+
236
+
237
+ @dataclass(frozen=True, slots=True)
238
+ class FinitePortfolioActionSemanticsCompiler:
239
+ """Default structural semantics for one engine-materialized finite option."""
240
+
241
+ compiler_id: str = "finite_portfolio_action_semantics"
242
+ compiler_version: int = 3
243
+ definition_sha256: str = hashlib.sha256(
244
+ b"agent-evolve:finite-portfolio-action-semantics:v3;"
245
+ b"exact-finite-contract-identity;intervention-arity-from-changed-paths"
246
+ ).hexdigest()
247
+
248
+ def compile(
249
+ self,
250
+ context: CampaignEvaluatedActionContext,
251
+ ) -> CampaignObservedActionSemantics:
252
+ if type(context) is not CampaignEvaluatedActionContext:
253
+ raise TypeError("context must be exact")
254
+ CampaignEvaluatedActionContext.__post_init__(context)
255
+ action = _object(
256
+ {
257
+ "schema_version": 2,
258
+ "option_id": context.option_id,
259
+ "option_identity_sha256": context.option_identity_sha256,
260
+ "option_family": context.option_family,
261
+ "operator_family": context.operator_family,
262
+ "changed_paths": list(context.changed_paths),
263
+ "materialization_receipt_sha256": (
264
+ context.materialization_receipt_sha256
265
+ ),
266
+ "outcome_sha256": context.outcome_sha256,
267
+ "finite_contract_identity_sha256": (
268
+ context.finite_contract_identity_sha256
269
+ ),
270
+ "compiler": {
271
+ "compiler_id": self.compiler_id,
272
+ "compiler_version": self.compiler_version,
273
+ "definition_sha256": self.definition_sha256,
274
+ },
275
+ }
276
+ )
277
+ return CampaignObservedActionSemantics(
278
+ observed_action=action,
279
+ intervention_identifiability=(
280
+ InterventionIdentifiability.EXACT_SINGLE
281
+ if len(context.changed_paths) == 1
282
+ else InterventionIdentifiability.JOINT_WITHOUT_ABLATION
283
+ ),
284
+ mechanism_identifying_design=False,
285
+ compiler_id=self.compiler_id,
286
+ compiler_version=self.compiler_version,
287
+ compiler_definition_sha256=self.definition_sha256,
288
+ )
289
+
290
+
291
+ @dataclass(frozen=True, slots=True)
292
+ class ObjectiveDeltaMetricEffectProjector:
293
+ """Project exact raw child-minus-parent objective transitions."""
294
+
295
+ adjudicator_definition_sha256: str
296
+ projector_id: str = "objective_delta_metric_effects"
297
+ projector_version: int = 1
298
+ definition_sha256: str = hashlib.sha256(
299
+ b"agent-evolve:objective-delta-metric-effects:v1"
300
+ ).hexdigest()
301
+
302
+ def __post_init__(self) -> None:
303
+ require_sha256(
304
+ self.adjudicator_definition_sha256,
305
+ "adjudicator_definition_sha256",
306
+ )
307
+
308
+ def project(
309
+ self,
310
+ parent: EvolutionCandidate,
311
+ child: EvolutionCandidate,
312
+ ) -> tuple[ObservedMetricEffect, ...]:
313
+ self.__post_init__()
314
+ for name, value in (("parent", parent), ("child", child)):
315
+ if type(value) is not EvolutionCandidate:
316
+ raise TypeError(f"{name} must be exact")
317
+ EvolutionCandidate.__post_init__(value)
318
+ parent_metrics = parent.objective_map
319
+ child_metrics = child.objective_map
320
+ if set(parent_metrics) != set(child_metrics):
321
+ raise ValueError("parent and child objective sets differ")
322
+ effects = []
323
+ for metric_id in sorted(parent_metrics):
324
+ delta = float(child_metrics[metric_id] - parent_metrics[metric_id])
325
+ if not math.isfinite(delta):
326
+ raise ValueError("objective delta must be finite")
327
+ direction = (
328
+ MetricEffectDirection.INCREASE
329
+ if delta > 0.0
330
+ else (
331
+ MetricEffectDirection.DECREASE
332
+ if delta < 0.0
333
+ else MetricEffectDirection.UNCHANGED
334
+ )
335
+ )
336
+ effects.append(
337
+ ObservedMetricEffect(
338
+ metric_id=metric_id,
339
+ direction=direction,
340
+ delta=delta,
341
+ adjudicator_definition_sha256=(self.adjudicator_definition_sha256),
342
+ )
343
+ )
344
+ return tuple(effects)
345
+
346
+
347
+ def _action_context(
348
+ *,
349
+ wave: PortfolioVariationWaveRequest,
350
+ result: PortfolioVariationWaveResult,
351
+ member: PortfolioVariationMemberReceipt,
352
+ outcome: InvocationOutcome,
353
+ rank_index: int,
354
+ ) -> CampaignEvaluatedActionContext:
355
+ decision = result.selection_decision
356
+ if decision is None:
357
+ raise ValueError("hypothesis evidence requires a typed ranked decision")
358
+ selected = decision.members[rank_index]
359
+ materialization = member.materialization
360
+ child = outcome.candidate
361
+ if child is None: # Closed by PortfolioVariationWaveResult validation.
362
+ raise AssertionError("validated portfolio result lost its child")
363
+ parent_configuration = wave.parent.configuration
364
+ child_configuration = child.configuration
365
+ if type(parent_configuration) is not FrozenJsonObject:
366
+ raise TypeError("portfolio parent configuration must be an object")
367
+ if type(child_configuration) is not FrozenJsonObject:
368
+ raise TypeError("portfolio child configuration must be an object")
369
+ operator = outcome.prepared.plan.operator_kind
370
+ if operator is not OperatorKind.TYPED_MUTATION:
371
+ raise ValueError("portfolio action evidence requires typed mutation")
372
+ return CampaignEvaluatedActionContext(
373
+ option_id=selected.option_id,
374
+ option_identity_sha256=selected.option_identity_sha256,
375
+ option_family=selected.family,
376
+ operator_family=operator.value,
377
+ changed_paths=materialization.changed_paths,
378
+ parent_configuration=parent_configuration,
379
+ child_configuration=child_configuration,
380
+ materialization_receipt_sha256=materialization.receipt_sha256,
381
+ outcome_sha256=member.outcome_sha256,
382
+ finite_contract_identity_sha256=(
383
+ wave.selection_request.finite_variation_contract.identity_sha256
384
+ ),
385
+ )
386
+
387
+
388
+ class CampaignHypothesisObservationExclusionReason(str, Enum):
389
+ """Closed reason a ranked action cannot become metric-effect evidence."""
390
+
391
+ CANDIDATE_INFEASIBLE = "candidate_infeasible"
392
+
393
+
394
+ @dataclass(frozen=True, slots=True)
395
+ class CampaignHypothesisObservationExclusion:
396
+ """Authenticated ITT action excluded from semantic metric adjudication."""
397
+
398
+ source_evidence_id: str
399
+ wave_receipt_sha256: str
400
+ request_sha256: str
401
+ rank: int
402
+ parent_candidate_id: str
403
+ candidate_id: str
404
+ candidate_configuration_sha256: str
405
+ option_id: str
406
+ option_identity_sha256: str
407
+ candidate_failure: PortfolioCandidateFailureEvidence
408
+ reason: CampaignHypothesisObservationExclusionReason = (
409
+ CampaignHypothesisObservationExclusionReason.CANDIDATE_INFEASIBLE
410
+ )
411
+ exclusion_sha256: str = field(init=False)
412
+
413
+ def __post_init__(self) -> None:
414
+ for name in (
415
+ "source_evidence_id",
416
+ "wave_receipt_sha256",
417
+ "request_sha256",
418
+ "candidate_configuration_sha256",
419
+ "option_identity_sha256",
420
+ ):
421
+ require_sha256(getattr(self, name), name)
422
+ if type(self.rank) is not int or self.rank <= 0:
423
+ raise ValueError("rank must be a positive exact integer")
424
+ for name in ("parent_candidate_id", "candidate_id", "option_id"):
425
+ _require_token(getattr(self, name), name=name)
426
+ if self.parent_candidate_id == self.candidate_id:
427
+ raise ValueError("excluded child cannot reuse its parent occurrence")
428
+ if type(self.candidate_failure) is not PortfolioCandidateFailureEvidence:
429
+ raise TypeError("candidate_failure must be exact")
430
+ PortfolioCandidateFailureEvidence.__post_init__(self.candidate_failure)
431
+ if type(self.reason) is not CampaignHypothesisObservationExclusionReason:
432
+ raise TypeError("reason must be exact")
433
+ object.__setattr__(
434
+ self,
435
+ "exclusion_sha256",
436
+ _hash(_EXCLUSION_DOMAIN, self._unsigned_record()),
437
+ )
438
+
439
+ def _unsigned_record(self) -> dict[str, object]:
440
+ return {
441
+ "schema_version": 1,
442
+ "source_evidence_id": self.source_evidence_id,
443
+ "wave_receipt_sha256": self.wave_receipt_sha256,
444
+ "request_sha256": self.request_sha256,
445
+ "rank": self.rank,
446
+ "parent_candidate_id": self.parent_candidate_id,
447
+ "candidate_id": self.candidate_id,
448
+ "candidate_configuration_sha256": self.candidate_configuration_sha256,
449
+ "option_id": self.option_id,
450
+ "option_identity_sha256": self.option_identity_sha256,
451
+ "reason": self.reason.value,
452
+ "candidate_failure": self.candidate_failure.to_record(),
453
+ "metric_projection_executed": False,
454
+ "semantics_compiler_executed": False,
455
+ "resampled": False,
456
+ }
457
+
458
+ def to_record(self) -> dict[str, object]:
459
+ self.__post_init__()
460
+ return {
461
+ **self._unsigned_record(),
462
+ "exclusion_sha256": self.exclusion_sha256,
463
+ }
464
+
465
+
466
+ @dataclass(frozen=True, slots=True)
467
+ class CampaignPortfolioHypothesisEvidenceProjection:
468
+ """Complete scored/excluded partition of all ranked ITT action members."""
469
+
470
+ wave_receipt_sha256s: tuple[str, ...]
471
+ ranked_source_evidence_ids: tuple[str, ...]
472
+ observations: tuple[AuthenticatedHypothesisObservation, ...]
473
+ exclusions: tuple[CampaignHypothesisObservationExclusion, ...]
474
+ projection_sha256: str = field(init=False)
475
+
476
+ def __post_init__(self) -> None:
477
+ if type(self.wave_receipt_sha256s) is not tuple or not self.wave_receipt_sha256s:
478
+ raise ValueError("wave_receipt_sha256s must be a non-empty exact tuple")
479
+ for value in self.wave_receipt_sha256s:
480
+ require_sha256(value, "wave_receipt_sha256s")
481
+ if self.wave_receipt_sha256s != tuple(
482
+ sorted(set(self.wave_receipt_sha256s))
483
+ ):
484
+ raise ValueError("wave receipt identities must be canonical and unique")
485
+ if (
486
+ type(self.ranked_source_evidence_ids) is not tuple
487
+ or not self.ranked_source_evidence_ids
488
+ ):
489
+ raise ValueError("ranked source evidence IDs must be non-empty")
490
+ for value in self.ranked_source_evidence_ids:
491
+ require_sha256(value, "ranked_source_evidence_ids")
492
+ if len(set(self.ranked_source_evidence_ids)) != len(
493
+ self.ranked_source_evidence_ids
494
+ ):
495
+ raise ValueError("ranked source evidence IDs must be unique")
496
+ if type(self.observations) is not tuple or any(
497
+ type(value) is not AuthenticatedHypothesisObservation
498
+ for value in self.observations
499
+ ):
500
+ raise TypeError("observations must contain exact authenticated evidence")
501
+ for value in self.observations:
502
+ AuthenticatedHypothesisObservation.__post_init__(value)
503
+ observation_ids = tuple(
504
+ value.source_evidence_id for value in self.observations
505
+ )
506
+ if observation_ids != tuple(sorted(set(observation_ids))):
507
+ raise ValueError("observations must use canonical unique source evidence")
508
+ if type(self.exclusions) is not tuple or any(
509
+ type(value) is not CampaignHypothesisObservationExclusion
510
+ for value in self.exclusions
511
+ ):
512
+ raise TypeError("exclusions must contain exact receipts")
513
+ for value in self.exclusions:
514
+ CampaignHypothesisObservationExclusion.__post_init__(value)
515
+ exclusion_ids = tuple(value.source_evidence_id for value in self.exclusions)
516
+ if exclusion_ids != tuple(sorted(set(exclusion_ids))):
517
+ raise ValueError("exclusions must use canonical unique source evidence")
518
+ if set(observation_ids).intersection(exclusion_ids) or set(
519
+ self.ranked_source_evidence_ids
520
+ ) != set((*observation_ids, *exclusion_ids)):
521
+ raise ValueError(
522
+ "observations and exclusions must exactly partition ranked ITT members"
523
+ )
524
+ if any(
525
+ value.wave_receipt_sha256 not in self.wave_receipt_sha256s
526
+ for value in self.exclusions
527
+ ):
528
+ raise ValueError("exclusion belongs to a foreign wave")
529
+ object.__setattr__(
530
+ self,
531
+ "projection_sha256",
532
+ _hash(_PROJECTION_DOMAIN, self._unsigned_record()),
533
+ )
534
+
535
+ def _unsigned_record(self) -> dict[str, object]:
536
+ return {
537
+ "schema_version": 1,
538
+ "wave_receipt_sha256s": list(self.wave_receipt_sha256s),
539
+ "ranked_source_evidence_ids": list(self.ranked_source_evidence_ids),
540
+ "observation_sha256s": [
541
+ value.observation_sha256 for value in self.observations
542
+ ],
543
+ "exclusion_sha256s": [
544
+ value.exclusion_sha256 for value in self.exclusions
545
+ ],
546
+ "ranked_itt_member_count": len(self.ranked_source_evidence_ids),
547
+ "observation_count": len(self.observations),
548
+ "exclusion_count": len(self.exclusions),
549
+ "resampled_member_count": 0,
550
+ }
551
+
552
+ def to_record(self) -> dict[str, object]:
553
+ self.__post_init__()
554
+ return {
555
+ **self._unsigned_record(),
556
+ "exclusions": [value.to_record() for value in self.exclusions],
557
+ "projection_sha256": self.projection_sha256,
558
+ }
559
+
560
+
561
+ def project_portfolio_hypothesis_evidence(
562
+ *,
563
+ campaign_sha256: str,
564
+ event_index: int,
565
+ workload_instance_sha256: str,
566
+ evaluator_contract_sha256: str,
567
+ waves: tuple[PortfolioVariationWaveRequest, ...],
568
+ results: tuple[PortfolioVariationWaveResult, ...],
569
+ metric_projector: CampaignMetricEffectProjector,
570
+ semantics_compiler: CampaignActionSemanticsCompiler,
571
+ ) -> CampaignPortfolioHypothesisEvidenceProjection:
572
+ """Partition every ranked finite action into evidence or typed exclusion."""
573
+
574
+ for name in (
575
+ "campaign_sha256",
576
+ "workload_instance_sha256",
577
+ "evaluator_contract_sha256",
578
+ ):
579
+ require_sha256(locals()[name], name)
580
+ if type(event_index) is not int or event_index <= 0:
581
+ raise ValueError("event_index must be positive")
582
+ if (
583
+ type(waves) is not tuple
584
+ or type(results) is not tuple
585
+ or not waves
586
+ or len(waves) != len(results)
587
+ ):
588
+ raise ValueError("waves/results must be equal non-empty tuples")
589
+ if not isinstance(metric_projector, CampaignMetricEffectProjector):
590
+ raise TypeError("metric_projector must implement its port")
591
+ if not isinstance(semantics_compiler, CampaignActionSemanticsCompiler):
592
+ raise TypeError("semantics_compiler must implement its port")
593
+ observations: list[AuthenticatedHypothesisObservation] = []
594
+ exclusions: list[CampaignHypothesisObservationExclusion] = []
595
+ ranked_source_evidence_ids: list[str] = []
596
+ wave_receipt_sha256s: list[str] = []
597
+ for wave, result in zip(waves, results, strict=True):
598
+ if type(wave) is not PortfolioVariationWaveRequest:
599
+ raise TypeError("waves must contain exact requests")
600
+ if type(result) is not PortfolioVariationWaveResult:
601
+ raise TypeError("results must contain exact results")
602
+ PortfolioVariationWaveRequest.__post_init__(wave)
603
+ PortfolioVariationWaveResult.__post_init__(result)
604
+ if result.receipt.request_sha256 != wave.selection_request.request_sha256:
605
+ raise ValueError("portfolio result belongs to a foreign wave")
606
+ wave_receipt_sha256s.append(result.receipt.receipt_sha256)
607
+ decision = result.selection_decision
608
+ if decision is None:
609
+ raise ValueError("portfolio result omitted its ranked decision")
610
+ for rank_index, (member, outcome) in enumerate(
611
+ zip(result.receipt.members, result.outcomes, strict=True)
612
+ ):
613
+ ranked_source_evidence_ids.append(member.outcome_sha256)
614
+ child = outcome.candidate
615
+ if child is None: # Closed by exact result validation.
616
+ raise AssertionError("validated result lost a child")
617
+ if member.disposition is PortfolioMemberDisposition.CANDIDATE_INFEASIBLE:
618
+ failure = member.candidate_failure
619
+ if type(failure) is not PortfolioCandidateFailureEvidence:
620
+ raise AssertionError(
621
+ "validated infeasible member lost candidate failure evidence"
622
+ )
623
+ selected = decision.members[rank_index]
624
+ materialization = member.materialization
625
+ exclusions.append(
626
+ CampaignHypothesisObservationExclusion(
627
+ source_evidence_id=member.outcome_sha256,
628
+ wave_receipt_sha256=result.receipt.receipt_sha256,
629
+ request_sha256=wave.selection_request.request_sha256,
630
+ rank=materialization.rank,
631
+ parent_candidate_id=wave.parent.candidate_id.value,
632
+ candidate_id=child.candidate_id.value,
633
+ candidate_configuration_sha256=(
634
+ child.occurrence.configuration_hash
635
+ ),
636
+ option_id=selected.option_id,
637
+ option_identity_sha256=selected.option_identity_sha256,
638
+ candidate_failure=failure,
639
+ )
640
+ )
641
+ continue
642
+ context = _action_context(
643
+ wave=wave,
644
+ result=result,
645
+ member=member,
646
+ outcome=outcome,
647
+ rank_index=rank_index,
648
+ )
649
+ semantics = semantics_compiler.compile(context)
650
+ if type(semantics) is not CampaignObservedActionSemantics:
651
+ raise TypeError("semantics compiler returned a foreign value")
652
+ CampaignObservedActionSemantics.__post_init__(semantics)
653
+ expected_compiler = (
654
+ semantics_compiler.compiler_id,
655
+ semantics_compiler.compiler_version,
656
+ semantics_compiler.definition_sha256,
657
+ )
658
+ observed_compiler = (
659
+ semantics.compiler_id,
660
+ semantics.compiler_version,
661
+ semantics.compiler_definition_sha256,
662
+ )
663
+ if observed_compiler != expected_compiler:
664
+ raise ValueError("action semantics compiler identity changed")
665
+ metrics = metric_projector.project(wave.parent, child)
666
+ if (
667
+ type(metrics) is not tuple
668
+ or not metrics
669
+ or any(type(value) is not ObservedMetricEffect for value in metrics)
670
+ ):
671
+ raise TypeError("metric projector returned foreign effects")
672
+ for value in metrics:
673
+ ObservedMetricEffect.__post_init__(value)
674
+ parent_configuration = context.parent_configuration
675
+ child_configuration = context.child_configuration
676
+ credit = wave.memory_credit
677
+ block_identity = (
678
+ result.receipt.receipt_sha256
679
+ if credit is None
680
+ else credit.assignment.block_id
681
+ )
682
+ observations.append(
683
+ AuthenticatedHypothesisObservation(
684
+ source_evidence_id=member.outcome_sha256,
685
+ event_index=event_index,
686
+ workload_instance_sha256=workload_instance_sha256,
687
+ evaluator_contract_sha256=evaluator_contract_sha256,
688
+ campaign_sha256=campaign_sha256,
689
+ parent_candidate_id=wave.parent.candidate_id,
690
+ child_candidate_id=child.candidate_id,
691
+ operator_invocation_id=member.operator_invocation_id,
692
+ finite_contract_identity_sha256=(
693
+ context.finite_contract_identity_sha256
694
+ ),
695
+ provenance=EvidenceProvenance.DIRECT_MUTATION,
696
+ causal_boundary=EvidenceCausalBoundary(
697
+ wave_sha256=result.receipt.receipt_sha256,
698
+ estimand_unit=CausalEstimandUnit.WAVE,
699
+ ),
700
+ parent_configuration=parent_configuration,
701
+ child_configuration=child_configuration,
702
+ parent_configuration_sha256=(
703
+ AuthenticatedHypothesisObservation.configuration_sha256(
704
+ parent_configuration
705
+ )
706
+ ),
707
+ child_configuration_sha256=(
708
+ AuthenticatedHypothesisObservation.configuration_sha256(
709
+ child_configuration
710
+ )
711
+ ),
712
+ parent_outcome_sha256=campaign_candidate_outcome_sha256(
713
+ wave.parent
714
+ ),
715
+ child_outcome_sha256=member.outcome_sha256,
716
+ operator_family=context.operator_family,
717
+ affected_paths=context.changed_paths,
718
+ observed_action=semantics.observed_action,
719
+ action_semantics_compiler_id=semantics.compiler_id,
720
+ action_semantics_compiler_version=semantics.compiler_version,
721
+ action_semantics_definition_sha256=(
722
+ semantics.compiler_definition_sha256
723
+ ),
724
+ intervention_identifiability=(
725
+ semantics.intervention_identifiability
726
+ ),
727
+ metrics=metrics,
728
+ lineage_cluster_sha256=_hash(
729
+ _LINEAGE_DOMAIN,
730
+ {
731
+ "campaign_sha256": campaign_sha256,
732
+ "parent_candidate_id": wave.parent.candidate_id.value,
733
+ "parent_ids": [
734
+ value.value for value in wave.parent.parent_ids
735
+ ],
736
+ "common_ancestor_id": (
737
+ None
738
+ if wave.parent.common_ancestor_id is None
739
+ else wave.parent.common_ancestor_id.value
740
+ ),
741
+ },
742
+ ),
743
+ factorial_block_sha256=_hash(
744
+ _BLOCK_DOMAIN,
745
+ {
746
+ "campaign_sha256": campaign_sha256,
747
+ "event_index": event_index,
748
+ "block_identity": block_identity,
749
+ },
750
+ ),
751
+ mechanism_identifying_design=(
752
+ semantics.mechanism_identifying_design
753
+ ),
754
+ )
755
+ )
756
+ canonical = tuple(sorted(observations, key=lambda value: value.source_evidence_id))
757
+ if len({value.source_evidence_id for value in canonical}) != len(canonical):
758
+ raise ValueError("portfolio observations repeat source evidence")
759
+ canonical_exclusions = tuple(
760
+ sorted(exclusions, key=lambda value: value.source_evidence_id)
761
+ )
762
+ return CampaignPortfolioHypothesisEvidenceProjection(
763
+ wave_receipt_sha256s=tuple(sorted(wave_receipt_sha256s)),
764
+ ranked_source_evidence_ids=tuple(ranked_source_evidence_ids),
765
+ observations=canonical,
766
+ exclusions=canonical_exclusions,
767
+ )
768
+
769
+
770
+ def project_portfolio_hypothesis_observations(
771
+ *,
772
+ campaign_sha256: str,
773
+ event_index: int,
774
+ workload_instance_sha256: str,
775
+ evaluator_contract_sha256: str,
776
+ waves: tuple[PortfolioVariationWaveRequest, ...],
777
+ results: tuple[PortfolioVariationWaveResult, ...],
778
+ metric_projector: CampaignMetricEffectProjector,
779
+ semantics_compiler: CampaignActionSemanticsCompiler,
780
+ ) -> tuple[AuthenticatedHypothesisObservation, ...]:
781
+ """Backward-compatible scored-observation projection.
782
+
783
+ Production generation audit uses :func:`project_portfolio_hypothesis_evidence`
784
+ so candidate-infeasible ranked actions also receive explicit exclusion
785
+ receipts. This narrow view remains for callers that consume only semantic
786
+ observations.
787
+ """
788
+
789
+ return project_portfolio_hypothesis_evidence(
790
+ campaign_sha256=campaign_sha256,
791
+ event_index=event_index,
792
+ workload_instance_sha256=workload_instance_sha256,
793
+ evaluator_contract_sha256=evaluator_contract_sha256,
794
+ waves=waves,
795
+ results=results,
796
+ metric_projector=metric_projector,
797
+ semantics_compiler=semantics_compiler,
798
+ ).observations
799
+
800
+
801
+ __all__ = [
802
+ "CampaignActionSemanticsCompiler",
803
+ "CampaignEvaluatedActionContext",
804
+ "CampaignHypothesisObservationExclusion",
805
+ "CampaignHypothesisObservationExclusionReason",
806
+ "CampaignMetricEffectProjector",
807
+ "CampaignObservedActionSemantics",
808
+ "CampaignPortfolioHypothesisEvidenceProjection",
809
+ "FinitePortfolioActionSemanticsCompiler",
810
+ "ObjectiveDeltaMetricEffectProjector",
811
+ "campaign_candidate_outcome_sha256",
812
+ "project_portfolio_hypothesis_evidence",
813
+ "project_portfolio_hypothesis_observations",
814
+ ]