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,930 @@
1
+ """Workload-neutral complete blocks for diagnostic insight exposure.
2
+
3
+ A campaign may admit one or more quarantined cards after reflection, while its
4
+ portfolio stage exposes a fixed number of independently assigned lanes. This
5
+ module fills any unused lanes with preregistered control cards and constructs a
6
+ complete singleton-subset block: each eligible card is shown exactly once and
7
+ withheld from every other lane. Consequently every card has treated and
8
+ control support without depending on provider completion order or outcomes.
9
+
10
+ The caller owns cohort selection, lifecycle admission, stable lane identities,
11
+ and the externally generated permutation rank. The planner owns only the
12
+ portable experimental design.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import hashlib
18
+ import json
19
+ import math
20
+ from dataclasses import dataclass, field
21
+ from enum import Enum
22
+
23
+ from agent_evolve.application.portfolio_memory_dose import (
24
+ PortfolioMemoryDoseCardSemantics,
25
+ derive_portfolio_memory_dose_card_support,
26
+ )
27
+ from agent_evolve.domain.finite_variation import (
28
+ FiniteVariationContract,
29
+ validate_finite_variation_contract,
30
+ )
31
+ from agent_evolve.domain.insight import InsightRef
32
+ from agent_evolve.domain.patch import require_sha256
33
+ from agent_evolve.policies.memory.balanced_subset_blocks import (
34
+ BalancedSubsetBlockPlan,
35
+ BalancedSubsetBlockPlanner,
36
+ StableMemoryAssignmentUnit,
37
+ )
38
+ from agent_evolve.policies.memory.compatibility_matching import (
39
+ CanonicalLaneCardMatchingPlanner,
40
+ LaneCardCompatibility,
41
+ LaneCardMatchingCard,
42
+ LaneCardMatchingInput,
43
+ LaneCardMatchingLane,
44
+ LaneCardMatchingReceipt,
45
+ )
46
+ from agent_evolve.policies.memory.staged_causal import CausalSearchScorePolicy
47
+ from agent_evolve.ports.portfolio_memory_dose import (
48
+ PortfolioMemoryDoseCardSupport,
49
+ )
50
+
51
+
52
+ CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_ID = (
53
+ "campaign_diagnostic_singleton_complete_block"
54
+ )
55
+ CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_VERSION = 1
56
+ CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_DEFINITION_SHA256 = hashlib.sha256(
57
+ b"agent-evolve:campaign-diagnostic-singleton-complete-block:v1:"
58
+ b"active-quarantine-plus-preregistered-controls:one-treatment-per-lane:"
59
+ b"complete-balanced-subset-block:external-permutation-rank"
60
+ ).hexdigest()
61
+
62
+ CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_ID = (
63
+ "campaign_diagnostic_complete_bipartite_support_audit"
64
+ )
65
+ CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_VERSION = 2
66
+ CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_DEFINITION_SHA256 = hashlib.sha256(
67
+ b"agent-evolve:campaign-diagnostic-complete-bipartite-support-audit:v2:"
68
+ b"prospective-positive-lane-card-graph:equal-card-and-lane-cardinality:"
69
+ b"minimum-two-units:every-card-compatible-with-every-lane:"
70
+ b"eligible-for-balanced-randomized-singleton-assignment-or-fail-closed:"
71
+ b"assignment-audit-is-not-a-card-vs-neutral-causal-effect"
72
+ ).hexdigest()
73
+ CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_ID = (
74
+ "campaign_diagnostic_complete_support_cohort_selection"
75
+ )
76
+ CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_VERSION = 1
77
+ CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_DEFINITION_SHA256 = hashlib.sha256(
78
+ b"agent-evolve:campaign-diagnostic-complete-support-cohort-selection:v1:"
79
+ b"prospective-positive-lane-card-graph:card-supported-by-every-lane:"
80
+ b"externally-keyed-card-order:select-exact-lane-count:"
81
+ b"provider-outcome-and-workload-neutral:fail-closed"
82
+ ).hexdigest()
83
+ _COMPATIBILITY_AUDIT_DOMAIN = (
84
+ b"agent-evolve:campaign-diagnostic-compatibility-audit:v1\x00"
85
+ )
86
+ _COHORT_SELECTION_DOMAIN = (
87
+ b"agent-evolve:campaign-diagnostic-cohort-selection:v1\x00"
88
+ )
89
+ _COHORT_CARD_ORDER_DOMAIN = (
90
+ b"agent-evolve:campaign-diagnostic-cohort-card-order:v1\x00"
91
+ )
92
+ CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_ID = (
93
+ "campaign_diagnostic_complete_support_resolution"
94
+ )
95
+ CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_VERSION = 1
96
+ CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_DEFINITION_SHA256 = hashlib.sha256(
97
+ b"agent-evolve:campaign-diagnostic-complete-support-resolution:v1:"
98
+ b"typed-current-finite-contract-per-stable-lane:typed-card-semantics:"
99
+ b"prospective-positive-support-derivation:outcome-blind-complete-support-"
100
+ b"cohort-selection:canonical-matching:complete-bipartite-audit:fail-closed"
101
+ ).hexdigest()
102
+ _SUPPORT_RESOLUTION_DOMAIN = (
103
+ b"agent-evolve:campaign-diagnostic-support-resolution:v1\x00"
104
+ )
105
+
106
+
107
+ def _canonical_json(value: object) -> bytes:
108
+ return json.dumps(
109
+ value,
110
+ allow_nan=False,
111
+ ensure_ascii=True,
112
+ separators=(",", ":"),
113
+ sort_keys=True,
114
+ ).encode("ascii", errors="strict")
115
+
116
+
117
+ class CampaignDiagnosticCompatibilityStatus(str, Enum):
118
+ """Whether the positive support graph admits the declared randomization."""
119
+
120
+ ELIGIBLE = "eligible_complete_bipartite_support"
121
+ INELIGIBLE = "ineligible_fail_closed_no_causal_credit"
122
+
123
+
124
+ class CampaignDiagnosticCohortSelectionStatus(str, Enum):
125
+ """Whether enough universally supported cards form one complete block."""
126
+
127
+ ELIGIBLE = "eligible_complete_support_cohort_selected"
128
+ INELIGIBLE = "ineligible_insufficient_complete_support_cards"
129
+
130
+
131
+ @dataclass(frozen=True, slots=True)
132
+ class CampaignDiagnosticSupportLaneInput:
133
+ """One stable lane and its current, parent-bound finite action contract."""
134
+
135
+ lane: LaneCardMatchingLane
136
+ finite_variation_contract: FiniteVariationContract
137
+
138
+ def __post_init__(self) -> None:
139
+ if type(self.lane) is not LaneCardMatchingLane:
140
+ raise TypeError("lane must be an exact LaneCardMatchingLane")
141
+ self.lane.__post_init__()
142
+ if type(self.finite_variation_contract) is not FiniteVariationContract:
143
+ raise TypeError(
144
+ "finite_variation_contract must be an exact FiniteVariationContract"
145
+ )
146
+ validate_finite_variation_contract(self.finite_variation_contract)
147
+
148
+
149
+ @dataclass(frozen=True, slots=True)
150
+ class CampaignDiagnosticSupportCardInput:
151
+ """One source-bound card and its trusted executable action semantics."""
152
+
153
+ card: LaneCardMatchingCard
154
+ semantics: PortfolioMemoryDoseCardSemantics
155
+
156
+ def __post_init__(self) -> None:
157
+ if type(self.card) is not LaneCardMatchingCard:
158
+ raise TypeError("card must be an exact LaneCardMatchingCard")
159
+ self.card.__post_init__()
160
+ if type(self.semantics) is not PortfolioMemoryDoseCardSemantics:
161
+ raise TypeError(
162
+ "semantics must be exact PortfolioMemoryDoseCardSemantics"
163
+ )
164
+ self.semantics.__post_init__()
165
+ if self.card.card_key != self.semantics.card_key:
166
+ raise ValueError("matching card and executable semantics differ")
167
+
168
+
169
+ @dataclass(frozen=True, slots=True)
170
+ class CampaignDiagnosticDerivedSupportEdge:
171
+ """One positive lane/card edge and its exact finite-option support."""
172
+
173
+ lane_id: str
174
+ card_key: str
175
+ support: PortfolioMemoryDoseCardSupport
176
+
177
+ def __post_init__(self) -> None:
178
+ if type(self.support) is not PortfolioMemoryDoseCardSupport:
179
+ raise TypeError("support must be exact PortfolioMemoryDoseCardSupport")
180
+ self.support.__post_init__()
181
+ if self.support.card_key != self.card_key:
182
+ raise ValueError("support edge and support card key differ")
183
+
184
+ @property
185
+ def evidence_sha256(self) -> str:
186
+ return hashlib.sha256(
187
+ _canonical_json(self.support.to_record())
188
+ ).hexdigest()
189
+
190
+ def to_record(self) -> dict[str, object]:
191
+ self.__post_init__()
192
+ return {
193
+ "lane_id": self.lane_id,
194
+ "card_key": self.card_key,
195
+ "compatibility_evidence_sha256": self.evidence_sha256,
196
+ "support": self.support.to_record(),
197
+ }
198
+
199
+
200
+ @dataclass(frozen=True, slots=True)
201
+ class CampaignDiagnosticRejectedSupportEdge:
202
+ """One prospectively incompatible lane/card pair, without raw error text."""
203
+
204
+ lane_id: str
205
+ card_key: str
206
+ reason_sha256: str
207
+
208
+ def __post_init__(self) -> None:
209
+ require_sha256(self.reason_sha256, "reason_sha256")
210
+
211
+ def to_record(self) -> dict[str, str]:
212
+ self.__post_init__()
213
+ return {
214
+ "lane_id": self.lane_id,
215
+ "card_key": self.card_key,
216
+ "status": "incompatible",
217
+ "reason_sha256": self.reason_sha256,
218
+ }
219
+
220
+
221
+ @dataclass(frozen=True, slots=True)
222
+ class CampaignDiagnosticCompleteSupportCohortSelection:
223
+ """Select a randomized, replayable complete-support card cohort.
224
+
225
+ Reflection may yield more candidate insights than a diagnostic wave has
226
+ stable lanes. Compatibility is necessarily parent-local, so selecting
227
+ the experimental cohort before those parents exist either broadens action
228
+ semantics or creates positivity violations. This policy filters only on
229
+ the prospective positive compatibility graph, then uses an external key to
230
+ sample exactly one lane-sized cohort before provider dispatch.
231
+ """
232
+
233
+ matching_input: LaneCardMatchingInput
234
+ cohort_size: int
235
+ selection_key_sha256: str
236
+ full_support_card_keys: tuple[str, ...] = field(init=False)
237
+ selected_card_keys: tuple[str, ...] = field(init=False)
238
+ selected_matching_input: LaneCardMatchingInput | None = field(init=False)
239
+ status: CampaignDiagnosticCohortSelectionStatus = field(init=False)
240
+ receipt_sha256: str = field(init=False)
241
+ policy_id: str = field(
242
+ init=False,
243
+ default=CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_ID,
244
+ )
245
+ policy_version: int = field(
246
+ init=False,
247
+ default=CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_VERSION,
248
+ )
249
+ policy_definition_sha256: str = field(
250
+ init=False,
251
+ default=CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_DEFINITION_SHA256,
252
+ )
253
+
254
+ def __post_init__(self) -> None:
255
+ if type(self.matching_input) is not LaneCardMatchingInput:
256
+ raise TypeError("matching_input must be exact LaneCardMatchingInput")
257
+ self.matching_input.__post_init__()
258
+ if type(self.cohort_size) is not int or self.cohort_size < 2:
259
+ raise ValueError("cohort_size must be an exact integer of at least two")
260
+ if self.cohort_size != len(self.matching_input.lanes):
261
+ raise ValueError("cohort_size must exactly fill the stable lanes")
262
+ require_sha256(self.selection_key_sha256, "selection_key_sha256")
263
+ positive = {
264
+ (value.lane_id, value.card_key)
265
+ for value in self.matching_input.compatibilities
266
+ }
267
+ lane_ids = tuple(value.lane_id for value in self.matching_input.lanes)
268
+ full_support = tuple(
269
+ card.card_key
270
+ for card in self.matching_input.cards
271
+ if all((lane_id, card.card_key) in positive for lane_id in lane_ids)
272
+ )
273
+ object.__setattr__(self, "full_support_card_keys", full_support)
274
+ eligible = len(full_support) >= self.cohort_size
275
+ if eligible:
276
+ cards_by_key = {
277
+ value.card_key: value for value in self.matching_input.cards
278
+ }
279
+ ordered = tuple(
280
+ sorted(
281
+ full_support,
282
+ key=lambda card_key: (
283
+ hashlib.sha256(
284
+ _COHORT_CARD_ORDER_DOMAIN
285
+ + bytes.fromhex(self.selection_key_sha256)
286
+ + card_key.encode("ascii", errors="strict")
287
+ + bytes.fromhex(
288
+ cards_by_key[card_key].card_identity_sha256
289
+ )
290
+ ).digest(),
291
+ card_key,
292
+ ),
293
+ )
294
+ )
295
+ selected_set = frozenset(ordered[: self.cohort_size])
296
+ selected_keys = tuple(sorted(selected_set))
297
+ selected_input = LaneCardMatchingInput(
298
+ lanes=self.matching_input.lanes,
299
+ cards=tuple(
300
+ value
301
+ for value in self.matching_input.cards
302
+ if value.card_key in selected_set
303
+ ),
304
+ compatibilities=tuple(
305
+ value
306
+ for value in self.matching_input.compatibilities
307
+ if value.card_key in selected_set
308
+ ),
309
+ )
310
+ status = CampaignDiagnosticCohortSelectionStatus.ELIGIBLE
311
+ else:
312
+ selected_keys = ()
313
+ selected_input = None
314
+ status = CampaignDiagnosticCohortSelectionStatus.INELIGIBLE
315
+ object.__setattr__(self, "selected_card_keys", selected_keys)
316
+ object.__setattr__(self, "selected_matching_input", selected_input)
317
+ object.__setattr__(self, "status", status)
318
+ object.__setattr__(
319
+ self,
320
+ "receipt_sha256",
321
+ hashlib.sha256(
322
+ _COHORT_SELECTION_DOMAIN + _canonical_json(self._unsigned_record())
323
+ ).hexdigest(),
324
+ )
325
+
326
+ @property
327
+ def eligible(self) -> bool:
328
+ return self.status is CampaignDiagnosticCohortSelectionStatus.ELIGIBLE
329
+
330
+ def _unsigned_record(self) -> dict[str, object]:
331
+ return {
332
+ "schema_version": 1,
333
+ "policy": {
334
+ "policy_id": self.policy_id,
335
+ "policy_version": self.policy_version,
336
+ "policy_definition_sha256": self.policy_definition_sha256,
337
+ },
338
+ "matching_input_sha256": self.matching_input.input_sha256,
339
+ "compatibility_graph_sha256": (
340
+ self.matching_input.compatibility_graph_sha256
341
+ ),
342
+ "cohort_size": self.cohort_size,
343
+ "selection_key_sha256": self.selection_key_sha256,
344
+ "full_support_card_keys": list(self.full_support_card_keys),
345
+ "selected_card_keys": list(self.selected_card_keys),
346
+ "status": self.status.value,
347
+ "provider_fields_consulted": False,
348
+ "outcome_values_consulted": False,
349
+ }
350
+
351
+ def to_record(self) -> dict[str, object]:
352
+ self.__post_init__()
353
+ return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
354
+
355
+
356
+ @dataclass(frozen=True, slots=True)
357
+ class CampaignDiagnosticCompatibilityAudit:
358
+ """Authenticate complete support before randomized card assignment.
359
+
360
+ A maximum matching is enough to administer one compatible card per lane,
361
+ but it is not enough to randomize every card over every lane. This audit
362
+ closes that distinction. The existing balanced singleton law may be used
363
+ only when lane/card cardinality is equal, at least two experimental units
364
+ exist, and the prospective positive graph is complete bipartite.
365
+
366
+ Passing this audit authorizes the assignment law. It does not identify a
367
+ card-versus-no-memory effect: every lane may still receive another active
368
+ card, and one realized block supplies no matched neutral potential outcome.
369
+ """
370
+
371
+ matching_input: LaneCardMatchingInput
372
+ status: CampaignDiagnosticCompatibilityStatus = field(init=False)
373
+ missing_pairs: tuple[tuple[str, str], ...] = field(init=False)
374
+ audit_sha256: str = field(init=False)
375
+ policy_id: str = field(
376
+ init=False,
377
+ default=CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_ID,
378
+ )
379
+ policy_version: int = field(
380
+ init=False,
381
+ default=CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_VERSION,
382
+ )
383
+ policy_definition_sha256: str = field(
384
+ init=False,
385
+ default=CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_DEFINITION_SHA256,
386
+ )
387
+
388
+ def __post_init__(self) -> None:
389
+ if type(self.matching_input) is not LaneCardMatchingInput:
390
+ raise TypeError("matching_input must be exact LaneCardMatchingInput")
391
+ self.matching_input.__post_init__()
392
+ observed = {
393
+ (value.lane_id, value.card_key)
394
+ for value in self.matching_input.compatibilities
395
+ }
396
+ expected = tuple(
397
+ (lane.lane_id, card.card_key)
398
+ for lane in self.matching_input.lanes
399
+ for card in self.matching_input.cards
400
+ )
401
+ missing = tuple(value for value in expected if value not in observed)
402
+ eligible = (
403
+ len(self.matching_input.lanes) >= 2
404
+ and len(self.matching_input.lanes) == len(self.matching_input.cards)
405
+ and not missing
406
+ )
407
+ object.__setattr__(self, "missing_pairs", missing)
408
+ object.__setattr__(
409
+ self,
410
+ "status",
411
+ (
412
+ CampaignDiagnosticCompatibilityStatus.ELIGIBLE
413
+ if eligible
414
+ else CampaignDiagnosticCompatibilityStatus.INELIGIBLE
415
+ ),
416
+ )
417
+ object.__setattr__(
418
+ self,
419
+ "audit_sha256",
420
+ hashlib.sha256(
421
+ _COMPATIBILITY_AUDIT_DOMAIN + _canonical_json(self._unsigned_record())
422
+ ).hexdigest(),
423
+ )
424
+
425
+ @property
426
+ def eligible(self) -> bool:
427
+ return self.status is CampaignDiagnosticCompatibilityStatus.ELIGIBLE
428
+
429
+ def _unsigned_record(self) -> dict[str, object]:
430
+ return {
431
+ "schema_version": 1,
432
+ "policy": {
433
+ "policy_id": self.policy_id,
434
+ "policy_version": self.policy_version,
435
+ "policy_definition_sha256": self.policy_definition_sha256,
436
+ },
437
+ "matching_input_sha256": self.matching_input.input_sha256,
438
+ "compatibility_graph_sha256": (
439
+ self.matching_input.compatibility_graph_sha256
440
+ ),
441
+ "lane_count": len(self.matching_input.lanes),
442
+ "card_count": len(self.matching_input.cards),
443
+ "observed_positive_edge_count": len(
444
+ self.matching_input.compatibilities
445
+ ),
446
+ "required_complete_edge_count": (
447
+ len(self.matching_input.lanes) * len(self.matching_input.cards)
448
+ ),
449
+ "minimum_two_units": len(self.matching_input.lanes) >= 2,
450
+ "balanced_cardinality": (
451
+ len(self.matching_input.lanes) == len(self.matching_input.cards)
452
+ ),
453
+ "complete_bipartite_support": not self.missing_pairs,
454
+ "missing_pairs": [
455
+ {"lane_id": lane_id, "card_key": card_key}
456
+ for lane_id, card_key in self.missing_pairs
457
+ ],
458
+ "status": self.status.value,
459
+ "randomized_singleton_assignment_allowed": self.eligible,
460
+ "card_vs_neutral_effect_identified": False,
461
+ "causal_credit_allowed": False,
462
+ "online_score_update_allowed": False,
463
+ "required_successor_design": (
464
+ "prospective_randomized_prompt_redacted_matched_control"
465
+ ),
466
+ }
467
+
468
+ def to_record(self) -> dict[str, object]:
469
+ self.__post_init__()
470
+ return {**self._unsigned_record(), "audit_sha256": self.audit_sha256}
471
+
472
+
473
+ @dataclass(frozen=True, slots=True)
474
+ class CampaignDiagnosticCompleteSupportResolution:
475
+ """Authenticated prospective resolution of one lane/card diagnostic block."""
476
+
477
+ full_matching_input: LaneCardMatchingInput
478
+ cohort_selection: CampaignDiagnosticCompleteSupportCohortSelection
479
+ matching: LaneCardMatchingReceipt
480
+ compatibility_audit: CampaignDiagnosticCompatibilityAudit
481
+ supports: tuple[CampaignDiagnosticDerivedSupportEdge, ...]
482
+ rejected_edges: tuple[CampaignDiagnosticRejectedSupportEdge, ...]
483
+ policy_id: str = field(
484
+ init=False,
485
+ default=CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_ID,
486
+ )
487
+ policy_version: int = field(
488
+ init=False,
489
+ default=CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_VERSION,
490
+ )
491
+ policy_definition_sha256: str = field(
492
+ init=False,
493
+ default=CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_DEFINITION_SHA256,
494
+ )
495
+
496
+ def __post_init__(self) -> None:
497
+ if type(self.full_matching_input) is not LaneCardMatchingInput:
498
+ raise TypeError("full_matching_input must be exact LaneCardMatchingInput")
499
+ self.full_matching_input.__post_init__()
500
+ if type(self.cohort_selection) is not (
501
+ CampaignDiagnosticCompleteSupportCohortSelection
502
+ ):
503
+ raise TypeError("cohort_selection must be exact")
504
+ self.cohort_selection.__post_init__()
505
+ if self.cohort_selection.matching_input != self.full_matching_input:
506
+ raise ValueError("cohort selection differs from the full support graph")
507
+ if type(self.matching) is not LaneCardMatchingReceipt:
508
+ raise TypeError("matching must be an exact LaneCardMatchingReceipt")
509
+ self.matching.__post_init__()
510
+ selected_input = self.cohort_selection.selected_matching_input
511
+ expected_matching_input = (
512
+ self.full_matching_input if selected_input is None else selected_input
513
+ )
514
+ if self.matching.matching_input != expected_matching_input:
515
+ raise ValueError("matching differs from selected diagnostic population")
516
+ if type(self.compatibility_audit) is not CampaignDiagnosticCompatibilityAudit:
517
+ raise TypeError("compatibility_audit must be exact")
518
+ self.compatibility_audit.__post_init__()
519
+ if self.compatibility_audit.matching_input != self.matching.matching_input:
520
+ raise ValueError("compatibility audit differs from the matching population")
521
+ if type(self.supports) is not tuple or any(
522
+ type(value) is not CampaignDiagnosticDerivedSupportEdge
523
+ for value in self.supports
524
+ ):
525
+ raise TypeError("supports must be an exact support-edge tuple")
526
+ for value in self.supports:
527
+ value.__post_init__()
528
+ support_keys = tuple((value.lane_id, value.card_key) for value in self.supports)
529
+ if support_keys != tuple(sorted(set(support_keys))):
530
+ raise ValueError("supports must use unique canonical lane/card order")
531
+ graph_keys = tuple(
532
+ (value.lane_id, value.card_key)
533
+ for value in self.full_matching_input.compatibilities
534
+ )
535
+ if support_keys != graph_keys:
536
+ raise ValueError("derived supports differ from positive graph edges")
537
+ if type(self.rejected_edges) is not tuple or any(
538
+ type(value) is not CampaignDiagnosticRejectedSupportEdge
539
+ for value in self.rejected_edges
540
+ ):
541
+ raise TypeError("rejected_edges must be an exact tuple")
542
+ for value in self.rejected_edges:
543
+ value.__post_init__()
544
+ rejected_keys = tuple(
545
+ (value.lane_id, value.card_key) for value in self.rejected_edges
546
+ )
547
+ if rejected_keys != tuple(sorted(set(rejected_keys))):
548
+ raise ValueError("rejected edges must use unique canonical lane/card order")
549
+ if set(support_keys).intersection(rejected_keys):
550
+ raise ValueError("one lane/card pair cannot be supported and rejected")
551
+ all_pairs = {
552
+ (lane.lane_id, card.card_key)
553
+ for lane in self.full_matching_input.lanes
554
+ for card in self.full_matching_input.cards
555
+ }
556
+ if set((*support_keys, *rejected_keys)) != all_pairs:
557
+ raise ValueError("support resolution must classify every lane/card pair")
558
+ if (
559
+ self.policy_id != CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_ID
560
+ or self.policy_version
561
+ != CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_VERSION
562
+ or self.policy_definition_sha256
563
+ != CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_DEFINITION_SHA256
564
+ ):
565
+ raise ValueError("unsupported complete-support resolution policy")
566
+
567
+ @property
568
+ def eligible(self) -> bool:
569
+ self.__post_init__()
570
+ return (
571
+ self.cohort_selection.eligible
572
+ and self.matching.is_full
573
+ and self.compatibility_audit.eligible
574
+ )
575
+
576
+ def support_for(
577
+ self,
578
+ lane_id: str,
579
+ card_key: str,
580
+ ) -> PortfolioMemoryDoseCardSupport:
581
+ self.__post_init__()
582
+ values = tuple(
583
+ value.support
584
+ for value in self.supports
585
+ if value.lane_id == lane_id and value.card_key == card_key
586
+ )
587
+ if len(values) != 1:
588
+ raise KeyError("lane/card pair has no derived positive support")
589
+ return values[0]
590
+
591
+ def _unsigned_record(self) -> dict[str, object]:
592
+ return {
593
+ "schema_version": 1,
594
+ "policy": {
595
+ "policy_id": self.policy_id,
596
+ "policy_version": self.policy_version,
597
+ "policy_definition_sha256": self.policy_definition_sha256,
598
+ },
599
+ "full_matching_input": self.full_matching_input.to_record(),
600
+ "cohort_selection": self.cohort_selection.to_record(),
601
+ "matching": self.matching.to_record(),
602
+ "compatibility_audit": self.compatibility_audit.to_record(),
603
+ "supports": [value.to_record() for value in self.supports],
604
+ "rejected_edges": [
605
+ value.to_record() for value in self.rejected_edges
606
+ ],
607
+ "eligible": self.eligible,
608
+ "provider_fields_consulted": False,
609
+ "outcome_values_consulted": False,
610
+ }
611
+
612
+ @property
613
+ def receipt_sha256(self) -> str:
614
+ return hashlib.sha256(
615
+ _SUPPORT_RESOLUTION_DOMAIN + _canonical_json(self._unsigned_record())
616
+ ).hexdigest()
617
+
618
+ def to_record(self) -> dict[str, object]:
619
+ self.__post_init__()
620
+ return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
621
+
622
+
623
+ @dataclass(frozen=True, slots=True)
624
+ class CampaignDiagnosticCompleteSupportResolver:
625
+ """Derive and resolve a complete-support cohort before provider dispatch."""
626
+
627
+ def resolve(
628
+ self,
629
+ *,
630
+ lanes: tuple[CampaignDiagnosticSupportLaneInput, ...],
631
+ cards: tuple[CampaignDiagnosticSupportCardInput, ...],
632
+ cohort_size: int,
633
+ selection_key_sha256: str,
634
+ ) -> CampaignDiagnosticCompleteSupportResolution:
635
+ if type(lanes) is not tuple or not lanes or any(
636
+ type(value) is not CampaignDiagnosticSupportLaneInput for value in lanes
637
+ ):
638
+ raise ValueError("lanes must be a non-empty exact support-lane tuple")
639
+ if type(cards) is not tuple or not cards or any(
640
+ type(value) is not CampaignDiagnosticSupportCardInput for value in cards
641
+ ):
642
+ raise ValueError("cards must be a non-empty exact support-card tuple")
643
+ for value in lanes:
644
+ value.__post_init__()
645
+ for value in cards:
646
+ value.__post_init__()
647
+ lane_ids = tuple(value.lane.lane_id for value in lanes)
648
+ card_keys = tuple(value.card.card_key for value in cards)
649
+ if lane_ids != tuple(sorted(set(lane_ids))):
650
+ raise ValueError("support lanes must be unique and canonical")
651
+ if card_keys != tuple(sorted(set(card_keys))):
652
+ raise ValueError("support cards must be unique and canonical")
653
+ if type(cohort_size) is not int or cohort_size != len(lanes):
654
+ raise ValueError("cohort_size must exactly equal the stable lane count")
655
+ require_sha256(selection_key_sha256, "selection_key_sha256")
656
+
657
+ supports: list[CampaignDiagnosticDerivedSupportEdge] = []
658
+ rejected: list[CampaignDiagnosticRejectedSupportEdge] = []
659
+ for lane in lanes:
660
+ for card in cards:
661
+ try:
662
+ support = derive_portfolio_memory_dose_card_support(
663
+ card.semantics,
664
+ lane.finite_variation_contract,
665
+ )
666
+ except ValueError as error:
667
+ rejected.append(
668
+ CampaignDiagnosticRejectedSupportEdge(
669
+ lane_id=lane.lane.lane_id,
670
+ card_key=card.card.card_key,
671
+ reason_sha256=hashlib.sha256(
672
+ str(error).encode("utf-8", errors="strict")
673
+ ).hexdigest(),
674
+ )
675
+ )
676
+ continue
677
+ supports.append(
678
+ CampaignDiagnosticDerivedSupportEdge(
679
+ lane_id=lane.lane.lane_id,
680
+ card_key=card.card.card_key,
681
+ support=support,
682
+ )
683
+ )
684
+ canonical_supports = tuple(
685
+ sorted(supports, key=lambda value: (value.lane_id, value.card_key))
686
+ )
687
+ canonical_rejected = tuple(
688
+ sorted(rejected, key=lambda value: (value.lane_id, value.card_key))
689
+ )
690
+ matching_input = LaneCardMatchingInput(
691
+ lanes=tuple(value.lane for value in lanes),
692
+ cards=tuple(value.card for value in cards),
693
+ compatibilities=tuple(
694
+ LaneCardCompatibility(
695
+ lane_id=value.lane_id,
696
+ card_key=value.card_key,
697
+ compatibility_evidence_sha256=value.evidence_sha256,
698
+ )
699
+ for value in canonical_supports
700
+ ),
701
+ )
702
+ selection = CampaignDiagnosticCompleteSupportCohortSelection(
703
+ matching_input=matching_input,
704
+ cohort_size=cohort_size,
705
+ selection_key_sha256=selection_key_sha256,
706
+ )
707
+ selected_input = selection.selected_matching_input
708
+ diagnostic_input = matching_input if selected_input is None else selected_input
709
+ matching = CanonicalLaneCardMatchingPlanner().plan(
710
+ lanes=diagnostic_input.lanes,
711
+ cards=diagnostic_input.cards,
712
+ compatibilities=diagnostic_input.compatibilities,
713
+ )
714
+ audit = CampaignDiagnosticCompatibilityAudit(matching.matching_input)
715
+ return CampaignDiagnosticCompleteSupportResolution(
716
+ full_matching_input=matching_input,
717
+ cohort_selection=selection,
718
+ matching=matching,
719
+ compatibility_audit=audit,
720
+ supports=canonical_supports,
721
+ rejected_edges=canonical_rejected,
722
+ )
723
+
724
+
725
+ def _canonical_references(
726
+ values: tuple[InsightRef, ...],
727
+ *,
728
+ name: str,
729
+ empty: bool,
730
+ ) -> tuple[InsightRef, ...]:
731
+ if type(values) is not tuple or any(
732
+ type(value) is not InsightRef for value in values
733
+ ):
734
+ raise TypeError(f"{name} must be an exact tuple of InsightRef values")
735
+ for value in values:
736
+ InsightRef.__post_init__(value)
737
+ if values != tuple(sorted(set(values))):
738
+ raise ValueError(f"{name} must be unique and canonical")
739
+ if not empty and not values:
740
+ raise ValueError(f"{name} must be non-empty")
741
+ return values
742
+
743
+
744
+ @dataclass(frozen=True, slots=True)
745
+ class CampaignDiagnosticSingletonBlock:
746
+ """Authenticated complete singleton block over active and control cards."""
747
+
748
+ active_references: tuple[InsightRef, ...]
749
+ control_references: tuple[InsightRef, ...]
750
+ assignment_plan: BalancedSubsetBlockPlan
751
+ policy_id: str = field(
752
+ init=False,
753
+ default=CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_ID,
754
+ )
755
+ policy_version: int = field(
756
+ init=False,
757
+ default=CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_VERSION,
758
+ )
759
+ policy_definition_sha256: str = field(
760
+ init=False,
761
+ default=CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_DEFINITION_SHA256,
762
+ )
763
+
764
+ def __post_init__(self) -> None:
765
+ active = _canonical_references(
766
+ self.active_references,
767
+ name="active_references",
768
+ empty=False,
769
+ )
770
+ controls = _canonical_references(
771
+ self.control_references,
772
+ name="control_references",
773
+ empty=True,
774
+ )
775
+ if set(active).intersection(controls):
776
+ raise ValueError("active and control references must be disjoint")
777
+ if type(self.assignment_plan) is not BalancedSubsetBlockPlan:
778
+ raise TypeError("assignment_plan must be exact BalancedSubsetBlockPlan")
779
+ self.assignment_plan.__post_init__()
780
+ eligible = tuple(
781
+ entry.reference for entry in self.assignment_plan.snapshot.entries
782
+ )
783
+ if eligible != tuple(sorted((*active, *controls))):
784
+ raise ValueError("assignment snapshot differs from the diagnostic cohort")
785
+ if (
786
+ self.assignment_plan.subset_size != 1
787
+ or self.assignment_plan.full_block_count != 1
788
+ or self.assignment_plan.remainder_size != 0
789
+ or len(self.assignment_plan.ordered_units) != len(eligible)
790
+ ):
791
+ raise ValueError(
792
+ "diagnostic singleton design must be exactly one complete block"
793
+ )
794
+ if (
795
+ self.policy_id != CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_ID
796
+ or self.policy_version != CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_VERSION
797
+ or self.policy_definition_sha256
798
+ != CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_DEFINITION_SHA256
799
+ ):
800
+ raise ValueError("unsupported diagnostic singleton block policy")
801
+
802
+ @property
803
+ def plan_sha256(self) -> str:
804
+ self.__post_init__()
805
+ return self.assignment_plan.receipt_sha256
806
+
807
+ def to_record(self) -> dict[str, object]:
808
+ self.__post_init__()
809
+ return {
810
+ "schema_version": 1,
811
+ "policy": {
812
+ "policy_id": self.policy_id,
813
+ "policy_version": self.policy_version,
814
+ "definition_sha256": self.policy_definition_sha256,
815
+ },
816
+ "active_references": [
817
+ {
818
+ "insight_id": value.insight_id.value,
819
+ "version": value.version,
820
+ }
821
+ for value in self.active_references
822
+ ],
823
+ "control_references": [
824
+ {
825
+ "insight_id": value.insight_id.value,
826
+ "version": value.version,
827
+ }
828
+ for value in self.control_references
829
+ ],
830
+ "assignment_plan": self.assignment_plan.to_record(),
831
+ "plan_sha256": self.plan_sha256,
832
+ }
833
+
834
+
835
+ @dataclass(frozen=True, slots=True)
836
+ class CampaignDiagnosticSingletonBlockPlanner:
837
+ """Fill stable lanes and delegate exact randomization to the block policy."""
838
+
839
+ def plan(
840
+ self,
841
+ *,
842
+ active_references: tuple[InsightRef, ...],
843
+ control_references: tuple[InsightRef, ...],
844
+ exact_context_sha256: str,
845
+ estimand_stratum_sha256: str,
846
+ ordered_units: tuple[StableMemoryAssignmentUnit, ...],
847
+ full_block_permutation_rank: int,
848
+ ) -> CampaignDiagnosticSingletonBlock:
849
+ active = _canonical_references(
850
+ active_references,
851
+ name="active_references",
852
+ empty=False,
853
+ )
854
+ controls = _canonical_references(
855
+ control_references,
856
+ name="control_references",
857
+ empty=True,
858
+ )
859
+ if set(active).intersection(controls):
860
+ raise ValueError("active and control references must be disjoint")
861
+ require_sha256(exact_context_sha256, "exact_context_sha256")
862
+ require_sha256(estimand_stratum_sha256, "estimand_stratum_sha256")
863
+ if (
864
+ type(ordered_units) is not tuple
865
+ or len(ordered_units) < 2
866
+ or any(
867
+ type(value) is not StableMemoryAssignmentUnit for value in ordered_units
868
+ )
869
+ ):
870
+ raise ValueError(
871
+ "ordered_units must contain at least two exact stable lanes"
872
+ )
873
+ for value in ordered_units:
874
+ StableMemoryAssignmentUnit.__post_init__(value)
875
+ eligible = tuple(sorted((*active, *controls)))
876
+ if len(eligible) != len(ordered_units):
877
+ raise ValueError(
878
+ "active plus control references must exactly fill the stable lanes"
879
+ )
880
+ if type(full_block_permutation_rank) is not int or not (
881
+ 0 <= full_block_permutation_rank < math.factorial(len(eligible))
882
+ ):
883
+ raise ValueError("full_block_permutation_rank is outside the exact law")
884
+ snapshot = CausalSearchScorePolicy(
885
+ uncertainty_scale=0.0,
886
+ exploration_weight=0.0,
887
+ ).genesis(
888
+ exact_context_hash=exact_context_sha256,
889
+ estimand_stratum_hash=estimand_stratum_sha256,
890
+ priors={reference: 0.0 for reference in eligible},
891
+ )
892
+ assignment_plan = BalancedSubsetBlockPlanner().plan(
893
+ snapshot=snapshot,
894
+ ordered_units=ordered_units,
895
+ subset_size=1,
896
+ full_block_permutation_ranks=(full_block_permutation_rank,),
897
+ )
898
+ return CampaignDiagnosticSingletonBlock(
899
+ active_references=active,
900
+ control_references=controls,
901
+ assignment_plan=assignment_plan,
902
+ )
903
+
904
+
905
+ __all__ = [
906
+ "CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_DEFINITION_SHA256",
907
+ "CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_ID",
908
+ "CAMPAIGN_DIAGNOSTIC_COHORT_SELECTION_POLICY_VERSION",
909
+ "CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_DEFINITION_SHA256",
910
+ "CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_ID",
911
+ "CAMPAIGN_DIAGNOSTIC_COMPATIBILITY_AUDIT_POLICY_VERSION",
912
+ "CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_DEFINITION_SHA256",
913
+ "CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_ID",
914
+ "CAMPAIGN_DIAGNOSTIC_SINGLETON_BLOCK_POLICY_VERSION",
915
+ "CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_DEFINITION_SHA256",
916
+ "CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_ID",
917
+ "CAMPAIGN_DIAGNOSTIC_SUPPORT_RESOLUTION_POLICY_VERSION",
918
+ "CampaignDiagnosticCompleteSupportResolution",
919
+ "CampaignDiagnosticCompleteSupportResolver",
920
+ "CampaignDiagnosticSingletonBlock",
921
+ "CampaignDiagnosticSingletonBlockPlanner",
922
+ "CampaignDiagnosticCohortSelectionStatus",
923
+ "CampaignDiagnosticCompleteSupportCohortSelection",
924
+ "CampaignDiagnosticCompatibilityAudit",
925
+ "CampaignDiagnosticCompatibilityStatus",
926
+ "CampaignDiagnosticDerivedSupportEdge",
927
+ "CampaignDiagnosticRejectedSupportEdge",
928
+ "CampaignDiagnosticSupportCardInput",
929
+ "CampaignDiagnosticSupportLaneInput",
930
+ ]