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,1544 @@
1
+ """Conserved, workload-opaque learning of residual evolutionary headroom.
2
+
3
+ The ledger closes a gap between one-stage outcome-adaptive racing and a
4
+ multi-generation optimizer. It converts authenticated conditional set gains
5
+ into conserved action credit, learns decayed posteriors over opaque action
6
+ cells, and exposes those posteriors through an optional adaptive-market
7
+ projector. It never inspects workload names, objective names, configuration
8
+ fields, prompts, providers, or model-name strings.
9
+
10
+ The module deliberately separates three responsibilities:
11
+
12
+ * ``ConservedResidualHeadroomProjector`` closes one evaluated stage without
13
+ manufacturing more credit than the stage actually earned;
14
+ * ``ConservedResidualHeadroomLedger`` stores immutable closures and estimates
15
+ context-conditioned residual value; and
16
+ * ``ResidualHeadroomAdaptiveMarketProjector`` injects the prior-only estimate
17
+ into any existing adaptive market without changing the workload adapter.
18
+
19
+ Predicted values are selection evidence only. They never enter an
20
+ authoritative archive or replace a real evaluator outcome.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import hashlib
26
+ import json
27
+ import math
28
+ from dataclasses import dataclass, field, replace
29
+
30
+ from agent_evolve.application.materialized_action_broker import (
31
+ BrokerActionScore,
32
+ MaterializedActionDescriptor,
33
+ )
34
+ from agent_evolve.application.outcome_adaptive_action_racing import (
35
+ AdaptiveActionDescriptor,
36
+ AdaptiveActionFactorCell,
37
+ AdaptiveActionOutcome,
38
+ AdaptiveActionRacingDecision,
39
+ AdaptiveActionSetOutcome,
40
+ )
41
+ from agent_evolve.application.outcome_adaptive_residual_portfolio_evolution import (
42
+ AdaptiveActionMarketProjectorPort,
43
+ )
44
+ from agent_evolve.application.residual_portfolio_evolution import (
45
+ MaterializedActionProposalBatch,
46
+ ResidualPortfolioDecisionRequest,
47
+ )
48
+ from agent_evolve.domain.patch import require_sha256
49
+
50
+
51
+ RESIDUAL_HEADROOM_LEDGER_ID = "conserved_residual_headroom_ledger"
52
+ RESIDUAL_HEADROOM_LEDGER_VERSION = 1
53
+ RESIDUAL_HEADROOM_LEDGER_DEFINITION_SHA256 = hashlib.sha256(
54
+ b"agent-evolve:conserved-residual-headroom-ledger:v1;"
55
+ b"evidence=authenticated-real-action-and-conditional-set-outcomes;"
56
+ b"credit=wave-conditional-gain-proportional-to-isolated-real-gain;"
57
+ b"conservation=sum-action-credit-equals-sum-conditional-set-gain;"
58
+ b"attribution=equal-share-over-opaque-portable-action-cells;"
59
+ b"posterior=context-conditioned-decayed-clipped-ipw;"
60
+ b"headroom=expected-gain-plus-uncertainty-plus-late-bloom;"
61
+ b"risk=redundancy-plus-saturation-plus-invalidity;"
62
+ b"archive-authority=real-evaluations-only;"
63
+ b"workload-objective-model-provider-prompt-config-branches=false"
64
+ ).hexdigest()
65
+
66
+ RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_ID = (
67
+ "residual_headroom_adaptive_market_projector"
68
+ )
69
+ RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_VERSION = 1
70
+
71
+ _OBSERVATION_DOMAIN = b"agent-evolve:residual-headroom-observation:v1\x00"
72
+ _CLOSURE_DOMAIN = b"agent-evolve:residual-headroom-stage-closure:v1\x00"
73
+ _STATE_DOMAIN = b"agent-evolve:residual-headroom-ledger-state:v1\x00"
74
+ _CONFIG_DOMAIN = b"agent-evolve:residual-headroom-ledger-config:v1\x00"
75
+ _ESTIMATE_DOMAIN = b"agent-evolve:residual-headroom-estimate:v1\x00"
76
+ _MARKET_PROJECTOR_DOMAIN = (
77
+ b"agent-evolve:residual-headroom-market-projector:v1\x00"
78
+ )
79
+ _MARKET_STATE_DOMAIN = (
80
+ b"agent-evolve:residual-headroom-market-projector-state:v1\x00"
81
+ )
82
+
83
+
84
+ def _canonical_json(value: object) -> bytes:
85
+ return json.dumps(
86
+ value,
87
+ allow_nan=False,
88
+ ensure_ascii=True,
89
+ separators=(",", ":"),
90
+ sort_keys=True,
91
+ ).encode("ascii", errors="strict")
92
+
93
+
94
+ def _hash(domain: bytes, value: object) -> str:
95
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
96
+
97
+
98
+ def _close(left: float, right: float) -> bool:
99
+ return math.isclose(left, right, rel_tol=1e-12, abs_tol=1e-15)
100
+
101
+
102
+ def _require_nonnegative(value: float, *, name: str) -> None:
103
+ if (
104
+ type(value) is not float
105
+ or not math.isfinite(value)
106
+ or value < 0.0
107
+ ):
108
+ raise ValueError(f"{name} must be finite and non-negative")
109
+
110
+
111
+ def _attribution_cells(
112
+ action: AdaptiveActionDescriptor,
113
+ ) -> tuple[AdaptiveActionFactorCell, ...]:
114
+ """Project one portable action into conserved-credit attribution cells."""
115
+
116
+ action.__post_init__()
117
+ cells = set(action.factor_cells)
118
+ cells.add(
119
+ AdaptiveActionFactorCell(
120
+ family_id="portable_lane",
121
+ level_id=action.lane_id,
122
+ )
123
+ )
124
+ cells.add(
125
+ AdaptiveActionFactorCell(
126
+ family_id="portable_operator",
127
+ level_id=action.operator_id,
128
+ )
129
+ )
130
+ cells.add(
131
+ AdaptiveActionFactorCell(
132
+ family_id="portable_parent_origin",
133
+ level_id=(
134
+ "current_run"
135
+ if action.parent_generated_in_current_run
136
+ else "prior_archive"
137
+ ),
138
+ )
139
+ )
140
+ if not any(
141
+ value.family_id == "materialized_rank_layer"
142
+ for value in cells
143
+ ):
144
+ layer = min(
145
+ 2,
146
+ ((action.native_rank - 1) * 3) // action.lane_size,
147
+ )
148
+ cells.add(
149
+ AdaptiveActionFactorCell(
150
+ family_id="materialized_rank_layer",
151
+ level_id=f"layer{layer}",
152
+ )
153
+ )
154
+ for value in action.semantic_cell_ids:
155
+ cells.add(
156
+ AdaptiveActionFactorCell(
157
+ family_id="portable_semantic_cell",
158
+ level_id=value,
159
+ )
160
+ )
161
+ return tuple(sorted(cells))
162
+
163
+
164
+ @dataclass(frozen=True, slots=True)
165
+ class ResidualHeadroomObservation:
166
+ """One action's conserved share of a real conditional wave gain."""
167
+
168
+ context_sha256: str
169
+ residual_request_sha256: str
170
+ generation_index: int
171
+ wave_index: int
172
+ action_sha256: str
173
+ evaluation_sha256: str
174
+ outcome_sha256: str
175
+ set_outcome_sha256: str
176
+ decision_sha256: str
177
+ selection_propensity: float
178
+ propensity_identified: bool
179
+ feasible: bool
180
+ isolated_gain: float
181
+ conditional_credit: float
182
+ normalized_conditional_credit: float
183
+ redundancy_fraction: float
184
+ synergy_fraction: float
185
+ attribution_cells: tuple[AdaptiveActionFactorCell, ...]
186
+ observation_sha256: str = field(init=False)
187
+
188
+ def __post_init__(self) -> None:
189
+ for name in (
190
+ "context_sha256",
191
+ "residual_request_sha256",
192
+ "action_sha256",
193
+ "evaluation_sha256",
194
+ "outcome_sha256",
195
+ "set_outcome_sha256",
196
+ "decision_sha256",
197
+ ):
198
+ require_sha256(getattr(self, name), name)
199
+ if type(self.generation_index) is not int or self.generation_index < 0:
200
+ raise ValueError("generation_index must be non-negative")
201
+ if type(self.wave_index) is not int or self.wave_index < 0:
202
+ raise ValueError("wave_index must be non-negative")
203
+ if (
204
+ type(self.selection_propensity) is not float
205
+ or not math.isfinite(self.selection_propensity)
206
+ or not 0.0 < self.selection_propensity <= 1.0
207
+ ):
208
+ raise ValueError("selection_propensity must lie in (0, 1]")
209
+ if type(self.propensity_identified) is not bool:
210
+ raise TypeError("propensity_identified must be exact")
211
+ if type(self.feasible) is not bool:
212
+ raise TypeError("feasible must be exact")
213
+ for name in (
214
+ "isolated_gain",
215
+ "conditional_credit",
216
+ "normalized_conditional_credit",
217
+ "redundancy_fraction",
218
+ "synergy_fraction",
219
+ ):
220
+ _require_nonnegative(getattr(self, name), name=name)
221
+ for name in ("redundancy_fraction", "synergy_fraction"):
222
+ if getattr(self, name) > 1.0:
223
+ raise ValueError(f"{name} must not exceed one")
224
+ if not self.feasible and (
225
+ self.isolated_gain != 0.0
226
+ or self.conditional_credit != 0.0
227
+ ):
228
+ raise ValueError("infeasible actions cannot receive positive credit")
229
+ if (
230
+ type(self.attribution_cells) is not tuple
231
+ or not self.attribution_cells
232
+ or self.attribution_cells
233
+ != tuple(sorted(set(self.attribution_cells)))
234
+ ):
235
+ raise ValueError(
236
+ "attribution_cells must be non-empty, unique, and canonical"
237
+ )
238
+ for value in self.attribution_cells:
239
+ if type(value) is not AdaptiveActionFactorCell:
240
+ raise TypeError("attribution cells must be exact")
241
+ value.__post_init__()
242
+ object.__setattr__(
243
+ self,
244
+ "observation_sha256",
245
+ _hash(_OBSERVATION_DOMAIN, self._unsigned_record()),
246
+ )
247
+
248
+ def _unsigned_record(self) -> dict[str, object]:
249
+ return {
250
+ "schema_version": 1,
251
+ "context_sha256": self.context_sha256,
252
+ "residual_request_sha256": self.residual_request_sha256,
253
+ "generation_index": self.generation_index,
254
+ "wave_index": self.wave_index,
255
+ "action_sha256": self.action_sha256,
256
+ "evaluation_sha256": self.evaluation_sha256,
257
+ "outcome_sha256": self.outcome_sha256,
258
+ "set_outcome_sha256": self.set_outcome_sha256,
259
+ "decision_sha256": self.decision_sha256,
260
+ "selection_propensity_hex": self.selection_propensity.hex(),
261
+ "propensity_identified": self.propensity_identified,
262
+ "feasible": self.feasible,
263
+ "isolated_gain_hex": self.isolated_gain.hex(),
264
+ "conditional_credit_hex": self.conditional_credit.hex(),
265
+ "normalized_conditional_credit_hex": (
266
+ self.normalized_conditional_credit.hex()
267
+ ),
268
+ "redundancy_fraction_hex": self.redundancy_fraction.hex(),
269
+ "synergy_fraction_hex": self.synergy_fraction.hex(),
270
+ "attribution_cells": [
271
+ value.to_record() for value in self.attribution_cells
272
+ ],
273
+ }
274
+
275
+ def to_record(self) -> dict[str, object]:
276
+ self.__post_init__()
277
+ return {
278
+ **self._unsigned_record(),
279
+ "observation_sha256": self.observation_sha256,
280
+ }
281
+
282
+ @classmethod
283
+ def from_record(
284
+ cls,
285
+ record: dict[str, object],
286
+ ) -> "ResidualHeadroomObservation":
287
+ if type(record) is not dict:
288
+ raise TypeError("observation record must be an exact object")
289
+ cells = record["attribution_cells"]
290
+ if (
291
+ type(cells) is not list
292
+ or any(type(value) is not dict for value in cells)
293
+ ):
294
+ raise TypeError("attribution_cells record must be a list")
295
+ value = cls(
296
+ context_sha256=str(record["context_sha256"]),
297
+ residual_request_sha256=str(
298
+ record["residual_request_sha256"]
299
+ ),
300
+ generation_index=int(record["generation_index"]),
301
+ wave_index=int(record["wave_index"]),
302
+ action_sha256=str(record["action_sha256"]),
303
+ evaluation_sha256=str(record["evaluation_sha256"]),
304
+ outcome_sha256=str(record["outcome_sha256"]),
305
+ set_outcome_sha256=str(record["set_outcome_sha256"]),
306
+ decision_sha256=str(record["decision_sha256"]),
307
+ selection_propensity=float.fromhex(
308
+ str(record["selection_propensity_hex"])
309
+ ),
310
+ propensity_identified=bool(record["propensity_identified"]),
311
+ feasible=bool(record["feasible"]),
312
+ isolated_gain=float.fromhex(
313
+ str(record["isolated_gain_hex"])
314
+ ),
315
+ conditional_credit=float.fromhex(
316
+ str(record["conditional_credit_hex"])
317
+ ),
318
+ normalized_conditional_credit=float.fromhex(
319
+ str(record["normalized_conditional_credit_hex"])
320
+ ),
321
+ redundancy_fraction=float.fromhex(
322
+ str(record["redundancy_fraction_hex"])
323
+ ),
324
+ synergy_fraction=float.fromhex(
325
+ str(record["synergy_fraction_hex"])
326
+ ),
327
+ attribution_cells=tuple(
328
+ AdaptiveActionFactorCell(
329
+ family_id=str(cell["family_id"]),
330
+ level_id=str(cell["level_id"]),
331
+ )
332
+ for cell in cells
333
+ ),
334
+ )
335
+ if value.observation_sha256 != str(
336
+ record["observation_sha256"]
337
+ ):
338
+ raise ValueError("observation record hash does not authenticate")
339
+ return value
340
+
341
+
342
+ @dataclass(frozen=True, slots=True)
343
+ class ResidualHeadroomStageClosure:
344
+ """Authenticated, conserved learning evidence for one real stage."""
345
+
346
+ context_sha256: str
347
+ residual_request_sha256: str
348
+ generation_index: int
349
+ reference_gain_scale: float
350
+ reference_gain_evidence_sha256: str
351
+ decision_sha256s: tuple[str, ...]
352
+ set_outcome_sha256s: tuple[str, ...]
353
+ observations: tuple[ResidualHeadroomObservation, ...]
354
+ total_conditional_gain: float
355
+ closure_sha256: str = field(init=False)
356
+
357
+ def __post_init__(self) -> None:
358
+ for name in (
359
+ "context_sha256",
360
+ "residual_request_sha256",
361
+ "reference_gain_evidence_sha256",
362
+ ):
363
+ require_sha256(getattr(self, name), name)
364
+ if type(self.generation_index) is not int or self.generation_index < 0:
365
+ raise ValueError("generation_index must be non-negative")
366
+ if (
367
+ type(self.reference_gain_scale) is not float
368
+ or not math.isfinite(self.reference_gain_scale)
369
+ or self.reference_gain_scale <= 0.0
370
+ ):
371
+ raise ValueError("reference_gain_scale must be positive")
372
+ for values, name in (
373
+ (self.decision_sha256s, "decision_sha256s"),
374
+ (self.set_outcome_sha256s, "set_outcome_sha256s"),
375
+ ):
376
+ if (
377
+ type(values) is not tuple
378
+ or not values
379
+ or values != tuple(dict.fromkeys(values))
380
+ ):
381
+ raise ValueError(f"{name} must be non-empty and ordered unique")
382
+ for value in values:
383
+ require_sha256(value, name)
384
+ if len(self.decision_sha256s) != len(self.set_outcome_sha256s):
385
+ raise ValueError("each decision must bind one set outcome")
386
+ if type(self.observations) is not tuple or not self.observations:
387
+ raise ValueError("observations must be a non-empty exact tuple")
388
+ identities: list[str] = []
389
+ for value in self.observations:
390
+ if type(value) is not ResidualHeadroomObservation:
391
+ raise TypeError("observations must contain exact values")
392
+ value.__post_init__()
393
+ if (
394
+ value.context_sha256 != self.context_sha256
395
+ or value.residual_request_sha256
396
+ != self.residual_request_sha256
397
+ or value.generation_index != self.generation_index
398
+ or value.decision_sha256
399
+ not in self.decision_sha256s
400
+ or value.set_outcome_sha256
401
+ not in self.set_outcome_sha256s
402
+ ):
403
+ raise ValueError("an observation names another stage closure")
404
+ if not _close(
405
+ value.normalized_conditional_credit,
406
+ value.conditional_credit / self.reference_gain_scale,
407
+ ):
408
+ raise ValueError("normalized credit differs from stage scale")
409
+ identities.append(value.action_sha256)
410
+ if len(identities) != len(set(identities)):
411
+ raise ValueError("stage closure repeats an action")
412
+ _require_nonnegative(
413
+ self.total_conditional_gain,
414
+ name="total_conditional_gain",
415
+ )
416
+ attributed = math.fsum(
417
+ value.conditional_credit for value in self.observations
418
+ )
419
+ if not _close(attributed, self.total_conditional_gain):
420
+ raise ValueError("action credit does not conserve conditional gain")
421
+ object.__setattr__(
422
+ self,
423
+ "closure_sha256",
424
+ _hash(_CLOSURE_DOMAIN, self._unsigned_record()),
425
+ )
426
+
427
+ def _unsigned_record(self) -> dict[str, object]:
428
+ return {
429
+ "schema_version": 1,
430
+ "ledger_definition_sha256": (
431
+ RESIDUAL_HEADROOM_LEDGER_DEFINITION_SHA256
432
+ ),
433
+ "context_sha256": self.context_sha256,
434
+ "residual_request_sha256": self.residual_request_sha256,
435
+ "generation_index": self.generation_index,
436
+ "reference_gain_scale_hex": self.reference_gain_scale.hex(),
437
+ "reference_gain_evidence_sha256": (
438
+ self.reference_gain_evidence_sha256
439
+ ),
440
+ "decision_sha256s": list(self.decision_sha256s),
441
+ "set_outcome_sha256s": list(self.set_outcome_sha256s),
442
+ "observation_sha256s": [
443
+ value.observation_sha256 for value in self.observations
444
+ ],
445
+ "total_conditional_gain_hex": (
446
+ self.total_conditional_gain.hex()
447
+ ),
448
+ "credit_conserved": True,
449
+ "predicted_values_admitted_to_archive": False,
450
+ "workload_objective_model_provider_prompt_config_fields": False,
451
+ }
452
+
453
+ def to_record(self) -> dict[str, object]:
454
+ self.__post_init__()
455
+ return {
456
+ **self._unsigned_record(),
457
+ "observations": [
458
+ value.to_record() for value in self.observations
459
+ ],
460
+ "closure_sha256": self.closure_sha256,
461
+ }
462
+
463
+ @classmethod
464
+ def from_record(
465
+ cls,
466
+ record: dict[str, object],
467
+ ) -> "ResidualHeadroomStageClosure":
468
+ if type(record) is not dict:
469
+ raise TypeError("closure record must be an exact object")
470
+ observations = record["observations"]
471
+ if (
472
+ type(observations) is not list
473
+ or any(type(value) is not dict for value in observations)
474
+ ):
475
+ raise TypeError("closure observations must be exact objects")
476
+ value = cls(
477
+ context_sha256=str(record["context_sha256"]),
478
+ residual_request_sha256=str(
479
+ record["residual_request_sha256"]
480
+ ),
481
+ generation_index=int(record["generation_index"]),
482
+ reference_gain_scale=float.fromhex(
483
+ str(record["reference_gain_scale_hex"])
484
+ ),
485
+ reference_gain_evidence_sha256=str(
486
+ record["reference_gain_evidence_sha256"]
487
+ ),
488
+ decision_sha256s=tuple(
489
+ str(item) for item in record["decision_sha256s"]
490
+ ),
491
+ set_outcome_sha256s=tuple(
492
+ str(item) for item in record["set_outcome_sha256s"]
493
+ ),
494
+ observations=tuple(
495
+ ResidualHeadroomObservation.from_record(value)
496
+ for value in observations
497
+ ),
498
+ total_conditional_gain=float.fromhex(
499
+ str(record["total_conditional_gain_hex"])
500
+ ),
501
+ )
502
+ if value.closure_sha256 != str(record["closure_sha256"]):
503
+ raise ValueError("closure record hash does not authenticate")
504
+ return value
505
+
506
+
507
+ @dataclass(frozen=True, slots=True)
508
+ class ConservedResidualHeadroomProjector:
509
+ """Compile one outcome-adaptive stage into conserved ledger evidence."""
510
+
511
+ def project(
512
+ self,
513
+ *,
514
+ context_sha256: str,
515
+ generation_index: int,
516
+ reference_gain_scale: float,
517
+ reference_gain_evidence_sha256: str,
518
+ actions: tuple[AdaptiveActionDescriptor, ...],
519
+ diagnostic_decision: AdaptiveActionRacingDecision,
520
+ continuation_decisions: tuple[
521
+ AdaptiveActionRacingDecision, ...
522
+ ],
523
+ outcomes: tuple[AdaptiveActionOutcome, ...],
524
+ set_outcomes: tuple[AdaptiveActionSetOutcome, ...],
525
+ ) -> ResidualHeadroomStageClosure:
526
+ require_sha256(context_sha256, "context_sha256")
527
+ require_sha256(
528
+ reference_gain_evidence_sha256,
529
+ "reference_gain_evidence_sha256",
530
+ )
531
+ if type(generation_index) is not int or generation_index < 0:
532
+ raise ValueError("generation_index must be non-negative")
533
+ if (
534
+ type(reference_gain_scale) is not float
535
+ or not math.isfinite(reference_gain_scale)
536
+ or reference_gain_scale <= 0.0
537
+ ):
538
+ raise ValueError("reference_gain_scale must be positive")
539
+ if type(actions) is not tuple or not actions:
540
+ raise ValueError("actions must be a non-empty exact tuple")
541
+ action_by_sha256: dict[str, AdaptiveActionDescriptor] = {}
542
+ for value in actions:
543
+ if type(value) is not AdaptiveActionDescriptor:
544
+ raise TypeError("actions must contain exact values")
545
+ value.__post_init__()
546
+ action_by_sha256[value.action_sha256] = value
547
+ if len(action_by_sha256) != len(actions):
548
+ raise ValueError("actions repeat an identity")
549
+ if type(diagnostic_decision) is not AdaptiveActionRacingDecision:
550
+ raise TypeError("diagnostic_decision must be exact")
551
+ diagnostic_decision.__post_init__()
552
+ if type(continuation_decisions) is not tuple:
553
+ raise TypeError("continuation_decisions must be an exact tuple")
554
+ decisions = (diagnostic_decision, *continuation_decisions)
555
+ for value in decisions:
556
+ if type(value) is not AdaptiveActionRacingDecision:
557
+ raise TypeError("continuation decisions must be exact")
558
+ value.__post_init__()
559
+ request_sha256 = diagnostic_decision.residual_request_sha256
560
+ if any(
561
+ value.residual_request_sha256 != request_sha256
562
+ for value in decisions
563
+ ):
564
+ raise ValueError("decisions name different residual requests")
565
+ if (
566
+ type(outcomes) is not tuple
567
+ or not outcomes
568
+ or any(type(value) is not AdaptiveActionOutcome for value in outcomes)
569
+ ):
570
+ raise ValueError("outcomes must be a non-empty exact tuple")
571
+ outcome_by_action: dict[str, AdaptiveActionOutcome] = {}
572
+ for value in outcomes:
573
+ value.__post_init__()
574
+ outcome_by_action[value.action_sha256] = value
575
+ if len(outcome_by_action) != len(outcomes):
576
+ raise ValueError("outcomes repeat an action")
577
+ if (
578
+ type(set_outcomes) is not tuple
579
+ or len(set_outcomes) != len(decisions)
580
+ ):
581
+ raise ValueError("each decision requires one ordered set outcome")
582
+
583
+ observations: list[ResidualHeadroomObservation] = []
584
+ for wave_index, (decision, set_outcome) in enumerate(
585
+ zip(decisions, set_outcomes, strict=True)
586
+ ):
587
+ if type(set_outcome) is not AdaptiveActionSetOutcome:
588
+ raise TypeError("set outcomes must contain exact values")
589
+ set_outcome.__post_init__()
590
+ selected = tuple(
591
+ value[0]
592
+ for value in set_outcome.current_action_evaluation_bindings
593
+ )
594
+ if set(selected) != set(decision.selected_action_sha256s):
595
+ raise ValueError(
596
+ "decision selection differs from its real set outcome"
597
+ )
598
+ wave_outcomes: list[AdaptiveActionOutcome] = []
599
+ for action_sha256, evaluation_sha256 in (
600
+ set_outcome.current_action_evaluation_bindings
601
+ ):
602
+ action = action_by_sha256.get(action_sha256)
603
+ outcome = outcome_by_action.get(action_sha256)
604
+ if (
605
+ action is None
606
+ or outcome is None
607
+ or outcome.evaluation_sha256 != evaluation_sha256
608
+ ):
609
+ raise ValueError(
610
+ "set outcome lacks its action/evaluation binding"
611
+ )
612
+ wave_outcomes.append(outcome)
613
+ isolated_sum = math.fsum(
614
+ value.marginal_archive_gain for value in wave_outcomes
615
+ )
616
+ conditional = set_outcome.conditional_set_gain
617
+ if conditional == 0.0:
618
+ credits = [0.0 for _ in wave_outcomes]
619
+ elif isolated_sum > 0.0:
620
+ credits = [
621
+ conditional
622
+ * value.marginal_archive_gain
623
+ / isolated_sum
624
+ for value in wave_outcomes
625
+ ]
626
+ else:
627
+ credits = [
628
+ conditional / len(wave_outcomes)
629
+ for _ in wave_outcomes
630
+ ]
631
+ if credits:
632
+ credits[-1] = max(
633
+ 0.0,
634
+ conditional - math.fsum(credits[:-1]),
635
+ )
636
+ fixed = set_outcome.current_wave_fixed_set_gain
637
+ redundancy_fraction = (
638
+ 0.0
639
+ if fixed <= 0.0
640
+ else min(
641
+ set_outcome.prior_conditioned_redundancy / fixed,
642
+ 1.0,
643
+ )
644
+ )
645
+ synergy_fraction = (
646
+ 0.0
647
+ if conditional <= 0.0
648
+ else min(
649
+ set_outcome.prior_conditioned_synergy / conditional,
650
+ 1.0,
651
+ )
652
+ )
653
+ identified = (
654
+ len(decision.selected_action_sha256s) == 1
655
+ or decision.selection_propensity == 1.0
656
+ )
657
+ effective_propensity = (
658
+ decision.selection_propensity if identified else 1.0
659
+ )
660
+ for outcome, credit in zip(
661
+ wave_outcomes,
662
+ credits,
663
+ strict=True,
664
+ ):
665
+ observations.append(
666
+ ResidualHeadroomObservation(
667
+ context_sha256=context_sha256,
668
+ residual_request_sha256=request_sha256,
669
+ generation_index=generation_index,
670
+ wave_index=wave_index,
671
+ action_sha256=outcome.action_sha256,
672
+ evaluation_sha256=outcome.evaluation_sha256,
673
+ outcome_sha256=outcome.outcome_sha256,
674
+ set_outcome_sha256=(
675
+ set_outcome.set_outcome_sha256
676
+ ),
677
+ decision_sha256=decision.decision_sha256,
678
+ selection_propensity=effective_propensity,
679
+ propensity_identified=identified,
680
+ feasible=outcome.feasible,
681
+ isolated_gain=outcome.marginal_archive_gain,
682
+ conditional_credit=float(credit),
683
+ normalized_conditional_credit=float(
684
+ credit / reference_gain_scale
685
+ ),
686
+ redundancy_fraction=redundancy_fraction,
687
+ synergy_fraction=synergy_fraction,
688
+ attribution_cells=_attribution_cells(
689
+ action_by_sha256[outcome.action_sha256]
690
+ ),
691
+ )
692
+ )
693
+ total_conditional_gain = math.fsum(
694
+ value.conditional_set_gain for value in set_outcomes
695
+ )
696
+ return ResidualHeadroomStageClosure(
697
+ context_sha256=context_sha256,
698
+ residual_request_sha256=request_sha256,
699
+ generation_index=generation_index,
700
+ reference_gain_scale=reference_gain_scale,
701
+ reference_gain_evidence_sha256=(
702
+ reference_gain_evidence_sha256
703
+ ),
704
+ decision_sha256s=tuple(
705
+ value.decision_sha256 for value in decisions
706
+ ),
707
+ set_outcome_sha256s=tuple(
708
+ value.set_outcome_sha256 for value in set_outcomes
709
+ ),
710
+ observations=tuple(observations),
711
+ total_conditional_gain=float(total_conditional_gain),
712
+ )
713
+
714
+
715
+ @dataclass(frozen=True, slots=True)
716
+ class ResidualHeadroomLedgerConfig:
717
+ """Portable posterior and risk controls for residual-headroom learning."""
718
+
719
+ generation_decay: float = 0.85
720
+ cross_context_weight: float = 0.0
721
+ maximum_inverse_propensity: float = 10.0
722
+ prior_strength: float = 2.0
723
+ prior_normalized_gain: float = 1.0
724
+ positive_prior_alpha: float = 1.0
725
+ positive_prior_beta: float = 1.0
726
+ invalid_prior_alpha: float = 1.0
727
+ invalid_prior_beta: float = 9.0
728
+ uncertainty_strength: float = 1.0
729
+ late_bloom_strength: float = 0.5
730
+ saturation_strength: float = 0.5
731
+ redundancy_strength: float = 0.5
732
+ invalidity_strength: float = 0.5
733
+ exploration_floor: float = 0.25
734
+ maximum_abs_slope: float = 2.0
735
+ definition_sha256: str = field(init=False)
736
+
737
+ def __post_init__(self) -> None:
738
+ if (
739
+ type(self.generation_decay) is not float
740
+ or not math.isfinite(self.generation_decay)
741
+ or not 0.0 < self.generation_decay <= 1.0
742
+ ):
743
+ raise ValueError("generation_decay must lie in (0, 1]")
744
+ if (
745
+ type(self.cross_context_weight) is not float
746
+ or not math.isfinite(self.cross_context_weight)
747
+ or not 0.0 <= self.cross_context_weight <= 1.0
748
+ ):
749
+ raise ValueError("cross_context_weight must lie in [0, 1]")
750
+ for value, name, positive in (
751
+ (
752
+ self.maximum_inverse_propensity,
753
+ "maximum_inverse_propensity",
754
+ True,
755
+ ),
756
+ (self.prior_strength, "prior_strength", True),
757
+ (
758
+ self.prior_normalized_gain,
759
+ "prior_normalized_gain",
760
+ False,
761
+ ),
762
+ (
763
+ self.positive_prior_alpha,
764
+ "positive_prior_alpha",
765
+ True,
766
+ ),
767
+ (
768
+ self.positive_prior_beta,
769
+ "positive_prior_beta",
770
+ True,
771
+ ),
772
+ (
773
+ self.invalid_prior_alpha,
774
+ "invalid_prior_alpha",
775
+ True,
776
+ ),
777
+ (
778
+ self.invalid_prior_beta,
779
+ "invalid_prior_beta",
780
+ True,
781
+ ),
782
+ (
783
+ self.uncertainty_strength,
784
+ "uncertainty_strength",
785
+ False,
786
+ ),
787
+ (
788
+ self.late_bloom_strength,
789
+ "late_bloom_strength",
790
+ False,
791
+ ),
792
+ (
793
+ self.saturation_strength,
794
+ "saturation_strength",
795
+ False,
796
+ ),
797
+ (
798
+ self.redundancy_strength,
799
+ "redundancy_strength",
800
+ False,
801
+ ),
802
+ (
803
+ self.invalidity_strength,
804
+ "invalidity_strength",
805
+ False,
806
+ ),
807
+ (
808
+ self.exploration_floor,
809
+ "exploration_floor",
810
+ False,
811
+ ),
812
+ (
813
+ self.maximum_abs_slope,
814
+ "maximum_abs_slope",
815
+ True,
816
+ ),
817
+ ):
818
+ if (
819
+ type(value) is not float
820
+ or not math.isfinite(value)
821
+ or value < 0.0
822
+ or (positive and value <= 0.0)
823
+ ):
824
+ qualifier = "positive" if positive else "non-negative"
825
+ raise ValueError(f"{name} must be finite and {qualifier}")
826
+ object.__setattr__(
827
+ self,
828
+ "definition_sha256",
829
+ _hash(_CONFIG_DOMAIN, self._unsigned_record()),
830
+ )
831
+
832
+ def _unsigned_record(self) -> dict[str, object]:
833
+ return {
834
+ "schema_version": 1,
835
+ "ledger_id": RESIDUAL_HEADROOM_LEDGER_ID,
836
+ "ledger_version": RESIDUAL_HEADROOM_LEDGER_VERSION,
837
+ "ledger_definition_sha256": (
838
+ RESIDUAL_HEADROOM_LEDGER_DEFINITION_SHA256
839
+ ),
840
+ "generation_decay_hex": self.generation_decay.hex(),
841
+ "cross_context_weight_hex": self.cross_context_weight.hex(),
842
+ "maximum_inverse_propensity_hex": (
843
+ self.maximum_inverse_propensity.hex()
844
+ ),
845
+ "prior_strength_hex": self.prior_strength.hex(),
846
+ "prior_normalized_gain_hex": (
847
+ self.prior_normalized_gain.hex()
848
+ ),
849
+ "positive_prior_alpha_hex": (
850
+ self.positive_prior_alpha.hex()
851
+ ),
852
+ "positive_prior_beta_hex": self.positive_prior_beta.hex(),
853
+ "invalid_prior_alpha_hex": self.invalid_prior_alpha.hex(),
854
+ "invalid_prior_beta_hex": self.invalid_prior_beta.hex(),
855
+ "uncertainty_strength_hex": self.uncertainty_strength.hex(),
856
+ "late_bloom_strength_hex": self.late_bloom_strength.hex(),
857
+ "saturation_strength_hex": self.saturation_strength.hex(),
858
+ "redundancy_strength_hex": self.redundancy_strength.hex(),
859
+ "invalidity_strength_hex": self.invalidity_strength.hex(),
860
+ "exploration_floor_hex": self.exploration_floor.hex(),
861
+ "maximum_abs_slope_hex": self.maximum_abs_slope.hex(),
862
+ "workload_objective_model_provider_prompt_config_branches": False,
863
+ }
864
+
865
+ def to_record(self) -> dict[str, object]:
866
+ self.__post_init__()
867
+ return {
868
+ **self._unsigned_record(),
869
+ "definition_sha256": self.definition_sha256,
870
+ }
871
+
872
+
873
+ @dataclass(frozen=True, slots=True)
874
+ class ResidualHeadroomLedgerState:
875
+ """Immutable append-only set of conserved stage closures."""
876
+
877
+ config_definition_sha256: str
878
+ closures: tuple[ResidualHeadroomStageClosure, ...] = ()
879
+ state_sha256: str = field(init=False)
880
+
881
+ def __post_init__(self) -> None:
882
+ require_sha256(
883
+ self.config_definition_sha256,
884
+ "config_definition_sha256",
885
+ )
886
+ if type(self.closures) is not tuple:
887
+ raise TypeError("closures must be an exact tuple")
888
+ closure_ids: list[str] = []
889
+ stage_ids: list[tuple[str, str]] = []
890
+ latest_generation_by_context: dict[str, int] = {}
891
+ for value in self.closures:
892
+ if type(value) is not ResidualHeadroomStageClosure:
893
+ raise TypeError("closures must contain exact values")
894
+ value.__post_init__()
895
+ prior = latest_generation_by_context.get(value.context_sha256)
896
+ if prior is not None and value.generation_index < prior:
897
+ raise ValueError(
898
+ "closure generations must not regress within a context"
899
+ )
900
+ latest_generation_by_context[value.context_sha256] = (
901
+ value.generation_index
902
+ )
903
+ closure_ids.append(value.closure_sha256)
904
+ stage_ids.append(
905
+ (value.context_sha256, value.residual_request_sha256)
906
+ )
907
+ if len(closure_ids) != len(set(closure_ids)):
908
+ raise ValueError("ledger repeats a closure")
909
+ if len(stage_ids) != len(set(stage_ids)):
910
+ raise ValueError("ledger repeats a context/request stage")
911
+ object.__setattr__(
912
+ self,
913
+ "state_sha256",
914
+ _hash(_STATE_DOMAIN, self._unsigned_record()),
915
+ )
916
+
917
+ def _unsigned_record(self) -> dict[str, object]:
918
+ return {
919
+ "schema_version": 1,
920
+ "ledger_definition_sha256": (
921
+ RESIDUAL_HEADROOM_LEDGER_DEFINITION_SHA256
922
+ ),
923
+ "config_definition_sha256": self.config_definition_sha256,
924
+ "closure_sha256s": [
925
+ value.closure_sha256 for value in self.closures
926
+ ],
927
+ "append_only": True,
928
+ "predicted_values_admitted_to_archive": False,
929
+ }
930
+
931
+ def to_record(self, *, include_closures: bool = False) -> dict[str, object]:
932
+ self.__post_init__()
933
+ record = {
934
+ **self._unsigned_record(),
935
+ "state_sha256": self.state_sha256,
936
+ }
937
+ if include_closures:
938
+ record["closures"] = [
939
+ value.to_record() for value in self.closures
940
+ ]
941
+ return record
942
+
943
+
944
+ @dataclass(frozen=True, slots=True)
945
+ class ResidualHeadroomCellPosterior:
946
+ cell: AdaptiveActionFactorCell
947
+ posterior_mean: float
948
+ uncertainty: float
949
+ positive_probability: float
950
+ invalid_probability: float
951
+ redundancy_fraction: float
952
+ late_bloom_slope: float
953
+ saturation_slope: float
954
+ effective_sample_size: float
955
+ raw_observation_count: int
956
+
957
+ def __post_init__(self) -> None:
958
+ if type(self.cell) is not AdaptiveActionFactorCell:
959
+ raise TypeError("cell must be exact")
960
+ self.cell.__post_init__()
961
+ for name in (
962
+ "posterior_mean",
963
+ "uncertainty",
964
+ "positive_probability",
965
+ "invalid_probability",
966
+ "redundancy_fraction",
967
+ "late_bloom_slope",
968
+ "saturation_slope",
969
+ "effective_sample_size",
970
+ ):
971
+ _require_nonnegative(getattr(self, name), name=name)
972
+ for name in (
973
+ "positive_probability",
974
+ "invalid_probability",
975
+ "redundancy_fraction",
976
+ ):
977
+ if getattr(self, name) > 1.0:
978
+ raise ValueError(f"{name} must not exceed one")
979
+ if (
980
+ type(self.raw_observation_count) is not int
981
+ or self.raw_observation_count < 0
982
+ ):
983
+ raise ValueError("raw_observation_count must be non-negative")
984
+
985
+ def to_record(self) -> dict[str, object]:
986
+ self.__post_init__()
987
+ return {
988
+ "cell": self.cell.to_record(),
989
+ "posterior_mean_hex": self.posterior_mean.hex(),
990
+ "uncertainty_hex": self.uncertainty.hex(),
991
+ "positive_probability_hex": (
992
+ self.positive_probability.hex()
993
+ ),
994
+ "invalid_probability_hex": self.invalid_probability.hex(),
995
+ "redundancy_fraction_hex": self.redundancy_fraction.hex(),
996
+ "late_bloom_slope_hex": self.late_bloom_slope.hex(),
997
+ "saturation_slope_hex": self.saturation_slope.hex(),
998
+ "effective_sample_size_hex": (
999
+ self.effective_sample_size.hex()
1000
+ ),
1001
+ "raw_observation_count": self.raw_observation_count,
1002
+ }
1003
+
1004
+
1005
+ @dataclass(frozen=True, slots=True)
1006
+ class ResidualHeadroomEstimate:
1007
+ context_sha256: str
1008
+ action_sha256: str
1009
+ generation_index: int
1010
+ expected_normalized_gain: float
1011
+ uncertainty: float
1012
+ positive_probability: float
1013
+ invalid_probability: float
1014
+ redundancy_fraction: float
1015
+ late_bloom_headroom: float
1016
+ saturation_risk: float
1017
+ acquisition_score: float
1018
+ cell_posteriors: tuple[ResidualHeadroomCellPosterior, ...]
1019
+ ledger_state_sha256: str
1020
+ config_definition_sha256: str
1021
+ estimate_sha256: str = field(init=False)
1022
+
1023
+ def __post_init__(self) -> None:
1024
+ for name in (
1025
+ "context_sha256",
1026
+ "action_sha256",
1027
+ "ledger_state_sha256",
1028
+ "config_definition_sha256",
1029
+ ):
1030
+ require_sha256(getattr(self, name), name)
1031
+ if type(self.generation_index) is not int or self.generation_index < 0:
1032
+ raise ValueError("generation_index must be non-negative")
1033
+ for name in (
1034
+ "expected_normalized_gain",
1035
+ "uncertainty",
1036
+ "positive_probability",
1037
+ "invalid_probability",
1038
+ "redundancy_fraction",
1039
+ "late_bloom_headroom",
1040
+ "saturation_risk",
1041
+ "acquisition_score",
1042
+ ):
1043
+ _require_nonnegative(getattr(self, name), name=name)
1044
+ for name in (
1045
+ "positive_probability",
1046
+ "invalid_probability",
1047
+ "redundancy_fraction",
1048
+ ):
1049
+ if getattr(self, name) > 1.0:
1050
+ raise ValueError(f"{name} must not exceed one")
1051
+ if (
1052
+ type(self.cell_posteriors) is not tuple
1053
+ or not self.cell_posteriors
1054
+ or tuple(value.cell for value in self.cell_posteriors)
1055
+ != tuple(sorted({value.cell for value in self.cell_posteriors}))
1056
+ ):
1057
+ raise ValueError("cell posteriors must be non-empty and canonical")
1058
+ for value in self.cell_posteriors:
1059
+ if type(value) is not ResidualHeadroomCellPosterior:
1060
+ raise TypeError("cell posteriors must be exact")
1061
+ value.__post_init__()
1062
+ object.__setattr__(
1063
+ self,
1064
+ "estimate_sha256",
1065
+ _hash(_ESTIMATE_DOMAIN, self._unsigned_record()),
1066
+ )
1067
+
1068
+ def _unsigned_record(self) -> dict[str, object]:
1069
+ return {
1070
+ "schema_version": 1,
1071
+ "context_sha256": self.context_sha256,
1072
+ "action_sha256": self.action_sha256,
1073
+ "generation_index": self.generation_index,
1074
+ "expected_normalized_gain_hex": (
1075
+ self.expected_normalized_gain.hex()
1076
+ ),
1077
+ "uncertainty_hex": self.uncertainty.hex(),
1078
+ "positive_probability_hex": (
1079
+ self.positive_probability.hex()
1080
+ ),
1081
+ "invalid_probability_hex": self.invalid_probability.hex(),
1082
+ "redundancy_fraction_hex": self.redundancy_fraction.hex(),
1083
+ "late_bloom_headroom_hex": self.late_bloom_headroom.hex(),
1084
+ "saturation_risk_hex": self.saturation_risk.hex(),
1085
+ "acquisition_score_hex": self.acquisition_score.hex(),
1086
+ "cell_posteriors": [
1087
+ value.to_record() for value in self.cell_posteriors
1088
+ ],
1089
+ "ledger_state_sha256": self.ledger_state_sha256,
1090
+ "config_definition_sha256": self.config_definition_sha256,
1091
+ "predicted_value_admitted_to_archive": False,
1092
+ }
1093
+
1094
+ def to_record(self) -> dict[str, object]:
1095
+ self.__post_init__()
1096
+ return {
1097
+ **self._unsigned_record(),
1098
+ "estimate_sha256": self.estimate_sha256,
1099
+ }
1100
+
1101
+
1102
+ @dataclass(frozen=True, slots=True)
1103
+ class ConservedResidualHeadroomLedger:
1104
+ """Fold conserved closures and query action-level residual headroom."""
1105
+
1106
+ config: ResidualHeadroomLedgerConfig = field(
1107
+ default_factory=ResidualHeadroomLedgerConfig
1108
+ )
1109
+
1110
+ def __post_init__(self) -> None:
1111
+ if type(self.config) is not ResidualHeadroomLedgerConfig:
1112
+ raise TypeError("config must be exact")
1113
+ self.config.__post_init__()
1114
+
1115
+ def empty_state(self) -> ResidualHeadroomLedgerState:
1116
+ self.__post_init__()
1117
+ return ResidualHeadroomLedgerState(
1118
+ config_definition_sha256=self.config.definition_sha256,
1119
+ )
1120
+
1121
+ def append(
1122
+ self,
1123
+ state: ResidualHeadroomLedgerState,
1124
+ closure: ResidualHeadroomStageClosure,
1125
+ ) -> ResidualHeadroomLedgerState:
1126
+ self.__post_init__()
1127
+ if type(state) is not ResidualHeadroomLedgerState:
1128
+ raise TypeError("state must be exact")
1129
+ state.__post_init__()
1130
+ if (
1131
+ state.config_definition_sha256
1132
+ != self.config.definition_sha256
1133
+ ):
1134
+ raise ValueError("state belongs to another ledger configuration")
1135
+ if type(closure) is not ResidualHeadroomStageClosure:
1136
+ raise TypeError("closure must be exact")
1137
+ closure.__post_init__()
1138
+ return ResidualHeadroomLedgerState(
1139
+ config_definition_sha256=self.config.definition_sha256,
1140
+ closures=(*state.closures, closure),
1141
+ )
1142
+
1143
+ def _cell_posterior(
1144
+ self,
1145
+ *,
1146
+ state: ResidualHeadroomLedgerState,
1147
+ context_sha256: str,
1148
+ generation_index: int,
1149
+ cell: AdaptiveActionFactorCell,
1150
+ candidate_cell_count: int,
1151
+ ) -> ResidualHeadroomCellPosterior:
1152
+ samples: list[tuple[ResidualHeadroomObservation, float, float]] = []
1153
+ for closure in state.closures:
1154
+ for observation in closure.observations:
1155
+ if cell not in observation.attribution_cells:
1156
+ continue
1157
+ if observation.context_sha256 == context_sha256:
1158
+ if observation.generation_index > generation_index:
1159
+ continue
1160
+ context_weight = 1.0
1161
+ decay = self.config.generation_decay ** (
1162
+ generation_index - observation.generation_index
1163
+ )
1164
+ else:
1165
+ context_weight = self.config.cross_context_weight
1166
+ decay = 1.0
1167
+ if context_weight == 0.0:
1168
+ continue
1169
+ inverse_propensity = (
1170
+ min(
1171
+ self.config.maximum_inverse_propensity,
1172
+ 1.0 / observation.selection_propensity,
1173
+ )
1174
+ if observation.propensity_identified
1175
+ else 1.0
1176
+ )
1177
+ weight = context_weight * decay * inverse_propensity
1178
+ target = (
1179
+ observation.normalized_conditional_credit
1180
+ / len(observation.attribution_cells)
1181
+ )
1182
+ samples.append((observation, weight, target))
1183
+
1184
+ prior_mean = (
1185
+ self.config.prior_normalized_gain / candidate_cell_count
1186
+ )
1187
+ weighted_count = math.fsum(value[1] for value in samples)
1188
+ denominator = self.config.prior_strength + weighted_count
1189
+ posterior_mean = (
1190
+ self.config.prior_strength * prior_mean
1191
+ + math.fsum(weight * target for _, weight, target in samples)
1192
+ ) / denominator
1193
+ variance = math.fsum(
1194
+ weight * (target - posterior_mean) ** 2
1195
+ for _, weight, target in samples
1196
+ ) / denominator
1197
+ uncertainty = (
1198
+ math.sqrt(max(variance, 0.0) / denominator)
1199
+ + max(prior_mean, 1.0e-12) / math.sqrt(denominator)
1200
+ )
1201
+ positive_probability = (
1202
+ self.config.positive_prior_alpha
1203
+ + math.fsum(
1204
+ weight * float(observation.conditional_credit > 0.0)
1205
+ for observation, weight, _ in samples
1206
+ )
1207
+ ) / (
1208
+ self.config.positive_prior_alpha
1209
+ + self.config.positive_prior_beta
1210
+ + weighted_count
1211
+ )
1212
+ invalid_probability = (
1213
+ self.config.invalid_prior_alpha
1214
+ + math.fsum(
1215
+ weight * float(not observation.feasible)
1216
+ for observation, weight, _ in samples
1217
+ )
1218
+ ) / (
1219
+ self.config.invalid_prior_alpha
1220
+ + self.config.invalid_prior_beta
1221
+ + weighted_count
1222
+ )
1223
+ redundancy_fraction = (
1224
+ 0.0
1225
+ if weighted_count == 0.0
1226
+ else math.fsum(
1227
+ weight * observation.redundancy_fraction
1228
+ for observation, weight, _ in samples
1229
+ )
1230
+ / weighted_count
1231
+ )
1232
+ slope = 0.0
1233
+ distinct_waves = {
1234
+ observation.wave_index for observation, _, _ in samples
1235
+ }
1236
+ if weighted_count > 0.0 and len(distinct_waves) >= 2:
1237
+ mean_wave = math.fsum(
1238
+ weight * observation.wave_index
1239
+ for observation, weight, _ in samples
1240
+ ) / weighted_count
1241
+ mean_target = math.fsum(
1242
+ weight * target for _, weight, target in samples
1243
+ ) / weighted_count
1244
+ wave_variance = math.fsum(
1245
+ weight * (observation.wave_index - mean_wave) ** 2
1246
+ for observation, weight, _ in samples
1247
+ )
1248
+ if wave_variance > 0.0:
1249
+ slope = math.fsum(
1250
+ weight
1251
+ * (observation.wave_index - mean_wave)
1252
+ * (target - mean_target)
1253
+ for observation, weight, target in samples
1254
+ ) / wave_variance
1255
+ slope = max(
1256
+ -self.config.maximum_abs_slope,
1257
+ min(self.config.maximum_abs_slope, slope),
1258
+ )
1259
+ sum_weight_squared = math.fsum(
1260
+ weight * weight for _, weight, _ in samples
1261
+ )
1262
+ effective_sample_size = (
1263
+ 0.0
1264
+ if sum_weight_squared == 0.0
1265
+ else weighted_count * weighted_count / sum_weight_squared
1266
+ )
1267
+ return ResidualHeadroomCellPosterior(
1268
+ cell=cell,
1269
+ posterior_mean=float(posterior_mean),
1270
+ uncertainty=float(uncertainty),
1271
+ positive_probability=float(positive_probability),
1272
+ invalid_probability=float(invalid_probability),
1273
+ redundancy_fraction=float(redundancy_fraction),
1274
+ late_bloom_slope=float(max(slope, 0.0)),
1275
+ saturation_slope=float(max(-slope, 0.0)),
1276
+ effective_sample_size=float(effective_sample_size),
1277
+ raw_observation_count=len(samples),
1278
+ )
1279
+
1280
+ def estimate(
1281
+ self,
1282
+ *,
1283
+ state: ResidualHeadroomLedgerState,
1284
+ context_sha256: str,
1285
+ generation_index: int,
1286
+ action: AdaptiveActionDescriptor,
1287
+ ) -> ResidualHeadroomEstimate:
1288
+ self.__post_init__()
1289
+ if type(state) is not ResidualHeadroomLedgerState:
1290
+ raise TypeError("state must be exact")
1291
+ state.__post_init__()
1292
+ if (
1293
+ state.config_definition_sha256
1294
+ != self.config.definition_sha256
1295
+ ):
1296
+ raise ValueError("state belongs to another ledger configuration")
1297
+ require_sha256(context_sha256, "context_sha256")
1298
+ if type(generation_index) is not int or generation_index < 0:
1299
+ raise ValueError("generation_index must be non-negative")
1300
+ if type(action) is not AdaptiveActionDescriptor:
1301
+ raise TypeError("action must be exact")
1302
+ cells = _attribution_cells(action)
1303
+ posteriors = tuple(
1304
+ self._cell_posterior(
1305
+ state=state,
1306
+ context_sha256=context_sha256,
1307
+ generation_index=generation_index,
1308
+ cell=cell,
1309
+ candidate_cell_count=len(cells),
1310
+ )
1311
+ for cell in cells
1312
+ )
1313
+ expected = math.fsum(value.posterior_mean for value in posteriors)
1314
+ uncertainty = math.sqrt(
1315
+ math.fsum(value.uncertainty**2 for value in posteriors)
1316
+ )
1317
+ raw_count = sum(
1318
+ value.raw_observation_count for value in posteriors
1319
+ )
1320
+ uncertainty += self.config.exploration_floor / math.sqrt(
1321
+ 1.0 + raw_count
1322
+ )
1323
+ positive_probability = math.fsum(
1324
+ value.positive_probability for value in posteriors
1325
+ ) / len(posteriors)
1326
+ invalid_probability = math.fsum(
1327
+ value.invalid_probability for value in posteriors
1328
+ ) / len(posteriors)
1329
+ redundancy = math.fsum(
1330
+ value.redundancy_fraction for value in posteriors
1331
+ ) / len(posteriors)
1332
+ late_bloom = math.fsum(
1333
+ value.late_bloom_slope for value in posteriors
1334
+ )
1335
+ saturation = math.fsum(
1336
+ value.saturation_slope for value in posteriors
1337
+ )
1338
+ acquisition = max(
1339
+ 0.0,
1340
+ expected
1341
+ + self.config.uncertainty_strength * uncertainty
1342
+ + self.config.late_bloom_strength * late_bloom
1343
+ - self.config.saturation_strength * saturation
1344
+ - self.config.redundancy_strength * expected * redundancy
1345
+ - self.config.invalidity_strength
1346
+ * max(self.config.prior_normalized_gain, expected)
1347
+ * invalid_probability,
1348
+ )
1349
+ return ResidualHeadroomEstimate(
1350
+ context_sha256=context_sha256,
1351
+ action_sha256=action.action_sha256,
1352
+ generation_index=generation_index,
1353
+ expected_normalized_gain=float(expected),
1354
+ uncertainty=float(uncertainty),
1355
+ positive_probability=float(positive_probability),
1356
+ invalid_probability=float(invalid_probability),
1357
+ redundancy_fraction=float(redundancy),
1358
+ late_bloom_headroom=float(late_bloom),
1359
+ saturation_risk=float(saturation),
1360
+ acquisition_score=float(acquisition),
1361
+ cell_posteriors=posteriors,
1362
+ ledger_state_sha256=state.state_sha256,
1363
+ config_definition_sha256=self.config.definition_sha256,
1364
+ )
1365
+
1366
+
1367
+ @dataclass(frozen=True, slots=True)
1368
+ class ResidualHeadroomAdaptiveMarketProjector:
1369
+ """Blend prior-only headroom ranks into any portable adaptive market."""
1370
+
1371
+ delegate: AdaptiveActionMarketProjectorPort = field(
1372
+ repr=False,
1373
+ compare=False,
1374
+ )
1375
+ ledger: ConservedResidualHeadroomLedger = field(
1376
+ repr=False,
1377
+ compare=False,
1378
+ )
1379
+ ledger_state: ResidualHeadroomLedgerState
1380
+ context_sha256: str
1381
+ base_prior_weight: float = 1.0
1382
+ headroom_weight: float = 1.0
1383
+ projector_id: str = RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_ID
1384
+ projector_version: int = (
1385
+ RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_VERSION
1386
+ )
1387
+ definition_sha256: str = field(init=False)
1388
+ state_sha256: str = field(init=False)
1389
+
1390
+ def __post_init__(self) -> None:
1391
+ if not isinstance(self.delegate, AdaptiveActionMarketProjectorPort):
1392
+ raise TypeError("delegate must implement the adaptive market port")
1393
+ self.delegate.__post_init__()
1394
+ if type(self.ledger) is not ConservedResidualHeadroomLedger:
1395
+ raise TypeError("ledger must be exact")
1396
+ self.ledger.__post_init__()
1397
+ if type(self.ledger_state) is not ResidualHeadroomLedgerState:
1398
+ raise TypeError("ledger_state must be exact")
1399
+ self.ledger_state.__post_init__()
1400
+ if (
1401
+ self.ledger_state.config_definition_sha256
1402
+ != self.ledger.config.definition_sha256
1403
+ ):
1404
+ raise ValueError("ledger state belongs to another configuration")
1405
+ require_sha256(self.context_sha256, "context_sha256")
1406
+ for value, name in (
1407
+ (self.base_prior_weight, "base_prior_weight"),
1408
+ (self.headroom_weight, "headroom_weight"),
1409
+ ):
1410
+ if (
1411
+ type(value) is not float
1412
+ or not math.isfinite(value)
1413
+ or value < 0.0
1414
+ ):
1415
+ raise ValueError(f"{name} must be finite and non-negative")
1416
+ if self.base_prior_weight + self.headroom_weight <= 0.0:
1417
+ raise ValueError("at least one projector weight must be positive")
1418
+ if (
1419
+ self.projector_id
1420
+ != RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_ID
1421
+ or self.projector_version
1422
+ != RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_VERSION
1423
+ ):
1424
+ raise ValueError("projector identity is immutable")
1425
+ object.__setattr__(
1426
+ self,
1427
+ "definition_sha256",
1428
+ _hash(
1429
+ _MARKET_PROJECTOR_DOMAIN,
1430
+ {
1431
+ "schema_version": 1,
1432
+ "projector_id": self.projector_id,
1433
+ "projector_version": self.projector_version,
1434
+ "delegate_definition_sha256": (
1435
+ self.delegate.definition_sha256
1436
+ ),
1437
+ "ledger_config_definition_sha256": (
1438
+ self.ledger.config.definition_sha256
1439
+ ),
1440
+ "base_prior_weight_hex": self.base_prior_weight.hex(),
1441
+ "headroom_weight_hex": self.headroom_weight.hex(),
1442
+ "normalization": (
1443
+ "within-sealed-market-tie-preserving-rank-percentile"
1444
+ ),
1445
+ "candidate_outcomes_observed": False,
1446
+ "predicted_values_admitted_to_archive": False,
1447
+ "workload_objective_model_provider_prompt_config_branches": (
1448
+ False
1449
+ ),
1450
+ },
1451
+ ),
1452
+ )
1453
+ object.__setattr__(
1454
+ self,
1455
+ "state_sha256",
1456
+ _hash(
1457
+ _MARKET_STATE_DOMAIN,
1458
+ {
1459
+ "schema_version": 1,
1460
+ "projector_definition_sha256": self.definition_sha256,
1461
+ "delegate_state_sha256": self.delegate.state_sha256,
1462
+ "ledger_state_sha256": self.ledger_state.state_sha256,
1463
+ "context_sha256": self.context_sha256,
1464
+ },
1465
+ ),
1466
+ )
1467
+
1468
+ @staticmethod
1469
+ def _rank_percentiles(
1470
+ values: dict[str, float],
1471
+ ) -> dict[str, float]:
1472
+ unique = sorted(set(values.values()))
1473
+ if len(unique) == 1:
1474
+ return {key: 0.5 for key in values}
1475
+ percentile = {
1476
+ value: index / (len(unique) - 1)
1477
+ for index, value in enumerate(unique)
1478
+ }
1479
+ return {key: percentile[value] for key, value in values.items()}
1480
+
1481
+ async def project(
1482
+ self,
1483
+ request: ResidualPortfolioDecisionRequest,
1484
+ proposals: tuple[MaterializedActionProposalBatch, ...],
1485
+ actions: tuple[MaterializedActionDescriptor, ...],
1486
+ scores: tuple[BrokerActionScore, ...],
1487
+ required_action_sha256s: tuple[str, ...],
1488
+ ) -> tuple[AdaptiveActionDescriptor, ...]:
1489
+ self.__post_init__()
1490
+ projected = await self.delegate.project(
1491
+ request,
1492
+ proposals,
1493
+ actions,
1494
+ scores,
1495
+ required_action_sha256s,
1496
+ )
1497
+ # A cold ledger contains no evidence with which to alter the existing
1498
+ # prior. Returning the delegate values exactly avoids manufacturing a
1499
+ # ranking from attribution-cardinality or hash tie breaks.
1500
+ if not self.ledger_state.closures:
1501
+ return projected
1502
+ estimates = {
1503
+ action.action_sha256: self.ledger.estimate(
1504
+ state=self.ledger_state,
1505
+ context_sha256=self.context_sha256,
1506
+ generation_index=request.decision_index,
1507
+ action=action,
1508
+ ).acquisition_score
1509
+ for action in projected
1510
+ }
1511
+ headroom_percentiles = self._rank_percentiles(estimates)
1512
+ denominator = self.base_prior_weight + self.headroom_weight
1513
+ return tuple(
1514
+ replace(
1515
+ action,
1516
+ prior_score=float(
1517
+ (
1518
+ self.base_prior_weight * action.prior_score
1519
+ + self.headroom_weight
1520
+ * headroom_percentiles[action.action_sha256]
1521
+ )
1522
+ / denominator
1523
+ ),
1524
+ )
1525
+ for action in projected
1526
+ )
1527
+
1528
+
1529
+ __all__ = [
1530
+ "ConservedResidualHeadroomLedger",
1531
+ "ConservedResidualHeadroomProjector",
1532
+ "ResidualHeadroomAdaptiveMarketProjector",
1533
+ "ResidualHeadroomCellPosterior",
1534
+ "ResidualHeadroomEstimate",
1535
+ "ResidualHeadroomLedgerConfig",
1536
+ "ResidualHeadroomLedgerState",
1537
+ "ResidualHeadroomObservation",
1538
+ "ResidualHeadroomStageClosure",
1539
+ "RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_ID",
1540
+ "RESIDUAL_HEADROOM_ADAPTIVE_MARKET_PROJECTOR_VERSION",
1541
+ "RESIDUAL_HEADROOM_LEDGER_DEFINITION_SHA256",
1542
+ "RESIDUAL_HEADROOM_LEDGER_ID",
1543
+ "RESIDUAL_HEADROOM_LEDGER_VERSION",
1544
+ ]