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,1571 @@
1
+ """Prior-only calibrated acquisition over a finite K8 slate.
2
+
3
+ The model proposes eight workload-grounded candidates. This provider-free
4
+ policy assigns four distinct evaluation roles using only facts sealed before
5
+ the current wave: calibrated forecast correctness, explicit abstention,
6
+ structural evidence, and feasibility constraints. Model-authored card
7
+ citations remain observable diagnostics but have no allocation authority.
8
+
9
+ The policy is intentionally workload-neutral and has no fitted benchmark
10
+ hyperparameters. In particular, an ``unknown`` direction is treated as
11
+ maximum epistemic uncertainty rather than as zero information. Epistemic
12
+ priority is multiplied by structural novelty/coverage so that uncertainty is
13
+ spent on candidates that can distinguish materially different hypotheses.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import hashlib
19
+ import json
20
+ import math
21
+ from dataclasses import dataclass
22
+ from enum import Enum
23
+ from itertools import permutations
24
+ from typing import Any, ClassVar
25
+
26
+ from agent_evolve.domain.patch import require_sha256
27
+ from agent_evolve.policies.selection.calibrated_slate import (
28
+ CalibratedSlateMember,
29
+ MetricOptimizationGoal,
30
+ SlateAllocationRequest,
31
+ assess_allocated_slate_memory_dose,
32
+ )
33
+ from agent_evolve.policies.selection.forecast_calibration import (
34
+ ForecastCalibrationCell,
35
+ ForecastConfidenceBin,
36
+ )
37
+ from agent_evolve.policies.variation.compositional_finite_catalog import (
38
+ COMPOSITE_OPTION_FAMILY,
39
+ )
40
+ from agent_evolve.ports.agentic_generator import MetricEffectDirection
41
+ from agent_evolve.ports.portfolio_memory_dose import (
42
+ PortfolioMemoryDoseAssessment,
43
+ )
44
+
45
+
46
+ POLICY_ID = "calibrated_frontier_four_role_slate"
47
+ POLICY_VERSION = 2
48
+ POLICY_DEFINITION_SHA256 = hashlib.sha256(
49
+ b"agent-evolve:calibrated-frontier-four-role-slate:v2;"
50
+ b"slate-size=8;portfolio-size=4;outcome-blind=true;"
51
+ b"calibration-cutoff-exclusive=true;"
52
+ b"roles=calibrated-exploit,calibrated-frontier,epistemic-structural,"
53
+ b"structural-coverage;unknown-epistemic-score=1;"
54
+ b"expected-signed-utility=favorable:2p-1,adverse:1-2p;"
55
+ b"known-epistemic-score=mean(posterior-uncertainty,calibrated-disagreement);"
56
+ b"epistemic-structural-coupling=multiply;"
57
+ b"frontier-score=expected-utility+0.5*structural;"
58
+ b"joint-exact-role-assignment=true;diversity-weight=0.25;"
59
+ b"model-card-citations=diagnostic-only;hard-memory-dose=matched-diagnostic-only;"
60
+ b"compatibility-family-and-patch-feasibility=true;"
61
+ b"no-benchmark-specific-parameters=true"
62
+ ).hexdigest()
63
+
64
+ OPERATOR_STRATIFIED_POLICY_ID = (
65
+ "operator_stratified_calibrated_frontier_four_role_slate"
66
+ )
67
+ OPERATOR_STRATIFIED_POLICY_VERSION = 1
68
+ OPERATOR_STRATIFIED_POLICY_DEFINITION_SHA256 = hashlib.sha256(
69
+ b"agent-evolve:operator-stratified-calibrated-frontier-four-role-slate:v1;"
70
+ b"base=calibrated-frontier-four-role-v2;"
71
+ b"required-family-minimums=authenticated-configuration;"
72
+ b"minimums-are-evaluation-assay-slots-not-quality-priors;"
73
+ b"joint-feasibility-and-role-optimization=true;outcome-blind=true;"
74
+ b"no-workload-specific-parameters=true"
75
+ ).hexdigest()
76
+
77
+ HORIZON_BOUNDED_POLICY_ID = (
78
+ "horizon_bounded_calibrated_frontier_four_role_slate"
79
+ )
80
+ HORIZON_BOUNDED_POLICY_VERSION = 1
81
+ HORIZON_BOUNDED_POLICY_DEFINITION_SHA256 = hashlib.sha256(
82
+ b"agent-evolve:horizon-bounded-calibrated-frontier-four-role-slate:v1;"
83
+ b"base=calibrated-frontier-four-role-v2;"
84
+ b"family-exposure-phases=authenticated-configuration;"
85
+ b"phase-index=sealed-wave-index;lower-and-upper-bounds=true;"
86
+ b"bounds-are-evaluation-assay-slots-not-quality-priors;"
87
+ b"infeasible-bounds=minimum-l1-structural-recourse;"
88
+ b"joint-feasibility-and-role-optimization=true;outcome-blind=true;"
89
+ b"arbitrary-action-family-identifiers=true;"
90
+ b"no-workload-specific-parameters=true"
91
+ ).hexdigest()
92
+
93
+ _DECISION_DOMAIN = b"agent-evolve:structural-posterior-slate-decision:v1\x00"
94
+ _CONFIGURATION_DOMAIN = b"agent-evolve:calibrated-frontier-configuration:v2\x00"
95
+ _OPERATOR_STRATIFIED_CONFIGURATION_DOMAIN = (
96
+ b"agent-evolve:operator-stratified-frontier-configuration:v1\x00"
97
+ )
98
+ _OPERATOR_STRATIFIED_DECISION_DOMAIN = (
99
+ b"agent-evolve:operator-stratified-frontier-decision:v1\x00"
100
+ )
101
+ _HORIZON_BOUNDED_CONFIGURATION_DOMAIN = (
102
+ b"agent-evolve:horizon-bounded-frontier-configuration:v1\x00"
103
+ )
104
+ _HORIZON_BOUNDED_DECISION_DOMAIN = (
105
+ b"agent-evolve:horizon-bounded-frontier-decision:v1\x00"
106
+ )
107
+ _SLATE_SIZE = 8
108
+ _PORTFOLIO_SIZE = 4
109
+ _FRONTIER_STRUCTURAL_WEIGHT = 0.5
110
+ _DIVERSITY_WEIGHT = 0.25
111
+
112
+
113
+ def _configuration_record() -> dict[str, object]:
114
+ return {
115
+ "schema_version": 2,
116
+ "slate_size": _SLATE_SIZE,
117
+ "portfolio_size": _PORTFOLIO_SIZE,
118
+ "unknown_epistemic_score_hex": (1.0).hex(),
119
+ "epistemic_structural_coupling": "multiply",
120
+ "expected_signed_utility": {
121
+ "favorable": "2p_minus_1",
122
+ "adverse": "1_minus_2p",
123
+ },
124
+ "frontier_structural_weight_hex": _FRONTIER_STRUCTURAL_WEIGHT.hex(),
125
+ "diversity_weight_hex": _DIVERSITY_WEIGHT.hex(),
126
+ "model_card_citation_authority": "diagnostic_only",
127
+ "hard_memory_dose": "matched_diagnostic_only",
128
+ "benchmark_specific_parameters": [],
129
+ }
130
+
131
+
132
+ def _canonical_json(value: object) -> bytes:
133
+ return json.dumps(
134
+ value,
135
+ allow_nan=False,
136
+ ensure_ascii=True,
137
+ separators=(",", ":"),
138
+ sort_keys=True,
139
+ ).encode("ascii", errors="strict")
140
+
141
+
142
+ def _hash(domain: bytes, value: object) -> str:
143
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
144
+
145
+
146
+ def _require_finite(value: float, *, name: str) -> None:
147
+ if type(value) is not float or not math.isfinite(value):
148
+ raise TypeError(f"{name} must be a finite canonical float")
149
+
150
+
151
+ def _require_unit_interval(value: float, *, name: str) -> None:
152
+ _require_finite(value, name=name)
153
+ if not 0.0 <= value <= 1.0:
154
+ raise ValueError(f"{name} must lie in [0, 1]")
155
+
156
+
157
+ def _require_canonical_strings(values: tuple[str, ...], *, name: str) -> None:
158
+ if type(values) is not tuple or any(
159
+ type(value) is not str or not value for value in values
160
+ ):
161
+ raise TypeError(f"{name} must be an exact tuple of non-empty strings")
162
+ if values != tuple(sorted(set(values))):
163
+ raise ValueError(f"{name} must be unique and canonical")
164
+
165
+
166
+ def _validate_required_family_minimums(
167
+ values: tuple[tuple[str, int], ...],
168
+ ) -> None:
169
+ if type(values) is not tuple or not values:
170
+ raise ValueError("required_family_minimums must be a non-empty exact tuple")
171
+ if values != tuple(sorted(values)):
172
+ raise ValueError("required_family_minimums must be canonical")
173
+ families: list[str] = []
174
+ total = 0
175
+ for family, minimum in values:
176
+ if type(family) is not str or not family:
177
+ raise ValueError("required family must be a non-empty string")
178
+ if type(minimum) is not int or not 1 <= minimum <= _PORTFOLIO_SIZE:
179
+ raise ValueError("required family minimum must lie in [1, 4]")
180
+ families.append(family)
181
+ total += minimum
182
+ if len(set(families)) != len(families):
183
+ raise ValueError("required families cannot repeat")
184
+ if total > _PORTFOLIO_SIZE:
185
+ raise ValueError("required family minimums exceed the evaluation budget")
186
+
187
+
188
+ @dataclass(frozen=True, slots=True)
189
+ class FamilyExposureBound:
190
+ """Authenticated lower and upper evaluator exposure for one action family."""
191
+
192
+ family: str
193
+ minimum_evaluations: int
194
+ maximum_evaluations: int
195
+
196
+ def __post_init__(self) -> None:
197
+ if type(self.family) is not str or not self.family:
198
+ raise ValueError("family must be a non-empty exact string")
199
+ if (
200
+ type(self.minimum_evaluations) is not int
201
+ or not 0 <= self.minimum_evaluations <= _PORTFOLIO_SIZE
202
+ ):
203
+ raise ValueError("minimum_evaluations must lie in [0, 4]")
204
+ if (
205
+ type(self.maximum_evaluations) is not int
206
+ or not 0 <= self.maximum_evaluations <= _PORTFOLIO_SIZE
207
+ ):
208
+ raise ValueError("maximum_evaluations must lie in [0, 4]")
209
+ if self.minimum_evaluations > self.maximum_evaluations:
210
+ raise ValueError("family exposure minimum cannot exceed its maximum")
211
+
212
+ def to_record(self) -> dict[str, object]:
213
+ self.__post_init__()
214
+ return {
215
+ "family": self.family,
216
+ "minimum_evaluations": self.minimum_evaluations,
217
+ "maximum_evaluations": self.maximum_evaluations,
218
+ }
219
+
220
+
221
+ @dataclass(frozen=True, slots=True)
222
+ class FamilyExposurePhase:
223
+ """Family exposure bounds activated at one sealed campaign wave index."""
224
+
225
+ start_wave_index: int
226
+ bounds: tuple[FamilyExposureBound, ...]
227
+
228
+ def __post_init__(self) -> None:
229
+ if type(self.start_wave_index) is not int or self.start_wave_index < 0:
230
+ raise ValueError("start_wave_index must be a non-negative exact integer")
231
+ if type(self.bounds) is not tuple or not self.bounds:
232
+ raise ValueError("bounds must be a non-empty exact tuple")
233
+ if len(self.bounds) > _PORTFOLIO_SIZE:
234
+ raise ValueError("family exposure bound count exceeds the portfolio size")
235
+ if any(type(value) is not FamilyExposureBound for value in self.bounds):
236
+ raise TypeError("bounds must contain exact FamilyExposureBound values")
237
+ for value in self.bounds:
238
+ value.__post_init__()
239
+ families = tuple(value.family for value in self.bounds)
240
+ if families != tuple(sorted(set(families))):
241
+ raise ValueError("phase families must be unique and canonical")
242
+ if sum(value.minimum_evaluations for value in self.bounds) > _PORTFOLIO_SIZE:
243
+ raise ValueError("phase family minima exceed the evaluation budget")
244
+
245
+ def to_record(self) -> dict[str, object]:
246
+ self.__post_init__()
247
+ return {
248
+ "start_wave_index": self.start_wave_index,
249
+ "bounds": [value.to_record() for value in self.bounds],
250
+ }
251
+
252
+
253
+ def _validate_family_exposure_phases(
254
+ values: tuple[FamilyExposurePhase, ...],
255
+ ) -> None:
256
+ if type(values) is not tuple or not values:
257
+ raise ValueError("family_exposure_phases must be a non-empty exact tuple")
258
+ if any(type(value) is not FamilyExposurePhase for value in values):
259
+ raise TypeError(
260
+ "family_exposure_phases must contain exact FamilyExposurePhase values"
261
+ )
262
+ for value in values:
263
+ value.__post_init__()
264
+ starts = tuple(value.start_wave_index for value in values)
265
+ if starts[0] != 0:
266
+ raise ValueError("family exposure phases must start at wave zero")
267
+ if starts != tuple(sorted(set(starts))):
268
+ raise ValueError("family exposure phase starts must be unique and canonical")
269
+
270
+
271
+ def build_terminal_tapered_family_exposure_phases(
272
+ *,
273
+ family: str,
274
+ terminal_wave_index: int,
275
+ discovery_exposure: int = 2,
276
+ terminal_exposure: int = 0,
277
+ ) -> tuple[FamilyExposurePhase, ...]:
278
+ """Build a generic explore-then-taper schedule for a finite campaign.
279
+
280
+ The caller supplies a topology family and the campaign's final selector
281
+ wave. No workload identifier or objective value enters the schedule.
282
+ """
283
+
284
+ if type(terminal_wave_index) is not int or terminal_wave_index <= 0:
285
+ raise ValueError("terminal_wave_index must be a positive exact integer")
286
+ discovery = FamilyExposureBound(
287
+ family=family,
288
+ minimum_evaluations=discovery_exposure,
289
+ maximum_evaluations=discovery_exposure,
290
+ )
291
+ terminal = FamilyExposureBound(
292
+ family=family,
293
+ minimum_evaluations=terminal_exposure,
294
+ maximum_evaluations=terminal_exposure,
295
+ )
296
+ phases = (
297
+ FamilyExposurePhase(start_wave_index=0, bounds=(discovery,)),
298
+ FamilyExposurePhase(
299
+ start_wave_index=terminal_wave_index,
300
+ bounds=(terminal,),
301
+ ),
302
+ )
303
+ _validate_family_exposure_phases(phases)
304
+ return phases
305
+
306
+
307
+ def build_controller_owned_family_exposure_phases(
308
+ *,
309
+ family: str,
310
+ ) -> tuple[FamilyExposurePhase, ...]:
311
+ """Expose the full K4 family range to an authenticated outer controller.
312
+
313
+ The horizon allocator remains responsible for structural feasibility and
314
+ replay, but contributes no fixed family-dose prior. A prospective
315
+ contextual allocation contract can therefore own the exact evaluator
316
+ exposure without conflicting with a second schedule.
317
+ """
318
+
319
+ phases = (
320
+ FamilyExposurePhase(
321
+ start_wave_index=0,
322
+ bounds=(
323
+ FamilyExposureBound(
324
+ family=family,
325
+ minimum_evaluations=0,
326
+ maximum_evaluations=_PORTFOLIO_SIZE,
327
+ ),
328
+ ),
329
+ ),
330
+ )
331
+ _validate_family_exposure_phases(phases)
332
+ return phases
333
+
334
+
335
+ def _active_family_exposure_phase(
336
+ phases: tuple[FamilyExposurePhase, ...],
337
+ *,
338
+ wave_index: int,
339
+ ) -> FamilyExposurePhase:
340
+ _validate_family_exposure_phases(phases)
341
+ if type(wave_index) is not int or wave_index < 0:
342
+ raise ValueError("wave_index must be a non-negative exact integer")
343
+ return max(
344
+ (value for value in phases if value.start_wave_index <= wave_index),
345
+ key=lambda value: value.start_wave_index,
346
+ )
347
+
348
+
349
+ def _horizon_bounded_configuration_record(
350
+ phases: tuple[FamilyExposurePhase, ...],
351
+ ) -> dict[str, object]:
352
+ _validate_family_exposure_phases(phases)
353
+ return {
354
+ "schema_version": 1,
355
+ "base_allocator": {
356
+ "policy_id": POLICY_ID,
357
+ "policy_version": POLICY_VERSION,
358
+ "definition_sha256": POLICY_DEFINITION_SHA256,
359
+ "configuration_sha256": _hash(
360
+ _CONFIGURATION_DOMAIN,
361
+ _configuration_record(),
362
+ ),
363
+ },
364
+ "family_exposure_phases": [value.to_record() for value in phases],
365
+ "phase_authority": "sealed_wave_index",
366
+ "constraint_semantics": "assay_exposure_not_quality_prior",
367
+ "outcomes_consulted": False,
368
+ "workload_identifiers": [],
369
+ }
370
+
371
+
372
+ class StructuralPosteriorSlateRole(str, Enum):
373
+ """Engine-owned purpose of one selected evaluation."""
374
+
375
+ CALIBRATED_EXPLOIT = "calibrated_exploit"
376
+ CALIBRATED_FRONTIER = "calibrated_frontier"
377
+ EPISTEMIC_STRUCTURAL = "epistemic_structural"
378
+ STRUCTURAL_COVERAGE = "structural_coverage"
379
+
380
+
381
+ _ROLES = (
382
+ StructuralPosteriorSlateRole.CALIBRATED_EXPLOIT,
383
+ StructuralPosteriorSlateRole.CALIBRATED_FRONTIER,
384
+ StructuralPosteriorSlateRole.EPISTEMIC_STRUCTURAL,
385
+ StructuralPosteriorSlateRole.STRUCTURAL_COVERAGE,
386
+ )
387
+
388
+
389
+ @dataclass(frozen=True, slots=True)
390
+ class StructuralPosteriorMetricScoreRow:
391
+ """One objective's auditable exploitation and epistemic contributions."""
392
+
393
+ metric_id: str
394
+ goal: MetricOptimizationGoal
395
+ asserted_direction: MetricEffectDirection
396
+ confidence: ForecastConfidenceBin
397
+ weight: float
398
+ calibration_cell: ForecastCalibrationCell
399
+ calibration_source: str
400
+ favorable_assertion: bool
401
+ adverse_assertion: bool
402
+ signed_exploitation_score: float
403
+ posterior_uncertainty_score: float
404
+ calibrated_disagreement_score: float
405
+ epistemic_score: float
406
+ explicit_abstention: bool
407
+
408
+ def __post_init__(self) -> None:
409
+ if type(self.metric_id) is not str or not self.metric_id:
410
+ raise ValueError("metric_id must be a non-empty string")
411
+ if type(self.goal) is not MetricOptimizationGoal:
412
+ raise TypeError("goal must be exact MetricOptimizationGoal")
413
+ if type(self.asserted_direction) is not MetricEffectDirection:
414
+ raise TypeError("asserted_direction must be exact MetricEffectDirection")
415
+ if type(self.confidence) is not ForecastConfidenceBin:
416
+ raise TypeError("confidence must be exact ForecastConfidenceBin")
417
+ _require_finite(self.weight, name="weight")
418
+ if self.weight <= 0.0:
419
+ raise ValueError("weight must be strictly positive")
420
+ if type(self.calibration_cell) is not ForecastCalibrationCell:
421
+ raise TypeError("calibration_cell must be exact ForecastCalibrationCell")
422
+ self.calibration_cell.__post_init__()
423
+ if self.calibration_source not in {
424
+ "supported_family",
425
+ "metric_direction_confidence",
426
+ "declared_prior",
427
+ }:
428
+ raise ValueError("unsupported calibration_source")
429
+ if type(self.favorable_assertion) is not bool:
430
+ raise TypeError("favorable_assertion must be an exact bool")
431
+ if type(self.adverse_assertion) is not bool:
432
+ raise TypeError("adverse_assertion must be an exact bool")
433
+ if self.favorable_assertion and self.adverse_assertion:
434
+ raise ValueError("one assertion cannot be favorable and adverse")
435
+ _require_finite(
436
+ self.signed_exploitation_score,
437
+ name="signed_exploitation_score",
438
+ )
439
+ for name in (
440
+ "posterior_uncertainty_score",
441
+ "calibrated_disagreement_score",
442
+ "epistemic_score",
443
+ ):
444
+ _require_unit_interval(getattr(self, name), name=name)
445
+ if type(self.explicit_abstention) is not bool:
446
+ raise TypeError("explicit_abstention must be an exact bool")
447
+ expected_abstention = (
448
+ self.asserted_direction is MetricEffectDirection.UNKNOWN
449
+ )
450
+ if self.explicit_abstention is not expected_abstention:
451
+ raise ValueError("explicit_abstention differs from asserted direction")
452
+ if self.explicit_abstention and self.epistemic_score != 1.0:
453
+ raise ValueError("explicit abstention must have maximum epistemic score")
454
+
455
+ def to_record(self) -> dict[str, object]:
456
+ self.__post_init__()
457
+ return {
458
+ "metric_id": self.metric_id,
459
+ "goal": self.goal.value,
460
+ "asserted_direction": self.asserted_direction.value,
461
+ "confidence": self.confidence.value,
462
+ "weight_hex": self.weight.hex(),
463
+ "calibration_cell": self.calibration_cell.to_record(),
464
+ "calibration_source": self.calibration_source,
465
+ "favorable_assertion": self.favorable_assertion,
466
+ "adverse_assertion": self.adverse_assertion,
467
+ "signed_exploitation_score_hex": (
468
+ self.signed_exploitation_score.hex()
469
+ ),
470
+ "posterior_uncertainty_score_hex": (
471
+ self.posterior_uncertainty_score.hex()
472
+ ),
473
+ "calibrated_disagreement_score_hex": (
474
+ self.calibrated_disagreement_score.hex()
475
+ ),
476
+ "epistemic_score_hex": self.epistemic_score.hex(),
477
+ "explicit_abstention": self.explicit_abstention,
478
+ }
479
+
480
+
481
+ @dataclass(frozen=True, slots=True)
482
+ class StructuralPosteriorMemberScoreRow:
483
+ """All prior-only role scores for one member of the current slate."""
484
+
485
+ option_id: str
486
+ option_identity_sha256: str
487
+ model_rank: int
488
+ metric_scores: tuple[StructuralPosteriorMetricScoreRow, ...]
489
+ calibrated_exploitation_score: float
490
+ calibrated_frontier_score: float
491
+ raw_epistemic_score: float
492
+ structural_coverage_score: float
493
+ epistemic_structural_score: float
494
+ model_declared_assigned_card_keys: tuple[str, ...]
495
+
496
+ def __post_init__(self) -> None:
497
+ if type(self.option_id) is not str or not self.option_id:
498
+ raise ValueError("option_id must be a non-empty string")
499
+ require_sha256(self.option_identity_sha256, "option_identity_sha256")
500
+ if type(self.model_rank) is not int or self.model_rank <= 0:
501
+ raise ValueError("model_rank must be a positive exact integer")
502
+ if type(self.metric_scores) is not tuple or not self.metric_scores or any(
503
+ type(value) is not StructuralPosteriorMetricScoreRow
504
+ for value in self.metric_scores
505
+ ):
506
+ raise ValueError("metric_scores must contain exact score rows")
507
+ for value in self.metric_scores:
508
+ value.__post_init__()
509
+ metric_ids = tuple(value.metric_id for value in self.metric_scores)
510
+ if metric_ids != tuple(sorted(set(metric_ids))):
511
+ raise ValueError("metric_scores must use canonical unique metric order")
512
+ for name in (
513
+ "calibrated_exploitation_score",
514
+ "calibrated_frontier_score",
515
+ ):
516
+ _require_finite(getattr(self, name), name=name)
517
+ for name in (
518
+ "raw_epistemic_score",
519
+ "structural_coverage_score",
520
+ "epistemic_structural_score",
521
+ ):
522
+ _require_unit_interval(getattr(self, name), name=name)
523
+ if self.epistemic_structural_score != (
524
+ self.raw_epistemic_score * self.structural_coverage_score
525
+ ):
526
+ raise ValueError("epistemic-structural score differs from fixed coupling")
527
+ _require_canonical_strings(
528
+ self.model_declared_assigned_card_keys,
529
+ name="model_declared_assigned_card_keys",
530
+ )
531
+
532
+ def score_for(self, role: StructuralPosteriorSlateRole) -> float:
533
+ self.__post_init__()
534
+ if role is StructuralPosteriorSlateRole.CALIBRATED_EXPLOIT:
535
+ return self.calibrated_exploitation_score
536
+ if role is StructuralPosteriorSlateRole.CALIBRATED_FRONTIER:
537
+ return self.calibrated_frontier_score
538
+ if role is StructuralPosteriorSlateRole.EPISTEMIC_STRUCTURAL:
539
+ return self.epistemic_structural_score
540
+ if role is StructuralPosteriorSlateRole.STRUCTURAL_COVERAGE:
541
+ return self.structural_coverage_score
542
+ raise TypeError("role must be exact StructuralPosteriorSlateRole")
543
+
544
+ def to_record(self) -> dict[str, object]:
545
+ self.__post_init__()
546
+ return {
547
+ "option_id": self.option_id,
548
+ "option_identity_sha256": self.option_identity_sha256,
549
+ "model_rank": self.model_rank,
550
+ "metric_scores": [value.to_record() for value in self.metric_scores],
551
+ "calibrated_exploitation_score_hex": (
552
+ self.calibrated_exploitation_score.hex()
553
+ ),
554
+ "calibrated_frontier_score_hex": (
555
+ self.calibrated_frontier_score.hex()
556
+ ),
557
+ "raw_epistemic_score_hex": self.raw_epistemic_score.hex(),
558
+ "structural_coverage_score_hex": (
559
+ self.structural_coverage_score.hex()
560
+ ),
561
+ "epistemic_structural_score_hex": (
562
+ self.epistemic_structural_score.hex()
563
+ ),
564
+ "model_declared_assigned_card_keys": list(
565
+ self.model_declared_assigned_card_keys
566
+ ),
567
+ }
568
+
569
+
570
+ @dataclass(frozen=True, slots=True)
571
+ class StructuralPosteriorAllocatedMember:
572
+ """One selected member with its engine-owned role and score."""
573
+
574
+ role: StructuralPosteriorSlateRole
575
+ option_id: str
576
+ option_identity_sha256: str
577
+ model_rank: int
578
+ role_score: float
579
+
580
+ def __post_init__(self) -> None:
581
+ if type(self.role) is not StructuralPosteriorSlateRole:
582
+ raise TypeError("role must be exact StructuralPosteriorSlateRole")
583
+ if type(self.option_id) is not str or not self.option_id:
584
+ raise ValueError("option_id must be a non-empty string")
585
+ require_sha256(self.option_identity_sha256, "option_identity_sha256")
586
+ if type(self.model_rank) is not int or self.model_rank <= 0:
587
+ raise ValueError("model_rank must be a positive exact integer")
588
+ _require_finite(self.role_score, name="role_score")
589
+
590
+ def to_record(self) -> dict[str, object]:
591
+ self.__post_init__()
592
+ return {
593
+ "role": self.role.value,
594
+ "option_id": self.option_id,
595
+ "option_identity_sha256": self.option_identity_sha256,
596
+ "model_rank": self.model_rank,
597
+ "role_score_hex": self.role_score.hex(),
598
+ }
599
+
600
+
601
+ @dataclass(frozen=True, slots=True)
602
+ class _StructuralPosteriorAssignment:
603
+ selected: tuple[StructuralPosteriorAllocatedMember, ...]
604
+ joint_score: float
605
+ diversity_score: float
606
+ distinct_family_count: int
607
+ distinct_locus_count: int
608
+ distinct_phenotype_count: int
609
+ administered_card_keys: tuple[str, ...]
610
+ feasible_role_assignment_count: int
611
+ memory_dose_assessment: PortfolioMemoryDoseAssessment | None
612
+ family_exposure_violation_count: int
613
+
614
+
615
+ def _favorable(
616
+ direction: MetricEffectDirection,
617
+ goal: MetricOptimizationGoal,
618
+ ) -> tuple[bool, bool]:
619
+ if direction in {MetricEffectDirection.UNKNOWN, MetricEffectDirection.UNCHANGED}:
620
+ return False, False
621
+ favorable = (
622
+ goal is MetricOptimizationGoal.MINIMIZE
623
+ and direction is MetricEffectDirection.DECREASE
624
+ ) or (
625
+ goal is MetricOptimizationGoal.MAXIMIZE
626
+ and direction is MetricEffectDirection.INCREASE
627
+ )
628
+ return favorable, not favorable
629
+
630
+
631
+ def _score_member(
632
+ request: SlateAllocationRequest,
633
+ member: CalibratedSlateMember,
634
+ ) -> StructuralPosteriorMemberScoreRow:
635
+ snapshot = request.calibration_snapshot
636
+ if snapshot is None:
637
+ raise ValueError("structural-posterior policy requires a calibration snapshot")
638
+ objective_by_metric = {value.metric_id: value for value in request.objectives}
639
+ metric_scores: list[StructuralPosteriorMetricScoreRow] = []
640
+ weighted_exploitation = 0.0
641
+ weighted_epistemic = 0.0
642
+ total_weight = sum(value.weight for value in request.objectives)
643
+ for prediction in member.predictions:
644
+ objective = objective_by_metric[prediction.metric_id]
645
+ cell, source = snapshot.lookup(
646
+ metric_id=prediction.metric_id,
647
+ asserted_direction=prediction.asserted_direction,
648
+ confidence=prediction.confidence,
649
+ family=member.family,
650
+ )
651
+ probability = cell.posterior_correctness
652
+ favorable, adverse = _favorable(
653
+ prediction.asserted_direction,
654
+ objective.goal,
655
+ )
656
+ # Posterior correctness is a probability that the asserted direction
657
+ # is right, not a non-negative confidence multiplier. A model family
658
+ # below chance is useful negative evidence: its favorable assertion
659
+ # has negative expected utility and its adverse assertion has positive
660
+ # expected utility. This is the key distinction between calibration
661
+ # and merely shrinking an unreliable model toward zero.
662
+ signed_exploitation = (
663
+ (2.0 * probability) - 1.0
664
+ if favorable
665
+ else 1.0 - (2.0 * probability)
666
+ if adverse
667
+ else 0.0
668
+ )
669
+ posterior_uncertainty = 1.0 - abs((2.0 * probability) - 1.0)
670
+ calibrated_disagreement = max(0.0, 0.5 - probability) * 2.0
671
+ explicit_abstention = (
672
+ prediction.asserted_direction is MetricEffectDirection.UNKNOWN
673
+ )
674
+ epistemic = (
675
+ 1.0
676
+ if explicit_abstention
677
+ else (posterior_uncertainty + calibrated_disagreement) / 2.0
678
+ )
679
+ weighted_exploitation += objective.weight * signed_exploitation
680
+ weighted_epistemic += objective.weight * epistemic
681
+ metric_scores.append(
682
+ StructuralPosteriorMetricScoreRow(
683
+ metric_id=prediction.metric_id,
684
+ goal=objective.goal,
685
+ asserted_direction=prediction.asserted_direction,
686
+ confidence=prediction.confidence,
687
+ weight=objective.weight,
688
+ calibration_cell=cell,
689
+ calibration_source=source,
690
+ favorable_assertion=favorable,
691
+ adverse_assertion=adverse,
692
+ signed_exploitation_score=signed_exploitation,
693
+ posterior_uncertainty_score=posterior_uncertainty,
694
+ calibrated_disagreement_score=calibrated_disagreement,
695
+ epistemic_score=epistemic,
696
+ explicit_abstention=explicit_abstention,
697
+ )
698
+ )
699
+ exploitation = weighted_exploitation / total_weight
700
+ raw_epistemic = weighted_epistemic / total_weight
701
+ declared_cards = tuple(
702
+ card
703
+ for card in request.assigned_card_keys
704
+ if card in member.supporting_card_keys
705
+ )
706
+ structural = (
707
+ member.structural_evidence.archive_novelty_score
708
+ + member.structural_evidence.structural_coverage_score
709
+ ) / 2.0
710
+ return StructuralPosteriorMemberScoreRow(
711
+ option_id=member.option_id,
712
+ option_identity_sha256=member.option_identity_sha256,
713
+ model_rank=member.model_rank,
714
+ metric_scores=tuple(metric_scores),
715
+ calibrated_exploitation_score=exploitation,
716
+ calibrated_frontier_score=(
717
+ exploitation + (_FRONTIER_STRUCTURAL_WEIGHT * structural)
718
+ ),
719
+ raw_epistemic_score=raw_epistemic,
720
+ structural_coverage_score=structural,
721
+ epistemic_structural_score=raw_epistemic * structural,
722
+ model_declared_assigned_card_keys=declared_cards,
723
+ )
724
+
725
+
726
+ def score_structural_posterior_slate(
727
+ request: SlateAllocationRequest,
728
+ ) -> tuple[StructuralPosteriorMemberScoreRow, ...]:
729
+ """Project prior-only calibrated structural evidence without allocating.
730
+
731
+ This is the stable projection boundary for downstream acquisition policies.
732
+ It deliberately returns score evidence for the complete sealed slate; it
733
+ does not choose evaluator exposures or consult any candidate outcome.
734
+ """
735
+
736
+ if type(request) is not SlateAllocationRequest:
737
+ raise TypeError("request must be exact SlateAllocationRequest")
738
+ request.revalidate()
739
+ return tuple(_score_member(request, member) for member in request.slate.members)
740
+
741
+
742
+ def _best_assignment(
743
+ request: SlateAllocationRequest,
744
+ score_rows: tuple[StructuralPosteriorMemberScoreRow, ...],
745
+ *,
746
+ required_family_minimums: tuple[tuple[str, int], ...] = (),
747
+ required_family_bounds: tuple[FamilyExposureBound, ...] = (),
748
+ minimize_family_bound_violation: bool = False,
749
+ ) -> _StructuralPosteriorAssignment:
750
+ if required_family_minimums and required_family_bounds:
751
+ raise ValueError("family minima and family bounds are mutually exclusive")
752
+ if required_family_minimums:
753
+ _validate_required_family_minimums(required_family_minimums)
754
+ if required_family_bounds:
755
+ FamilyExposurePhase(0, required_family_bounds).__post_init__()
756
+ if minimize_family_bound_violation and not required_family_bounds:
757
+ raise ValueError("family-bound recourse requires explicit family bounds")
758
+ member_by_id = {value.option_id: value for value in request.slate.members}
759
+ required_option_ids = set(request.required_option_ids)
760
+ allowed_pairs = (
761
+ None
762
+ if request.pairwise_disjoint_option_id_pairs is None
763
+ else {frozenset(value) for value in request.pairwise_disjoint_option_id_pairs}
764
+ )
765
+ memory_dose_by_subset: dict[
766
+ tuple[str, ...], PortfolioMemoryDoseAssessment | None
767
+ ] = {}
768
+ feasible: list[
769
+ tuple[
770
+ tuple[object, ...],
771
+ tuple[StructuralPosteriorMemberScoreRow, ...],
772
+ tuple[float, ...],
773
+ float,
774
+ float,
775
+ int,
776
+ int,
777
+ int,
778
+ tuple[str, ...],
779
+ PortfolioMemoryDoseAssessment | None,
780
+ ]
781
+ ] = []
782
+ for rows in permutations(score_rows, _PORTFOLIO_SIZE):
783
+ if not required_option_ids.issubset(
784
+ {row.option_id for row in rows}
785
+ ):
786
+ continue
787
+ if allowed_pairs is not None and any(
788
+ frozenset((left.option_id, right.option_id)) not in allowed_pairs
789
+ for left_index, left in enumerate(rows)
790
+ for right in rows[left_index + 1 :]
791
+ ):
792
+ continue
793
+ members = tuple(member_by_id[row.option_id] for row in rows)
794
+ family_count = len({value.family for value in members})
795
+ family_exposure_violation = sum(
796
+ max(
797
+ bound.minimum_evaluations
798
+ - sum(value.family == bound.family for value in members),
799
+ 0,
800
+ sum(value.family == bound.family for value in members)
801
+ - bound.maximum_evaluations,
802
+ )
803
+ for bound in required_family_bounds
804
+ )
805
+ if (
806
+ request.min_distinct_families is not None
807
+ and family_count < request.min_distinct_families
808
+ ):
809
+ continue
810
+ if any(
811
+ sum(value.family == family for value in members) < minimum
812
+ for family, minimum in required_family_minimums
813
+ ):
814
+ continue
815
+ if family_exposure_violation and not minimize_family_bound_violation:
816
+ continue
817
+ if (
818
+ request.memory_dose_contract is not None
819
+ and not rows[1].model_declared_assigned_card_keys
820
+ ):
821
+ continue
822
+ administered = (
823
+ ()
824
+ if request.memory_dose_contract is None
825
+ else tuple(
826
+ sorted(
827
+ {
828
+ card
829
+ for row in rows
830
+ for card in row.model_declared_assigned_card_keys
831
+ }
832
+ )
833
+ )
834
+ )
835
+ if (
836
+ request.memory_dose_contract is not None
837
+ and administered != request.assigned_card_keys
838
+ ):
839
+ continue
840
+ subset_key = tuple(sorted(row.option_id for row in rows))
841
+ if subset_key not in memory_dose_by_subset:
842
+ canonical_members = tuple(
843
+ member_by_id[option_id] for option_id in subset_key
844
+ )
845
+ memory_dose_by_subset[subset_key] = (
846
+ None
847
+ if request.memory_dose_contract is None
848
+ else assess_allocated_slate_memory_dose(
849
+ request,
850
+ canonical_members,
851
+ )
852
+ )
853
+ dose_assessment = memory_dose_by_subset[subset_key]
854
+ if dose_assessment is not None and not dose_assessment.passed:
855
+ continue
856
+ locus_count = len({value.locus_key for value in members})
857
+ phenotype_count = len(
858
+ {value.phenotype_identity_sha256 for value in members}
859
+ )
860
+ diversity = (
861
+ family_count + locus_count + phenotype_count
862
+ ) / (3.0 * _PORTFOLIO_SIZE)
863
+ role_scores = tuple(row.score_for(role) for role, row in zip(_ROLES, rows))
864
+ joint_score = sum(role_scores) + (_DIVERSITY_WEIGHT * diversity)
865
+ tie_key: tuple[object, ...] = (
866
+ *((family_exposure_violation,) if minimize_family_bound_violation else ()),
867
+ -joint_score,
868
+ *(-value for value in role_scores),
869
+ tuple(value.model_rank for value in rows),
870
+ tuple(value.option_id for value in rows),
871
+ )
872
+ feasible.append(
873
+ (
874
+ tie_key,
875
+ rows,
876
+ role_scores,
877
+ joint_score,
878
+ diversity,
879
+ family_count,
880
+ locus_count,
881
+ phenotype_count,
882
+ administered,
883
+ dose_assessment,
884
+ )
885
+ )
886
+ if not feasible:
887
+ raise ValueError(
888
+ "slate has no feasible calibrated four-role assignment"
889
+ )
890
+ (
891
+ _,
892
+ rows,
893
+ role_scores,
894
+ joint_score,
895
+ diversity,
896
+ family_count,
897
+ locus_count,
898
+ phenotype_count,
899
+ administered,
900
+ dose_assessment,
901
+ ) = min(feasible, key=lambda value: value[0])
902
+ # Feasibility is invariant to member order and is therefore cached by
903
+ # unordered subset above. The durable dose receipt is not: its member
904
+ # bindings include the final rank. Reissue that receipt over the exact
905
+ # four-role order that will cross the decision trust boundary.
906
+ if request.memory_dose_contract is not None:
907
+ dose_assessment = assess_allocated_slate_memory_dose(
908
+ request,
909
+ tuple(member_by_id[row.option_id] for row in rows),
910
+ )
911
+ if not dose_assessment.passed: # Defensive after subset feasibility.
912
+ raise RuntimeError(
913
+ "winning structural-posterior assignment violated memory dose"
914
+ )
915
+ selected = tuple(
916
+ StructuralPosteriorAllocatedMember(
917
+ role=role,
918
+ option_id=row.option_id,
919
+ option_identity_sha256=row.option_identity_sha256,
920
+ model_rank=row.model_rank,
921
+ role_score=score,
922
+ )
923
+ for role, row, score in zip(_ROLES, rows, role_scores)
924
+ )
925
+ return _StructuralPosteriorAssignment(
926
+ selected=selected,
927
+ joint_score=joint_score,
928
+ diversity_score=diversity,
929
+ distinct_family_count=family_count,
930
+ distinct_locus_count=locus_count,
931
+ distinct_phenotype_count=phenotype_count,
932
+ administered_card_keys=administered,
933
+ feasible_role_assignment_count=len(feasible),
934
+ memory_dose_assessment=dose_assessment,
935
+ family_exposure_violation_count=(
936
+ sum(
937
+ max(
938
+ bound.minimum_evaluations
939
+ - sum(
940
+ member_by_id[row.option_id].family == bound.family
941
+ for row in rows
942
+ ),
943
+ 0,
944
+ sum(
945
+ member_by_id[row.option_id].family == bound.family
946
+ for row in rows
947
+ )
948
+ - bound.maximum_evaluations,
949
+ )
950
+ for bound in required_family_bounds
951
+ )
952
+ ),
953
+ )
954
+
955
+
956
+ def _validate_request(request: SlateAllocationRequest) -> None:
957
+ if len(request.slate.members) != _SLATE_SIZE:
958
+ raise ValueError("structural-posterior policy requires exactly eight members")
959
+ if request.portfolio_size != _PORTFOLIO_SIZE:
960
+ raise ValueError("structural-posterior policy requires four evaluations")
961
+ snapshot = request.calibration_snapshot
962
+ if snapshot is None:
963
+ raise ValueError("structural-posterior policy requires a calibration snapshot")
964
+ if snapshot.cutoff_wave_index_exclusive > request.slate.wave_index:
965
+ raise ValueError("calibration snapshot cutoff reaches beyond current wave")
966
+ if any(
967
+ value.prediction.wave_index >= request.slate.wave_index
968
+ for value in snapshot.observations
969
+ ):
970
+ raise ValueError("calibration snapshot contains current-wave outcome evidence")
971
+
972
+
973
+ def _validate_structural_decision(
974
+ value: Any,
975
+ *,
976
+ required_family_minimums: tuple[tuple[str, int], ...] = (),
977
+ required_family_bounds: tuple[FamilyExposureBound, ...] = (),
978
+ minimize_family_bound_violation: bool = False,
979
+ ) -> _StructuralPosteriorAssignment:
980
+ if required_family_minimums and required_family_bounds:
981
+ raise ValueError("family minima and family bounds are mutually exclusive")
982
+ if required_family_minimums:
983
+ _validate_required_family_minimums(required_family_minimums)
984
+ if required_family_bounds:
985
+ FamilyExposurePhase(0, required_family_bounds).__post_init__()
986
+ if type(value.request) is not SlateAllocationRequest:
987
+ raise TypeError("request must be exact SlateAllocationRequest")
988
+ value.request.revalidate()
989
+ _validate_request(value.request)
990
+ if type(value.score_rows) is not tuple or any(
991
+ type(row) is not StructuralPosteriorMemberScoreRow
992
+ for row in value.score_rows
993
+ ):
994
+ raise TypeError("score_rows must contain exact member score rows")
995
+ for row in value.score_rows:
996
+ row.__post_init__()
997
+ if type(value.selected) is not tuple or any(
998
+ type(row) is not StructuralPosteriorAllocatedMember
999
+ for row in value.selected
1000
+ ):
1001
+ raise TypeError("selected must contain exact allocated members")
1002
+ for row in value.selected:
1003
+ row.__post_init__()
1004
+ if value.memory_dose_assessment is not None:
1005
+ if type(value.memory_dose_assessment) is not PortfolioMemoryDoseAssessment:
1006
+ raise TypeError("memory_dose_assessment must be exact or None")
1007
+ value.memory_dose_assessment.__post_init__()
1008
+ expected_rows = tuple(
1009
+ _score_member(value.request, member)
1010
+ for member in value.request.slate.members
1011
+ )
1012
+ if value.score_rows != expected_rows:
1013
+ raise ValueError("score rows differ from sealed prior evidence")
1014
+ expected = _best_assignment(
1015
+ value.request,
1016
+ expected_rows,
1017
+ required_family_minimums=required_family_minimums,
1018
+ required_family_bounds=required_family_bounds,
1019
+ minimize_family_bound_violation=minimize_family_bound_violation,
1020
+ )
1021
+ observed_values = (
1022
+ value.selected,
1023
+ value.joint_score,
1024
+ value.diversity_score,
1025
+ value.distinct_family_count,
1026
+ value.distinct_locus_count,
1027
+ value.distinct_phenotype_count,
1028
+ value.administered_card_keys,
1029
+ value.feasible_role_assignment_count,
1030
+ value.memory_dose_assessment,
1031
+ )
1032
+ expected_values = (
1033
+ expected.selected,
1034
+ expected.joint_score,
1035
+ expected.diversity_score,
1036
+ expected.distinct_family_count,
1037
+ expected.distinct_locus_count,
1038
+ expected.distinct_phenotype_count,
1039
+ expected.administered_card_keys,
1040
+ expected.feasible_role_assignment_count,
1041
+ expected.memory_dose_assessment,
1042
+ )
1043
+ if observed_values != expected_values:
1044
+ raise ValueError("decision differs from exact structural-posterior allocation")
1045
+ return expected
1046
+
1047
+
1048
+ @dataclass(frozen=True, slots=True, eq=False)
1049
+ class StructuralPosteriorSlateDecision:
1050
+ """Replayable receipt for one outcome-blind structural-posterior decision."""
1051
+
1052
+ request: SlateAllocationRequest
1053
+ score_rows: tuple[StructuralPosteriorMemberScoreRow, ...]
1054
+ selected: tuple[StructuralPosteriorAllocatedMember, ...]
1055
+ joint_score: float
1056
+ diversity_score: float
1057
+ distinct_family_count: int
1058
+ distinct_locus_count: int
1059
+ distinct_phenotype_count: int
1060
+ administered_card_keys: tuple[str, ...]
1061
+ feasible_role_assignment_count: int
1062
+ memory_dose_assessment: PortfolioMemoryDoseAssessment | None = None
1063
+
1064
+ policy_id: ClassVar[str] = POLICY_ID
1065
+ policy_version: ClassVar[int] = POLICY_VERSION
1066
+ policy_definition_sha256: ClassVar[str] = POLICY_DEFINITION_SHA256
1067
+
1068
+ def __post_init__(self) -> None:
1069
+ _validate_structural_decision(self)
1070
+
1071
+ def revalidate(self) -> None:
1072
+ if type(self) is not StructuralPosteriorSlateDecision:
1073
+ raise TypeError("decision must be exact StructuralPosteriorSlateDecision")
1074
+ StructuralPosteriorSlateDecision.__post_init__(self)
1075
+
1076
+ @property
1077
+ def prior_only(self) -> bool:
1078
+ self.revalidate()
1079
+ snapshot = self.request.calibration_snapshot
1080
+ assert snapshot is not None
1081
+ return all(
1082
+ value.prediction.wave_index < self.request.slate.wave_index
1083
+ for value in snapshot.observations
1084
+ )
1085
+
1086
+ def _unsigned_record(self) -> dict[str, object]:
1087
+ self.revalidate()
1088
+ return {
1089
+ "schema_version": 1,
1090
+ "event_type": "structural_posterior_four_role_slate_allocated",
1091
+ "policy_id": self.policy_id,
1092
+ "policy_version": self.policy_version,
1093
+ "policy_definition_sha256": self.policy_definition_sha256,
1094
+ "request": self.request.to_record(),
1095
+ "request_sha256": self.request.request_sha256,
1096
+ "calibration_snapshot_sha256": (
1097
+ self.request.calibration_snapshot.snapshot_sha256
1098
+ if self.request.calibration_snapshot is not None
1099
+ else None
1100
+ ),
1101
+ "prior_only": self.prior_only,
1102
+ "roles": [value.value for value in _ROLES],
1103
+ "score_rows": [value.to_record() for value in self.score_rows],
1104
+ "selected": [value.to_record() for value in self.selected],
1105
+ "joint_score_hex": self.joint_score.hex(),
1106
+ "diversity_score_hex": self.diversity_score.hex(),
1107
+ "distinct_family_count": self.distinct_family_count,
1108
+ "distinct_locus_count": self.distinct_locus_count,
1109
+ "distinct_phenotype_count": self.distinct_phenotype_count,
1110
+ "administered_card_keys": list(self.administered_card_keys),
1111
+ "feasible_role_assignment_count": self.feasible_role_assignment_count,
1112
+ **(
1113
+ {}
1114
+ if self.memory_dose_assessment is None
1115
+ else {
1116
+ "memory_dose_assessment": self.memory_dose_assessment.to_record()
1117
+ }
1118
+ ),
1119
+ "claim_scope": (
1120
+ "replayable_prior_only_allocation_not_efficacy_or_outcome_claim"
1121
+ ),
1122
+ }
1123
+
1124
+ @property
1125
+ def decision_sha256(self) -> str:
1126
+ return _hash(_DECISION_DOMAIN, self._unsigned_record())
1127
+
1128
+ def to_record(self) -> dict[str, object]:
1129
+ return {
1130
+ **self._unsigned_record(),
1131
+ "decision_sha256": self.decision_sha256,
1132
+ }
1133
+
1134
+ def __eq__(self, other: object) -> bool:
1135
+ return (
1136
+ type(other) is StructuralPosteriorSlateDecision
1137
+ and self.decision_sha256 == other.decision_sha256
1138
+ )
1139
+
1140
+ __hash__ = None
1141
+
1142
+
1143
+ @dataclass(frozen=True, slots=True, eq=False)
1144
+ class OperatorStratifiedStructuralPosteriorSlateDecision(
1145
+ StructuralPosteriorSlateDecision
1146
+ ):
1147
+ """Structural-posterior decision with authenticated assay minima."""
1148
+
1149
+ required_family_minimums: tuple[tuple[str, int], ...] = (
1150
+ (COMPOSITE_OPTION_FAMILY, 1),
1151
+ )
1152
+
1153
+ policy_id: ClassVar[str] = OPERATOR_STRATIFIED_POLICY_ID
1154
+ policy_version: ClassVar[int] = OPERATOR_STRATIFIED_POLICY_VERSION
1155
+ policy_definition_sha256: ClassVar[str] = (
1156
+ OPERATOR_STRATIFIED_POLICY_DEFINITION_SHA256
1157
+ )
1158
+
1159
+ def __post_init__(self) -> None:
1160
+ if type(self) is not OperatorStratifiedStructuralPosteriorSlateDecision:
1161
+ raise TypeError("decision must be exact operator-stratified decision")
1162
+ _validate_required_family_minimums(self.required_family_minimums)
1163
+ _validate_structural_decision(
1164
+ self,
1165
+ required_family_minimums=self.required_family_minimums,
1166
+ )
1167
+
1168
+ def revalidate(self) -> None:
1169
+ if type(self) is not OperatorStratifiedStructuralPosteriorSlateDecision:
1170
+ raise TypeError("decision must be exact operator-stratified decision")
1171
+ OperatorStratifiedStructuralPosteriorSlateDecision.__post_init__(self)
1172
+
1173
+ def _unsigned_record(self) -> dict[str, object]:
1174
+ record = StructuralPosteriorSlateDecision._unsigned_record(self)
1175
+ return {
1176
+ **record,
1177
+ "schema_version": 2,
1178
+ "event_type": "operator_stratified_structural_posterior_allocated",
1179
+ "operator_stratification": {
1180
+ "required_family_minimums": [
1181
+ {"family": family, "minimum_evaluations": minimum}
1182
+ for family, minimum in self.required_family_minimums
1183
+ ],
1184
+ "semantics": "assay_exposure_not_quality_prior",
1185
+ "outcomes_consulted": False,
1186
+ },
1187
+ }
1188
+
1189
+ @property
1190
+ def decision_sha256(self) -> str:
1191
+ return _hash(
1192
+ _OPERATOR_STRATIFIED_DECISION_DOMAIN,
1193
+ self._unsigned_record(),
1194
+ )
1195
+
1196
+ def __eq__(self, other: object) -> bool:
1197
+ return (
1198
+ type(other) is OperatorStratifiedStructuralPosteriorSlateDecision
1199
+ and self.decision_sha256 == other.decision_sha256
1200
+ )
1201
+
1202
+ __hash__ = None
1203
+
1204
+
1205
+ @dataclass(frozen=True, slots=True, eq=False)
1206
+ class HorizonBoundedStructuralPosteriorSlateDecision(
1207
+ StructuralPosteriorSlateDecision
1208
+ ):
1209
+ """Replayable allocation under an authenticated finite-horizon schedule."""
1210
+
1211
+ family_exposure_phases: tuple[FamilyExposurePhase, ...] = ()
1212
+ family_exposure_violation_count: int = 0
1213
+
1214
+ policy_id: ClassVar[str] = HORIZON_BOUNDED_POLICY_ID
1215
+ policy_version: ClassVar[int] = HORIZON_BOUNDED_POLICY_VERSION
1216
+ policy_definition_sha256: ClassVar[str] = (
1217
+ HORIZON_BOUNDED_POLICY_DEFINITION_SHA256
1218
+ )
1219
+
1220
+ def __post_init__(self) -> None:
1221
+ if type(self) is not HorizonBoundedStructuralPosteriorSlateDecision:
1222
+ raise TypeError("decision must be exact horizon-bounded decision")
1223
+ _validate_family_exposure_phases(self.family_exposure_phases)
1224
+ active = _active_family_exposure_phase(
1225
+ self.family_exposure_phases,
1226
+ wave_index=self.request.slate.wave_index,
1227
+ )
1228
+ expected = _validate_structural_decision(
1229
+ self,
1230
+ required_family_bounds=active.bounds,
1231
+ minimize_family_bound_violation=True,
1232
+ )
1233
+ if (
1234
+ type(self.family_exposure_violation_count) is not int
1235
+ or self.family_exposure_violation_count < 0
1236
+ ):
1237
+ raise ValueError(
1238
+ "family_exposure_violation_count must be a non-negative integer"
1239
+ )
1240
+ if self.family_exposure_violation_count != (
1241
+ expected.family_exposure_violation_count
1242
+ ):
1243
+ raise ValueError("family exposure recourse differs from exact replay")
1244
+
1245
+ def revalidate(self) -> None:
1246
+ if type(self) is not HorizonBoundedStructuralPosteriorSlateDecision:
1247
+ raise TypeError("decision must be exact horizon-bounded decision")
1248
+ HorizonBoundedStructuralPosteriorSlateDecision.__post_init__(self)
1249
+
1250
+ @property
1251
+ def active_exposure_phase(self) -> FamilyExposurePhase:
1252
+ self.revalidate()
1253
+ return _active_family_exposure_phase(
1254
+ self.family_exposure_phases,
1255
+ wave_index=self.request.slate.wave_index,
1256
+ )
1257
+
1258
+ @property
1259
+ def policy_configuration_sha256(self) -> str:
1260
+ self.revalidate()
1261
+ return _hash(
1262
+ _HORIZON_BOUNDED_CONFIGURATION_DOMAIN,
1263
+ _horizon_bounded_configuration_record(self.family_exposure_phases),
1264
+ )
1265
+
1266
+ def _unsigned_record(self) -> dict[str, object]:
1267
+ record = StructuralPosteriorSlateDecision._unsigned_record(self)
1268
+ active = self.active_exposure_phase
1269
+ family_by_id = {
1270
+ value.option_id: value.family for value in self.request.slate.members
1271
+ }
1272
+ applied_counts = {
1273
+ bound.family: sum(
1274
+ family_by_id[value.option_id] == bound.family
1275
+ for value in self.selected
1276
+ )
1277
+ for bound in active.bounds
1278
+ }
1279
+ return {
1280
+ **record,
1281
+ "schema_version": 3,
1282
+ "event_type": "horizon_bounded_structural_posterior_allocated",
1283
+ "policy_configuration_sha256": self.policy_configuration_sha256,
1284
+ "finite_horizon_exposure": {
1285
+ "family_exposure_phases": [
1286
+ value.to_record() for value in self.family_exposure_phases
1287
+ ],
1288
+ "active_phase": active.to_record(),
1289
+ "applied_family_counts": applied_counts,
1290
+ "family_exposure_violation_count": (
1291
+ self.family_exposure_violation_count
1292
+ ),
1293
+ "requested_bounds_satisfied": (
1294
+ self.family_exposure_violation_count == 0
1295
+ ),
1296
+ "structural_recourse": "minimum_l1_violation_then_role_score",
1297
+ "phase_authority": "sealed_wave_index",
1298
+ "semantics": "assay_exposure_not_quality_prior",
1299
+ "outcomes_consulted": False,
1300
+ },
1301
+ }
1302
+
1303
+ @property
1304
+ def decision_sha256(self) -> str:
1305
+ return _hash(
1306
+ _HORIZON_BOUNDED_DECISION_DOMAIN,
1307
+ self._unsigned_record(),
1308
+ )
1309
+
1310
+ def __eq__(self, other: object) -> bool:
1311
+ return (
1312
+ type(other) is HorizonBoundedStructuralPosteriorSlateDecision
1313
+ and self.decision_sha256 == other.decision_sha256
1314
+ )
1315
+
1316
+ __hash__ = None
1317
+
1318
+
1319
+ @dataclass(frozen=True, slots=True)
1320
+ class StructuralPosteriorSlatePolicy:
1321
+ """Allocate K8 to K4 by exact prior-only role assignment."""
1322
+
1323
+ policy_id: ClassVar[str] = POLICY_ID
1324
+ policy_version: ClassVar[int] = POLICY_VERSION
1325
+ definition_sha256: ClassVar[str] = POLICY_DEFINITION_SHA256
1326
+
1327
+ def __post_init__(self) -> None:
1328
+ # The v1 mechanism deliberately has no workload-tuned parameters.
1329
+ if type(self) is not StructuralPosteriorSlatePolicy:
1330
+ raise TypeError("policy must be exact StructuralPosteriorSlatePolicy")
1331
+
1332
+ @property
1333
+ def configuration_sha256(self) -> str:
1334
+ self.__post_init__()
1335
+ return _hash(_CONFIGURATION_DOMAIN, _configuration_record())
1336
+
1337
+ def select(
1338
+ self,
1339
+ request: SlateAllocationRequest,
1340
+ ) -> StructuralPosteriorSlateDecision:
1341
+ self.__post_init__()
1342
+ if type(request) is not SlateAllocationRequest:
1343
+ raise TypeError("request must be exact SlateAllocationRequest")
1344
+ request.revalidate()
1345
+ _validate_request(request)
1346
+ rows = tuple(_score_member(request, member) for member in request.slate.members)
1347
+ assignment = _best_assignment(request, rows)
1348
+ return StructuralPosteriorSlateDecision(
1349
+ request=request,
1350
+ score_rows=rows,
1351
+ selected=assignment.selected,
1352
+ joint_score=assignment.joint_score,
1353
+ diversity_score=assignment.diversity_score,
1354
+ distinct_family_count=assignment.distinct_family_count,
1355
+ distinct_locus_count=assignment.distinct_locus_count,
1356
+ distinct_phenotype_count=assignment.distinct_phenotype_count,
1357
+ administered_card_keys=assignment.administered_card_keys,
1358
+ feasible_role_assignment_count=(
1359
+ assignment.feasible_role_assignment_count
1360
+ ),
1361
+ memory_dose_assessment=assignment.memory_dose_assessment,
1362
+ )
1363
+
1364
+ def to_record(self) -> dict[str, object]:
1365
+ self.__post_init__()
1366
+ return {
1367
+ "policy_id": self.policy_id,
1368
+ "policy_version": self.policy_version,
1369
+ "definition_sha256": self.definition_sha256,
1370
+ "configuration": _configuration_record(),
1371
+ "configuration_sha256": self.configuration_sha256,
1372
+ }
1373
+
1374
+
1375
+ @dataclass(frozen=True, slots=True)
1376
+ class OperatorStratifiedStructuralPosteriorSlatePolicy:
1377
+ """Reserve evaluator assay exposure while preserving prior-only ranking."""
1378
+
1379
+ required_family_minimums: tuple[tuple[str, int], ...] = (
1380
+ (COMPOSITE_OPTION_FAMILY, 1),
1381
+ )
1382
+
1383
+ policy_id: ClassVar[str] = OPERATOR_STRATIFIED_POLICY_ID
1384
+ policy_version: ClassVar[int] = OPERATOR_STRATIFIED_POLICY_VERSION
1385
+ definition_sha256: ClassVar[str] = (
1386
+ OPERATOR_STRATIFIED_POLICY_DEFINITION_SHA256
1387
+ )
1388
+
1389
+ def __post_init__(self) -> None:
1390
+ if type(self) is not OperatorStratifiedStructuralPosteriorSlatePolicy:
1391
+ raise TypeError("policy must be exact operator-stratified policy")
1392
+ _validate_required_family_minimums(self.required_family_minimums)
1393
+
1394
+ @property
1395
+ def configuration_sha256(self) -> str:
1396
+ self.__post_init__()
1397
+ return _hash(
1398
+ _OPERATOR_STRATIFIED_CONFIGURATION_DOMAIN,
1399
+ self._configuration_record(),
1400
+ )
1401
+
1402
+ def _configuration_record(self) -> dict[str, object]:
1403
+ return {
1404
+ "schema_version": 1,
1405
+ "base_allocator": {
1406
+ "policy_id": POLICY_ID,
1407
+ "policy_version": POLICY_VERSION,
1408
+ "definition_sha256": POLICY_DEFINITION_SHA256,
1409
+ "configuration_sha256": _hash(
1410
+ _CONFIGURATION_DOMAIN,
1411
+ _configuration_record(),
1412
+ ),
1413
+ },
1414
+ "required_family_minimums": [
1415
+ {"family": family, "minimum_evaluations": minimum}
1416
+ for family, minimum in self.required_family_minimums
1417
+ ],
1418
+ "constraint_semantics": "assay_exposure_not_quality_prior",
1419
+ "outcomes_consulted": False,
1420
+ "benchmark_specific_parameters": [],
1421
+ }
1422
+
1423
+ def select(
1424
+ self,
1425
+ request: SlateAllocationRequest,
1426
+ ) -> OperatorStratifiedStructuralPosteriorSlateDecision:
1427
+ self.__post_init__()
1428
+ if type(request) is not SlateAllocationRequest:
1429
+ raise TypeError("request must be exact SlateAllocationRequest")
1430
+ request.revalidate()
1431
+ _validate_request(request)
1432
+ rows = tuple(_score_member(request, member) for member in request.slate.members)
1433
+ assignment = _best_assignment(
1434
+ request,
1435
+ rows,
1436
+ required_family_minimums=self.required_family_minimums,
1437
+ )
1438
+ return OperatorStratifiedStructuralPosteriorSlateDecision(
1439
+ request=request,
1440
+ score_rows=rows,
1441
+ selected=assignment.selected,
1442
+ joint_score=assignment.joint_score,
1443
+ diversity_score=assignment.diversity_score,
1444
+ distinct_family_count=assignment.distinct_family_count,
1445
+ distinct_locus_count=assignment.distinct_locus_count,
1446
+ distinct_phenotype_count=assignment.distinct_phenotype_count,
1447
+ administered_card_keys=assignment.administered_card_keys,
1448
+ feasible_role_assignment_count=(
1449
+ assignment.feasible_role_assignment_count
1450
+ ),
1451
+ memory_dose_assessment=assignment.memory_dose_assessment,
1452
+ required_family_minimums=self.required_family_minimums,
1453
+ )
1454
+
1455
+ def to_record(self) -> dict[str, object]:
1456
+ self.__post_init__()
1457
+ return {
1458
+ "policy_id": self.policy_id,
1459
+ "policy_version": self.policy_version,
1460
+ "definition_sha256": self.definition_sha256,
1461
+ "configuration": self._configuration_record(),
1462
+ "configuration_sha256": self.configuration_sha256,
1463
+ }
1464
+
1465
+
1466
+ @dataclass(frozen=True, slots=True)
1467
+ class HorizonBoundedStructuralPosteriorSlatePolicy:
1468
+ """Apply pre-registered action-family exposure bounds by campaign phase."""
1469
+
1470
+ family_exposure_phases: tuple[FamilyExposurePhase, ...]
1471
+
1472
+ policy_id: ClassVar[str] = HORIZON_BOUNDED_POLICY_ID
1473
+ policy_version: ClassVar[int] = HORIZON_BOUNDED_POLICY_VERSION
1474
+ definition_sha256: ClassVar[str] = HORIZON_BOUNDED_POLICY_DEFINITION_SHA256
1475
+
1476
+ def __post_init__(self) -> None:
1477
+ if type(self) is not HorizonBoundedStructuralPosteriorSlatePolicy:
1478
+ raise TypeError("policy must be exact horizon-bounded policy")
1479
+ _validate_family_exposure_phases(self.family_exposure_phases)
1480
+
1481
+ @property
1482
+ def configuration_sha256(self) -> str:
1483
+ self.__post_init__()
1484
+ return _hash(
1485
+ _HORIZON_BOUNDED_CONFIGURATION_DOMAIN,
1486
+ self._configuration_record(),
1487
+ )
1488
+
1489
+ def _configuration_record(self) -> dict[str, object]:
1490
+ return _horizon_bounded_configuration_record(self.family_exposure_phases)
1491
+
1492
+ def exposure_phase_for_wave(self, wave_index: int) -> FamilyExposurePhase:
1493
+ self.__post_init__()
1494
+ return _active_family_exposure_phase(
1495
+ self.family_exposure_phases,
1496
+ wave_index=wave_index,
1497
+ )
1498
+
1499
+ def select(
1500
+ self,
1501
+ request: SlateAllocationRequest,
1502
+ ) -> HorizonBoundedStructuralPosteriorSlateDecision:
1503
+ self.__post_init__()
1504
+ if type(request) is not SlateAllocationRequest:
1505
+ raise TypeError("request must be exact SlateAllocationRequest")
1506
+ request.revalidate()
1507
+ _validate_request(request)
1508
+ active = self.exposure_phase_for_wave(request.slate.wave_index)
1509
+ rows = tuple(_score_member(request, member) for member in request.slate.members)
1510
+ assignment = _best_assignment(
1511
+ request,
1512
+ rows,
1513
+ required_family_bounds=active.bounds,
1514
+ minimize_family_bound_violation=True,
1515
+ )
1516
+ return HorizonBoundedStructuralPosteriorSlateDecision(
1517
+ request=request,
1518
+ score_rows=rows,
1519
+ selected=assignment.selected,
1520
+ joint_score=assignment.joint_score,
1521
+ diversity_score=assignment.diversity_score,
1522
+ distinct_family_count=assignment.distinct_family_count,
1523
+ distinct_locus_count=assignment.distinct_locus_count,
1524
+ distinct_phenotype_count=assignment.distinct_phenotype_count,
1525
+ administered_card_keys=assignment.administered_card_keys,
1526
+ feasible_role_assignment_count=(
1527
+ assignment.feasible_role_assignment_count
1528
+ ),
1529
+ memory_dose_assessment=assignment.memory_dose_assessment,
1530
+ family_exposure_phases=self.family_exposure_phases,
1531
+ family_exposure_violation_count=(
1532
+ assignment.family_exposure_violation_count
1533
+ ),
1534
+ )
1535
+
1536
+ def to_record(self) -> dict[str, object]:
1537
+ self.__post_init__()
1538
+ return {
1539
+ "policy_id": self.policy_id,
1540
+ "policy_version": self.policy_version,
1541
+ "definition_sha256": self.definition_sha256,
1542
+ "configuration": self._configuration_record(),
1543
+ "configuration_sha256": self.configuration_sha256,
1544
+ }
1545
+
1546
+
1547
+ __all__ = [
1548
+ "FamilyExposureBound",
1549
+ "FamilyExposurePhase",
1550
+ "HORIZON_BOUNDED_POLICY_DEFINITION_SHA256",
1551
+ "HORIZON_BOUNDED_POLICY_ID",
1552
+ "HORIZON_BOUNDED_POLICY_VERSION",
1553
+ "HorizonBoundedStructuralPosteriorSlateDecision",
1554
+ "HorizonBoundedStructuralPosteriorSlatePolicy",
1555
+ "POLICY_DEFINITION_SHA256",
1556
+ "POLICY_ID",
1557
+ "POLICY_VERSION",
1558
+ "OPERATOR_STRATIFIED_POLICY_DEFINITION_SHA256",
1559
+ "OPERATOR_STRATIFIED_POLICY_ID",
1560
+ "OPERATOR_STRATIFIED_POLICY_VERSION",
1561
+ "OperatorStratifiedStructuralPosteriorSlateDecision",
1562
+ "OperatorStratifiedStructuralPosteriorSlatePolicy",
1563
+ "StructuralPosteriorAllocatedMember",
1564
+ "StructuralPosteriorMemberScoreRow",
1565
+ "StructuralPosteriorMetricScoreRow",
1566
+ "StructuralPosteriorSlateDecision",
1567
+ "StructuralPosteriorSlatePolicy",
1568
+ "StructuralPosteriorSlateRole",
1569
+ "build_controller_owned_family_exposure_phases",
1570
+ "build_terminal_tapered_family_exposure_phases",
1571
+ ]