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,316 @@
1
+ """Project a same-prefix forecast shadow into calibration evidence.
2
+
3
+ The projector joins only authenticated, already-observed records:
4
+
5
+ * the protected forecast-opportunity decision and its sealed raw score;
6
+ * the portable action descriptor used before evaluation; and
7
+ * the final same-prefix challenger-versus-fallback observation.
8
+
9
+ It does not inspect workload schemas, objective names, prompts, models, or
10
+ providers. The resulting observation can therefore enter the generic
11
+ prequential calibration memory without adding a workload integration method.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import hashlib
17
+ import json
18
+ import math
19
+ from dataclasses import dataclass, field
20
+
21
+ from agent_evolve.application.outcome_adaptive_action_racing import (
22
+ AdaptiveActionDescriptor,
23
+ AdaptiveActionRacingDecision,
24
+ )
25
+ from agent_evolve.application.prequential_archive_opportunity_calibration import (
26
+ ArchiveOpportunityActionContext,
27
+ ArchiveOpportunityCalibrationEvidenceRole,
28
+ ArchiveOpportunityCalibrationObservation,
29
+ ArchiveOpportunityCalibrationRequest,
30
+ )
31
+ from agent_evolve.application.same_prefix_paired_audit import (
32
+ FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS,
33
+ FORECAST_OPPORTUNITY_SAME_PREFIX_SHADOW_DESIGNER_ID,
34
+ FORECAST_STRATIFIED_SAME_PREFIX_AUDIT_DESIGNER_ID,
35
+ SamePrefixPairedAuditArm,
36
+ SamePrefixPairedAuditObservation,
37
+ )
38
+ from agent_evolve.domain.typed_json import thaw_json
39
+
40
+
41
+ FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID = (
42
+ "forecast_opportunity_shadow_calibration"
43
+ )
44
+ FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION = 2
45
+ _DEFINITION_DOMAIN = (
46
+ b"agent-evolve:forecast-opportunity-shadow-calibration-projector:v2\x00"
47
+ )
48
+
49
+
50
+ def _canonical_json(value: object) -> bytes:
51
+ return json.dumps(
52
+ value,
53
+ allow_nan=False,
54
+ ensure_ascii=True,
55
+ separators=(",", ":"),
56
+ sort_keys=True,
57
+ ).encode("ascii", errors="strict")
58
+
59
+
60
+ def _hash(domain: bytes, value: object) -> str:
61
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
62
+
63
+
64
+ def _read_nonnegative_hex(record: dict[str, object], key: str) -> float:
65
+ raw = record.get(key)
66
+ if type(raw) is not str:
67
+ raise TypeError(f"{key} must be an exact hexadecimal float")
68
+ try:
69
+ value = float.fromhex(raw)
70
+ except ValueError as error:
71
+ raise ValueError(f"{key} is not a hexadecimal float") from error
72
+ if not math.isfinite(value) or value < 0.0:
73
+ raise ValueError(f"{key} must be finite and non-negative")
74
+ return float(value)
75
+
76
+
77
+ @dataclass(frozen=True, slots=True)
78
+ class ForecastOpportunityShadowCalibrationProjector:
79
+ """Create one calibration target from a sealed same-prefix forecast arm."""
80
+
81
+ projector_id: str = (
82
+ FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID
83
+ )
84
+ projector_version: int = (
85
+ FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION
86
+ )
87
+ definition_sha256: str = field(init=False)
88
+
89
+ def __post_init__(self) -> None:
90
+ if (
91
+ self.projector_id
92
+ != FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID
93
+ or self.projector_version
94
+ != FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION
95
+ ):
96
+ raise ValueError("shadow calibration projector identity is immutable")
97
+ object.__setattr__(
98
+ self,
99
+ "definition_sha256",
100
+ _hash(
101
+ _DEFINITION_DOMAIN,
102
+ {
103
+ "schema_version": 1,
104
+ "projector_id": self.projector_id,
105
+ "projector_version": self.projector_version,
106
+ "forecast_source": (
107
+ "authenticated-protected-decision-raw-score"
108
+ ),
109
+ "target": (
110
+ "exact-forecast-arm-conditional-gain-at-identical-"
111
+ "prefix"
112
+ ),
113
+ "accepted_designers": sorted(
114
+ FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS
115
+ ),
116
+ "fallback_target_retained_in_paired_observation": True,
117
+ "paired_evidence_role_and_sampling_propensity_recorded": (
118
+ True
119
+ ),
120
+ "current_or_future_candidate_outcomes_used_for_forecast": (
121
+ False
122
+ ),
123
+ "workload_objective_model_provider_prompt_config_"
124
+ "branches": False,
125
+ },
126
+ ),
127
+ )
128
+
129
+ @staticmethod
130
+ def _score_record(
131
+ decision: AdaptiveActionRacingDecision,
132
+ action_sha256: str,
133
+ *,
134
+ require_recommended: bool,
135
+ ) -> dict[str, object]:
136
+ evidence = thaw_json(decision.evidence)
137
+ ranking = evidence.get("opportunity_ranking")
138
+ if type(ranking) is not dict:
139
+ raise TypeError("decision lacks an exact opportunity ranking")
140
+ recommended = ranking.get("recommended_action_sha256s")
141
+ scores = ranking.get("scores")
142
+ if (
143
+ type(recommended) is not list
144
+ or type(scores) is not list
145
+ ):
146
+ raise TypeError("decision opportunity ranking is incomplete")
147
+ if require_recommended and action_sha256 not in recommended:
148
+ raise ValueError(
149
+ "legacy shadow challenger is not a recommendation"
150
+ )
151
+ matches = [
152
+ value
153
+ for value in scores
154
+ if type(value) is dict
155
+ and value.get("action_sha256") == action_sha256
156
+ ]
157
+ if len(matches) != 1:
158
+ raise ValueError(
159
+ "opportunity ranking must expose one challenger score"
160
+ )
161
+ return matches[0]
162
+
163
+ def project(
164
+ self,
165
+ *,
166
+ decision_index: int,
167
+ evidence_cutoff_ordinal: int,
168
+ decision: AdaptiveActionRacingDecision,
169
+ action: AdaptiveActionDescriptor,
170
+ observation: SamePrefixPairedAuditObservation,
171
+ ) -> ArchiveOpportunityCalibrationObservation:
172
+ """Join the sealed raw score to the later real challenger outcome."""
173
+
174
+ self.__post_init__()
175
+ if type(decision_index) is not int or decision_index <= 0:
176
+ raise ValueError("decision_index must be positive")
177
+ if (
178
+ type(evidence_cutoff_ordinal) is not int
179
+ or evidence_cutoff_ordinal <= 0
180
+ ):
181
+ raise ValueError("evidence_cutoff_ordinal must be positive")
182
+ if type(decision) is not AdaptiveActionRacingDecision:
183
+ raise TypeError("decision must be exact")
184
+ if type(action) is not AdaptiveActionDescriptor:
185
+ raise TypeError("action must be exact")
186
+ if type(observation) is not SamePrefixPairedAuditObservation:
187
+ raise TypeError("observation must be exact")
188
+ decision.__post_init__()
189
+ action.__post_init__()
190
+ observation.__post_init__()
191
+ plan = observation.plan
192
+ if plan.designer_id not in (
193
+ FORECAST_OPPORTUNITY_SAME_PREFIX_AUDIT_DESIGNER_IDS
194
+ ):
195
+ raise ValueError("observation is not a forecast audit")
196
+ is_legacy_final_shadow = (
197
+ plan.designer_id
198
+ == FORECAST_OPPORTUNITY_SAME_PREFIX_SHADOW_DESIGNER_ID
199
+ )
200
+ if (
201
+ plan.racing_decision_sha256 != decision.decision_sha256
202
+ or plan.exploration_action_sha256 != action.action_sha256
203
+ or decision.selected_action_sha256s
204
+ != (plan.authoritative_action_sha256,)
205
+ or decision.prior_selected_action_sha256s
206
+ != plan.common_prefix_action_sha256s
207
+ or (
208
+ is_legacy_final_shadow
209
+ and plan.authoritative_arm
210
+ is not SamePrefixPairedAuditArm.EXPLORATION
211
+ )
212
+ or (
213
+ plan.designer_id
214
+ == FORECAST_STRATIFIED_SAME_PREFIX_AUDIT_DESIGNER_ID
215
+ and plan.authoritative_arm
216
+ not in {
217
+ SamePrefixPairedAuditArm.LEGACY,
218
+ SamePrefixPairedAuditArm.EXPLORATION,
219
+ }
220
+ )
221
+ ):
222
+ raise ValueError(
223
+ "decision, descriptor, and forecast shadow do not join"
224
+ )
225
+ score = self._score_record(
226
+ decision,
227
+ action.action_sha256,
228
+ require_recommended=is_legacy_final_shadow,
229
+ )
230
+ raw_acquisition_key = (
231
+ "raw_acquisition_value_hex"
232
+ if "raw_acquisition_value_hex" in score
233
+ else "acquisition_value_hex"
234
+ )
235
+ paired_role = (
236
+ ArchiveOpportunityCalibrationEvidenceRole
237
+ .SAME_PREFIX_PAIRED_AUTHORITATIVE
238
+ if plan.authoritative_arm
239
+ is SamePrefixPairedAuditArm.EXPLORATION
240
+ else (
241
+ ArchiveOpportunityCalibrationEvidenceRole
242
+ .SAME_PREFIX_PAIRED_COUNTERFACTUAL
243
+ )
244
+ )
245
+ return ArchiveOpportunityCalibrationObservation(
246
+ request=ArchiveOpportunityCalibrationRequest(
247
+ context=ArchiveOpportunityActionContext(
248
+ action_sha256=action.action_sha256,
249
+ decision_index=decision_index,
250
+ lane_id=action.lane_id,
251
+ operator_id=action.operator_id,
252
+ native_rank=action.native_rank,
253
+ lane_size=action.lane_size,
254
+ prior_score=action.prior_score,
255
+ parent_generated_in_current_run=(
256
+ action.parent_generated_in_current_run
257
+ ),
258
+ ),
259
+ forecast_reliability=_read_nonnegative_hex(
260
+ score,
261
+ "reliability_hex",
262
+ ),
263
+ raw_adverse_gain=_read_nonnegative_hex(
264
+ score,
265
+ "adverse_gain_hex",
266
+ ),
267
+ raw_central_gain=_read_nonnegative_hex(
268
+ score,
269
+ "central_gain_hex",
270
+ ),
271
+ raw_favorable_gain=_read_nonnegative_hex(
272
+ score,
273
+ "favorable_gain_hex",
274
+ ),
275
+ raw_acquisition_value=_read_nonnegative_hex(
276
+ score,
277
+ raw_acquisition_key,
278
+ ),
279
+ prefix_gain=float(
280
+ observation.exploration_set_outcome
281
+ .prior_selected_set_gain
282
+ ),
283
+ prefix_action_count=len(
284
+ plan.common_prefix_action_sha256s
285
+ ),
286
+ ),
287
+ realized_conditional_gain=float(
288
+ observation.exploration_set_outcome.conditional_set_gain
289
+ ),
290
+ decision_sha256=decision.decision_sha256,
291
+ outcome_sha256=observation.exploration_outcome.outcome_sha256,
292
+ evidence_cutoff_ordinal=evidence_cutoff_ordinal,
293
+ evidence_role=(
294
+ ArchiveOpportunityCalibrationEvidenceRole
295
+ .AUTHORITATIVE_SELECTED
296
+ if is_legacy_final_shadow
297
+ else paired_role
298
+ ),
299
+ sampling_propensity=(
300
+ 1.0
301
+ if is_legacy_final_shadow
302
+ else plan.exploration_selection_propensity
303
+ ),
304
+ paired_observation_sha256=(
305
+ None
306
+ if is_legacy_final_shadow
307
+ else observation.observation_sha256
308
+ ),
309
+ )
310
+
311
+
312
+ __all__ = [
313
+ "FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_ID",
314
+ "FORECAST_OPPORTUNITY_SHADOW_CALIBRATION_PROJECTOR_VERSION",
315
+ "ForecastOpportunityShadowCalibrationProjector",
316
+ ]
@@ -0,0 +1,311 @@
1
+ """Front-proximity admission: drop the market's dominated-parent tail.
2
+
3
+ A candidate's *parent anchor* is the objective point its action was derived
4
+ from. The anchor's Chebyshev excess over the current archive front measures
5
+ how deep inside the dominated interior that anchor sits: a value at or below
6
+ zero means the anchor is itself non-dominated, and larger values mean the
7
+ anchor is buried further behind the front.
8
+
9
+ On the jul28 sealed BOiLS held-out markets this quantity is the strongest
10
+ outcome-blind discriminator measured (pooled AUC 0.732 for individual
11
+ positivity, 8 of 8 markets at or above 0.50), and its worst band is
12
+ effectively empty: anchors more than 0.05 normalized units behind the front
13
+ hold 26% of the market mass, 1 of 88 positives and 1.6% of the realised
14
+ gain. This module turns that observation into a *support restriction* that
15
+ composes over any allocation policy: the wrapped policy still makes every
16
+ decision, it simply never sees the tail of the market that carries no
17
+ outcome mass.
18
+
19
+ The rule is deliberately RELATIVE — it keeps the market's own best
20
+ ``keep_fraction`` of anchors — so it introduces no absolute threshold, no
21
+ workload constant, no metric name and no scale assumption. Candidates whose
22
+ anchor is unknown are scored at the market's median anchor so an anchorless
23
+ lane is never systematically evicted or systematically protected.
24
+
25
+ The signal replicates: pooled AUC 0.700 on the five jul27 replay-corpus
26
+ markets that record parent anchors (0.583 to 0.767 per market), against
27
+ 0.732 on the eight held-out markets. What has NOT been shown is that any
28
+ deterministic policy built on it beats the ``lane_heads`` incumbent on four
29
+ sealed cells; the incumbent's own headline sits at the p = 0.08 tail of the
30
+ uniform null, so a four-cell single-run comparison cannot resolve it.
31
+
32
+ Claim boundary: replay-evaluation only. Nothing here carries live campaign
33
+ authority. See
34
+ ``research_artifacts/jul28_large_gain_anatomy_and_refinement.md``.
35
+ """
36
+
37
+ from __future__ import annotations
38
+
39
+ import hashlib
40
+ import json
41
+ import math
42
+ import re
43
+ from dataclasses import dataclass, field
44
+
45
+ from agent_evolve.application.calibrated_positive_gain_opportunity import (
46
+ ObjectivePoint,
47
+ chebyshev_excess,
48
+ non_dominated,
49
+ )
50
+ from agent_evolve.application.sequential_market_replay import (
51
+ MarketRecord,
52
+ ReplaySelection,
53
+ ReplayStepReceipt,
54
+ _corpus_action_sha256,
55
+ _normalized_point,
56
+ )
57
+ from agent_evolve.domain.patch import require_sha256
58
+
59
+ FRONT_PROXIMITY_ADMISSION_ID = "front_proximity_admission"
60
+ FRONT_PROXIMITY_ADMISSION_VERSION = 1
61
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
62
+ _DEFINITION_DOMAIN = b"agent-evolve:front-proximity-admission:v1\x00"
63
+
64
+
65
+ def _canonical_json(value: object) -> bytes:
66
+ return json.dumps(
67
+ value,
68
+ allow_nan=False,
69
+ ensure_ascii=True,
70
+ separators=(",", ":"),
71
+ sort_keys=True,
72
+ ).encode("ascii", errors="strict")
73
+
74
+
75
+ def _hash(value: object) -> str:
76
+ return hashlib.sha256(
77
+ _DEFINITION_DOMAIN + _canonical_json(value)
78
+ ).hexdigest()
79
+
80
+
81
+ # ``non_dominated`` and ``chebyshev_excess`` now live in the calibrated
82
+ # scorer, which consumes the same geometry directly; they are re-exported
83
+ # here unchanged so every existing import keeps resolving.
84
+
85
+
86
+ @dataclass(frozen=True, slots=True)
87
+ class FrontProximityAdmissionConfig:
88
+ """How much of the market's anchor distribution stays selectable."""
89
+
90
+ #: Fraction of the market's known anchors retained, best (smallest
91
+ #: Chebyshev excess) first. 1.0 disables the restriction entirely.
92
+ keep_fraction: float = 0.50
93
+ #: Never shrink the support below this many candidates, so a small
94
+ #: market can never be reduced to a single forced choice.
95
+ minimum_support: int = 2
96
+
97
+ def __post_init__(self) -> None:
98
+ if (
99
+ type(self.keep_fraction) is not float
100
+ or not math.isfinite(self.keep_fraction)
101
+ or not 0.0 < self.keep_fraction <= 1.0
102
+ ):
103
+ raise ValueError("keep_fraction must lie in (0, 1]")
104
+ if type(self.minimum_support) is not int or self.minimum_support < 1:
105
+ raise ValueError("minimum_support must be a positive integer")
106
+
107
+ def to_record(self) -> dict[str, object]:
108
+ return {
109
+ "keep_fraction_hex": float(self.keep_fraction).hex(),
110
+ "minimum_support": self.minimum_support,
111
+ }
112
+
113
+
114
+ @dataclass(frozen=True, slots=True)
115
+ class FrontProximityAdmission:
116
+ """Restrict a replay policy to the front-proximal part of its market.
117
+
118
+ ``anchors`` maps ``action_sha256`` to that candidate's parent objective
119
+ point in the market's own normalized metric frame. Candidates absent
120
+ from the map are scored at the median known excess.
121
+ """
122
+
123
+ inner: object
124
+ anchors: dict[str, ObjectivePoint]
125
+ config: FrontProximityAdmissionConfig = field(
126
+ default_factory=FrontProximityAdmissionConfig
127
+ )
128
+ policy_id: str = "replay_arm.front_proximity_admission"
129
+ definition_sha256: str = field(init=False)
130
+
131
+ def __post_init__(self) -> None:
132
+ if not hasattr(self.inner, "select"):
133
+ raise TypeError("inner must expose an exact select()")
134
+ if type(self.anchors) is not dict:
135
+ raise TypeError("anchors must be an exact mapping")
136
+ for action_sha256, point in self.anchors.items():
137
+ require_sha256(action_sha256, "anchors key")
138
+ if type(point) is not tuple or not point:
139
+ raise TypeError("anchor points must be exact tuples")
140
+ self.config.__post_init__()
141
+ if _TOKEN.fullmatch(self.policy_id) is None:
142
+ raise ValueError("policy_id must use the closed token grammar")
143
+ object.__setattr__(
144
+ self,
145
+ "definition_sha256",
146
+ _hash(
147
+ {
148
+ "arm": FRONT_PROXIMITY_ADMISSION_ID,
149
+ "version": FRONT_PROXIMITY_ADMISSION_VERSION,
150
+ "config": self.config.to_record(),
151
+ "inner_policy_id": str(
152
+ getattr(self.inner, "policy_id", "")
153
+ ),
154
+ "inner_definition_sha256": str(
155
+ getattr(self.inner, "definition_sha256", "")
156
+ ),
157
+ "rule": (
158
+ "keep the market's best keep_fraction of candidates "
159
+ "by parent-anchor chebyshev excess over the archive "
160
+ "front, unknown anchors scored at the median, never "
161
+ "below minimum_support"
162
+ ),
163
+ }
164
+ ),
165
+ )
166
+
167
+ def admissible(
168
+ self,
169
+ *,
170
+ record: MarketRecord,
171
+ revealed: tuple[ReplayStepReceipt, ...],
172
+ selectable_action_sha256s: tuple[str, ...],
173
+ ) -> tuple[str, ...]:
174
+ """The retained support, outcome-blind except for revealed points."""
175
+
176
+ support = tuple(sorted(set(selectable_action_sha256s)))
177
+ if not support:
178
+ raise ValueError("selectable support must be non-empty")
179
+ if self.config.keep_fraction >= 1.0:
180
+ return support
181
+ metric_ids = record.metric_ids
182
+ archive: list[ObjectivePoint] = list(record.archive_points)
183
+ for receipt in revealed:
184
+ candidate = record.candidate(receipt.action_sha256)
185
+ if candidate.objectives is not None:
186
+ archive.append(candidate.objectives)
187
+ frozen_archive = tuple(archive)
188
+ scored: list[tuple[str, float | None]] = []
189
+ for action_sha256 in support:
190
+ anchor = self.anchors.get(action_sha256)
191
+ scored.append(
192
+ (
193
+ action_sha256,
194
+ None
195
+ if anchor is None
196
+ else chebyshev_excess(
197
+ anchor, frozen_archive, metric_ids
198
+ ),
199
+ )
200
+ )
201
+ known = sorted(
202
+ value for _sha, value in scored if value is not None
203
+ )
204
+ if not known:
205
+ return support
206
+ median = known[len(known) // 2]
207
+ index = int(round(self.config.keep_fraction * len(known))) - 1
208
+ index = max(0, min(len(known) - 1, index))
209
+ cutoff = known[index]
210
+ kept = tuple(
211
+ action_sha256
212
+ for action_sha256, value in scored
213
+ if (median if value is None else value) <= cutoff
214
+ )
215
+ if len(kept) < min(self.config.minimum_support, len(support)):
216
+ # Restore in ascending excess order until the floor is met, so
217
+ # the restriction degrades continuously instead of collapsing.
218
+ order = sorted(
219
+ scored,
220
+ key=lambda item: (
221
+ median if item[1] is None else item[1],
222
+ item[0],
223
+ ),
224
+ )
225
+ kept = tuple(
226
+ action_sha256
227
+ for action_sha256, _value in order[
228
+ : min(self.config.minimum_support, len(support))
229
+ ]
230
+ )
231
+ return tuple(sorted(kept)) or support
232
+
233
+ def select(
234
+ self,
235
+ *,
236
+ record: MarketRecord,
237
+ revealed: tuple[ReplayStepReceipt, ...],
238
+ selectable_action_sha256s: tuple[str, ...],
239
+ step_index: int,
240
+ budget: int,
241
+ ) -> ReplaySelection:
242
+ kept = self.admissible(
243
+ record=record,
244
+ revealed=revealed,
245
+ selectable_action_sha256s=selectable_action_sha256s,
246
+ )
247
+ selection = self.inner.select(
248
+ record=record,
249
+ revealed=revealed,
250
+ selectable_action_sha256s=kept,
251
+ step_index=step_index,
252
+ budget=budget,
253
+ )
254
+ if type(selection) is not ReplaySelection:
255
+ raise TypeError("inner policy must return an exact selection")
256
+ if selection.action_sha256 not in kept:
257
+ raise ValueError("inner policy escaped the admissible support")
258
+ return ReplaySelection(
259
+ action_sha256=selection.action_sha256,
260
+ selection_propensity=selection.selection_propensity,
261
+ evidence={
262
+ **dict(selection.evidence),
263
+ "admissible_support_size": len(kept),
264
+ "offered_support_size": len(
265
+ set(selectable_action_sha256s)
266
+ ),
267
+ },
268
+ )
269
+
270
+
271
+ def anchors_from_corpus(
272
+ payload: dict[str, object],
273
+ ) -> dict[str, ObjectivePoint]:
274
+ """Parent anchors for one jul27 replay-corpus payload, if recorded.
275
+
276
+ Candidates with no recorded parent objective vector are simply absent,
277
+ which the admission rule treats as the median anchor.
278
+ """
279
+
280
+ market_id = str(payload["market_id"])
281
+ axes = tuple(payload["hv_reference_point"]["axes"]) # type: ignore[index]
282
+ metric_ids = tuple(sorted(str(axis["metric_id"]) for axis in axes))
283
+ anchors: dict[str, ObjectivePoint] = {}
284
+ for raw in payload["candidates"]: # type: ignore[union-attr]
285
+ parent = raw.get("parent")
286
+ if not isinstance(parent, dict):
287
+ continue
288
+ objectives = parent.get("objectives")
289
+ if not isinstance(objectives, dict):
290
+ continue
291
+ if not set(metric_ids) <= set(objectives):
292
+ continue
293
+ anchors[_corpus_action_sha256(market_id, raw)] = _normalized_point(
294
+ {
295
+ metric_id: float(objectives[metric_id])
296
+ for metric_id in metric_ids
297
+ },
298
+ axes,
299
+ )
300
+ return anchors
301
+
302
+
303
+ __all__ = [
304
+ "FRONT_PROXIMITY_ADMISSION_ID",
305
+ "FRONT_PROXIMITY_ADMISSION_VERSION",
306
+ "FrontProximityAdmission",
307
+ "FrontProximityAdmissionConfig",
308
+ "anchors_from_corpus",
309
+ "chebyshev_excess",
310
+ "non_dominated",
311
+ ]