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,547 @@
1
+ """Workload-neutral trajectory-preserving evaluation escrow contracts.
2
+
3
+ Challenger evaluations are recorded as debt against a protected native
4
+ optimizer. Debt is settled only by withholding terminal backbone units, so
5
+ every retained backbone action has the same ask/tell history it would have had
6
+ without challengers. This module owns accounting and evidence; workload
7
+ adapters own candidates, evaluators, and native optimizer state.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass, field
13
+ from enum import Enum
14
+ import hashlib
15
+ import json
16
+ import re
17
+
18
+ from agent_evolve.domain.ids import CandidateId
19
+ from agent_evolve.domain.patch import require_sha256
20
+
21
+
22
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
23
+ _POLICY_DOMAIN = b"agent-evolve:evaluation-escrow-policy:v1\x00"
24
+ _CAPACITY_DOMAIN = b"agent-evolve:terminal-settlement-capacity:v1\x00"
25
+ _LOAN_DOMAIN = b"agent-evolve:challenger-evaluation-loan:v1\x00"
26
+ _UNIT_DOMAIN = b"agent-evolve:backbone-settlement-unit:v1\x00"
27
+ _SETTLEMENT_DOMAIN = b"agent-evolve:evaluation-escrow-settlement:v1\x00"
28
+
29
+
30
+ def _canonical_bytes(value: object) -> bytes:
31
+ return json.dumps(
32
+ value,
33
+ allow_nan=False,
34
+ ensure_ascii=True,
35
+ separators=(",", ":"),
36
+ sort_keys=True,
37
+ ).encode("ascii", errors="strict")
38
+
39
+
40
+ def _hash(domain: bytes, value: object) -> str:
41
+ return hashlib.sha256(domain + _canonical_bytes(value)).hexdigest()
42
+
43
+
44
+ def _token(value: str, name: str) -> None:
45
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
46
+ raise ValueError(f"{name} must use the closed token grammar")
47
+
48
+
49
+ class ChallengerLoanKind(str, Enum):
50
+ COLD_START_EXPLORATION = "cold_start_exploration"
51
+ EARNED_REPRODUCTION = "earned_reproduction"
52
+
53
+
54
+ class TerminalSettlementMode(str, Enum):
55
+ SEQUENTIAL_TRUNCATION = "sequential_truncation"
56
+ FINAL_BATCH_WITHHOLDING = "final_batch_withholding"
57
+
58
+
59
+ @dataclass(frozen=True, slots=True)
60
+ class EvaluationEscrowPolicy:
61
+ """Frozen debt authority; model and workload identity are intentionally absent."""
62
+
63
+ policy_id: str = "trajectory_preserving_evaluation_escrow"
64
+ policy_version: int = 1
65
+ maximum_open_debt: int = 2
66
+
67
+ def __post_init__(self) -> None:
68
+ _token(self.policy_id, "policy_id")
69
+ if type(self.policy_version) is not int or self.policy_version <= 0:
70
+ raise ValueError("policy_version must be positive")
71
+ if type(self.maximum_open_debt) is not int or self.maximum_open_debt <= 0:
72
+ raise ValueError("maximum_open_debt must be positive")
73
+
74
+ def _unsigned_record(self) -> dict[str, object]:
75
+ self.__post_init__()
76
+ return {
77
+ "schema_version": 1,
78
+ "policy_id": self.policy_id,
79
+ "policy_version": self.policy_version,
80
+ "maximum_open_debt": self.maximum_open_debt,
81
+ "challenger_outcomes_visible_to_backbone": False,
82
+ "settlement_scope": "terminal_only_after_last_retained_transition",
83
+ "workload_model_provider_fields_consulted": False,
84
+ }
85
+
86
+ @property
87
+ def definition_sha256(self) -> str:
88
+ return _hash(_POLICY_DOMAIN, self._unsigned_record())
89
+
90
+ def to_record(self) -> dict[str, object]:
91
+ return {**self._unsigned_record(), "definition_sha256": self.definition_sha256}
92
+
93
+
94
+ @dataclass(frozen=True, slots=True)
95
+ class TerminalSettlementCapacityReceipt:
96
+ """Adapter proof that a terminal tail can repay a bounded debt."""
97
+
98
+ physical_evaluation_budget: int
99
+ maximum_settlement_units: int
100
+ mode: TerminalSettlementMode
101
+ backbone_schedule_definition_sha256: str
102
+ campaign_scope_sha256: str
103
+ capability_receipt_sha256: str
104
+
105
+ def __post_init__(self) -> None:
106
+ if (
107
+ type(self.physical_evaluation_budget) is not int
108
+ or self.physical_evaluation_budget <= 0
109
+ ):
110
+ raise ValueError("physical_evaluation_budget must be positive")
111
+ if (
112
+ type(self.maximum_settlement_units) is not int
113
+ or not 0 < self.maximum_settlement_units
114
+ < self.physical_evaluation_budget
115
+ ):
116
+ raise ValueError(
117
+ "maximum_settlement_units must lie inside the physical budget"
118
+ )
119
+ if type(self.mode) is not TerminalSettlementMode:
120
+ raise TypeError("mode must be an exact TerminalSettlementMode")
121
+ for name in (
122
+ "backbone_schedule_definition_sha256",
123
+ "campaign_scope_sha256",
124
+ "capability_receipt_sha256",
125
+ ):
126
+ require_sha256(getattr(self, name), name)
127
+
128
+ def _unsigned_record(self) -> dict[str, object]:
129
+ self.__post_init__()
130
+ return {
131
+ "schema_version": 1,
132
+ "physical_evaluation_budget": self.physical_evaluation_budget,
133
+ "maximum_settlement_units": self.maximum_settlement_units,
134
+ "mode": self.mode.value,
135
+ "backbone_schedule_definition_sha256": (
136
+ self.backbone_schedule_definition_sha256
137
+ ),
138
+ "campaign_scope_sha256": self.campaign_scope_sha256,
139
+ "capability_receipt_sha256": self.capability_receipt_sha256,
140
+ "settlement_after_last_retained_state_transition": True,
141
+ }
142
+
143
+ @property
144
+ def receipt_sha256(self) -> str:
145
+ return _hash(_CAPACITY_DOMAIN, self._unsigned_record())
146
+
147
+ def to_record(self) -> dict[str, object]:
148
+ return {**self._unsigned_record(), "receipt_sha256": self.receipt_sha256}
149
+
150
+
151
+ @dataclass(frozen=True, slots=True)
152
+ class ChallengerEvaluationLoan:
153
+ """One completed real challenger evaluation and its debt unit."""
154
+
155
+ candidate_id: CandidateId
156
+ proposal_provenance_sha256: str
157
+ evaluation_receipt_sha256: str
158
+ issued_after_backbone_evaluation_count: int
159
+ generation: int
160
+ kind: ChallengerLoanKind
161
+ source_ticket_sha256: str | None
162
+ backbone_state_sha256: str
163
+ policy_definition_sha256: str
164
+
165
+ def __post_init__(self) -> None:
166
+ if type(self.candidate_id) is not CandidateId:
167
+ raise TypeError("candidate_id must be an exact CandidateId")
168
+ CandidateId.__post_init__(self.candidate_id)
169
+ for name in (
170
+ "proposal_provenance_sha256",
171
+ "evaluation_receipt_sha256",
172
+ "backbone_state_sha256",
173
+ "policy_definition_sha256",
174
+ ):
175
+ require_sha256(getattr(self, name), name)
176
+ if (
177
+ type(self.issued_after_backbone_evaluation_count) is not int
178
+ or self.issued_after_backbone_evaluation_count < 0
179
+ ):
180
+ raise ValueError(
181
+ "issued_after_backbone_evaluation_count must be non-negative"
182
+ )
183
+ if type(self.generation) is not int or self.generation <= 0:
184
+ raise ValueError("generation must be positive")
185
+ if type(self.kind) is not ChallengerLoanKind:
186
+ raise TypeError("kind must be an exact ChallengerLoanKind")
187
+ if self.kind is ChallengerLoanKind.EARNED_REPRODUCTION:
188
+ if self.source_ticket_sha256 is None:
189
+ raise ValueError("earned reproduction requires its source ticket")
190
+ require_sha256(self.source_ticket_sha256, "source_ticket_sha256")
191
+ elif self.source_ticket_sha256 is not None:
192
+ raise ValueError("cold-start exploration cannot consume a lineage ticket")
193
+
194
+ def _unsigned_record(self) -> dict[str, object]:
195
+ self.__post_init__()
196
+ return {
197
+ "schema_version": 1,
198
+ "candidate_id": self.candidate_id.value,
199
+ "proposal_provenance_sha256": self.proposal_provenance_sha256,
200
+ "evaluation_receipt_sha256": self.evaluation_receipt_sha256,
201
+ "issued_after_backbone_evaluation_count": (
202
+ self.issued_after_backbone_evaluation_count
203
+ ),
204
+ "generation": self.generation,
205
+ "kind": self.kind.value,
206
+ "source_ticket_sha256": self.source_ticket_sha256,
207
+ "backbone_state_sha256": self.backbone_state_sha256,
208
+ "policy_definition_sha256": self.policy_definition_sha256,
209
+ "physical_evaluation_units": 1,
210
+ "outcome_visible_to_backbone_optimizer": False,
211
+ }
212
+
213
+ @property
214
+ def loan_sha256(self) -> str:
215
+ return _hash(_LOAN_DOMAIN, self._unsigned_record())
216
+
217
+ def to_record(self) -> dict[str, object]:
218
+ return {**self._unsigned_record(), "loan_sha256": self.loan_sha256}
219
+
220
+
221
+ @dataclass(frozen=True, slots=True)
222
+ class BackboneSettlementUnit:
223
+ """One terminal native evaluation withheld to repay one challenger loan."""
224
+
225
+ unit_index: int
226
+ backbone_sequence_index: int
227
+ mode: TerminalSettlementMode
228
+ terminal_state_sha256: str
229
+ settlement_decision_receipt_sha256: str
230
+ candidate_id: CandidateId | None = None
231
+ ask_receipt_sha256: str | None = None
232
+ prior_ranking_receipt_sha256: str | None = None
233
+
234
+ def __post_init__(self) -> None:
235
+ if type(self.unit_index) is not int or self.unit_index <= 0:
236
+ raise ValueError("unit_index must be positive")
237
+ if type(self.backbone_sequence_index) is not int or (
238
+ self.backbone_sequence_index <= 0
239
+ ):
240
+ raise ValueError("backbone_sequence_index must be positive")
241
+ if type(self.mode) is not TerminalSettlementMode:
242
+ raise TypeError("mode must be an exact TerminalSettlementMode")
243
+ require_sha256(self.terminal_state_sha256, "terminal_state_sha256")
244
+ require_sha256(
245
+ self.settlement_decision_receipt_sha256,
246
+ "settlement_decision_receipt_sha256",
247
+ )
248
+ if self.mode is TerminalSettlementMode.FINAL_BATCH_WITHHOLDING:
249
+ if type(self.candidate_id) is not CandidateId:
250
+ raise TypeError("final-batch withholding requires a candidate_id")
251
+ CandidateId.__post_init__(self.candidate_id)
252
+ if self.ask_receipt_sha256 is None:
253
+ raise ValueError("final-batch withholding requires an ask receipt")
254
+ if self.prior_ranking_receipt_sha256 is None:
255
+ raise ValueError(
256
+ "final-batch withholding requires a prior ranking receipt"
257
+ )
258
+ require_sha256(self.ask_receipt_sha256, "ask_receipt_sha256")
259
+ require_sha256(
260
+ self.prior_ranking_receipt_sha256,
261
+ "prior_ranking_receipt_sha256",
262
+ )
263
+ elif any(
264
+ value is not None
265
+ for value in (
266
+ self.candidate_id,
267
+ self.ask_receipt_sha256,
268
+ self.prior_ranking_receipt_sha256,
269
+ )
270
+ ):
271
+ raise ValueError(
272
+ "sequential truncation cannot name an unasked future candidate"
273
+ )
274
+
275
+ def _unsigned_record(self) -> dict[str, object]:
276
+ self.__post_init__()
277
+ return {
278
+ "schema_version": 1,
279
+ "unit_index": self.unit_index,
280
+ "backbone_sequence_index": self.backbone_sequence_index,
281
+ "mode": self.mode.value,
282
+ "terminal_state_sha256": self.terminal_state_sha256,
283
+ "settlement_decision_receipt_sha256": (
284
+ self.settlement_decision_receipt_sha256
285
+ ),
286
+ "candidate_id": (
287
+ None if self.candidate_id is None else self.candidate_id.value
288
+ ),
289
+ "ask_receipt_sha256": self.ask_receipt_sha256,
290
+ "prior_ranking_receipt_sha256": self.prior_ranking_receipt_sha256,
291
+ "physical_evaluation_units_withheld": 1,
292
+ "later_backbone_state_transitions_allowed": False,
293
+ }
294
+
295
+ @property
296
+ def unit_sha256(self) -> str:
297
+ return _hash(_UNIT_DOMAIN, self._unsigned_record())
298
+
299
+ def to_record(self) -> dict[str, object]:
300
+ return {**self._unsigned_record(), "unit_sha256": self.unit_sha256}
301
+
302
+
303
+ @dataclass(frozen=True, slots=True)
304
+ class EvaluationEscrowSettlement:
305
+ """Exact physical-budget and no-path-interference closure receipt."""
306
+
307
+ policy_definition_sha256: str
308
+ capacity_receipt_sha256: str
309
+ physical_evaluation_budget: int
310
+ actual_backbone_evaluations: int
311
+ loans: tuple[ChallengerEvaluationLoan, ...]
312
+ settlement_units: tuple[BackboneSettlementUnit, ...]
313
+ retained_backbone_prefix_receipt_sha256: str
314
+ final_union_archive_receipt_sha256: str
315
+
316
+ def __post_init__(self) -> None:
317
+ require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
318
+ require_sha256(self.capacity_receipt_sha256, "capacity_receipt_sha256")
319
+ if (
320
+ type(self.physical_evaluation_budget) is not int
321
+ or self.physical_evaluation_budget <= 0
322
+ ):
323
+ raise ValueError("physical_evaluation_budget must be positive")
324
+ if (
325
+ type(self.actual_backbone_evaluations) is not int
326
+ or self.actual_backbone_evaluations < 0
327
+ ):
328
+ raise ValueError("actual_backbone_evaluations must be non-negative")
329
+ if type(self.loans) is not tuple or not self.loans or any(
330
+ type(value) is not ChallengerEvaluationLoan for value in self.loans
331
+ ):
332
+ raise ValueError("loans must be a non-empty exact tuple")
333
+ if type(self.settlement_units) is not tuple or not self.settlement_units or any(
334
+ type(value) is not BackboneSettlementUnit
335
+ for value in self.settlement_units
336
+ ):
337
+ raise ValueError("settlement_units must be a non-empty exact tuple")
338
+ for value in self.loans:
339
+ ChallengerEvaluationLoan.__post_init__(value)
340
+ if value.policy_definition_sha256 != self.policy_definition_sha256:
341
+ raise ValueError("loan uses another escrow policy")
342
+ for value in self.settlement_units:
343
+ BackboneSettlementUnit.__post_init__(value)
344
+ if len(self.loans) != len(self.settlement_units):
345
+ raise ValueError("settlement units must close every debt unit exactly")
346
+ if len({value.candidate_id for value in self.loans}) != len(self.loans):
347
+ raise ValueError("settlement repeats a challenger loan candidate")
348
+ if any(
349
+ value.issued_after_backbone_evaluation_count
350
+ > self.actual_backbone_evaluations
351
+ for value in self.loans
352
+ ):
353
+ raise ValueError(
354
+ "challenger loan was issued after the retained backbone prefix"
355
+ )
356
+ if tuple(value.unit_index for value in self.settlement_units) != tuple(
357
+ range(1, len(self.settlement_units) + 1)
358
+ ):
359
+ raise ValueError("settlement unit indices must be canonical")
360
+ sequence_indices = tuple(
361
+ value.backbone_sequence_index for value in self.settlement_units
362
+ )
363
+ if len(set(sequence_indices)) != len(sequence_indices):
364
+ raise ValueError("settlement repeats a backbone sequence index")
365
+ modes = {value.mode for value in self.settlement_units}
366
+ if len(modes) != 1:
367
+ raise ValueError("one settlement cannot mix adapter modes")
368
+ if self.actual_backbone_evaluations + len(self.loans) != (
369
+ self.physical_evaluation_budget
370
+ ):
371
+ raise ValueError("real backbone and challenger evaluations exceed budget")
372
+ if self.actual_backbone_evaluations + len(self.settlement_units) != (
373
+ self.physical_evaluation_budget
374
+ ):
375
+ raise ValueError("withheld units do not close the planned backbone budget")
376
+ mode = next(iter(modes))
377
+ if mode is TerminalSettlementMode.SEQUENTIAL_TRUNCATION and (
378
+ sequence_indices
379
+ != tuple(
380
+ range(
381
+ self.actual_backbone_evaluations + 1,
382
+ self.physical_evaluation_budget + 1,
383
+ )
384
+ )
385
+ ):
386
+ raise ValueError(
387
+ "sequential settlement must name the exact terminal backbone tail"
388
+ )
389
+ withheld_candidate_ids = tuple(
390
+ value.candidate_id
391
+ for value in self.settlement_units
392
+ if value.candidate_id is not None
393
+ )
394
+ if len(set(withheld_candidate_ids)) != len(withheld_candidate_ids):
395
+ raise ValueError("settlement repeats a withheld backbone candidate")
396
+ require_sha256(
397
+ self.retained_backbone_prefix_receipt_sha256,
398
+ "retained_backbone_prefix_receipt_sha256",
399
+ )
400
+ require_sha256(
401
+ self.final_union_archive_receipt_sha256,
402
+ "final_union_archive_receipt_sha256",
403
+ )
404
+
405
+ def _unsigned_record(self) -> dict[str, object]:
406
+ self.__post_init__()
407
+ return {
408
+ "schema_version": 1,
409
+ "policy_definition_sha256": self.policy_definition_sha256,
410
+ "capacity_receipt_sha256": self.capacity_receipt_sha256,
411
+ "physical_evaluation_budget": self.physical_evaluation_budget,
412
+ "actual_backbone_evaluations": self.actual_backbone_evaluations,
413
+ "actual_challenger_evaluations": len(self.loans),
414
+ "loans": [value.to_record() for value in self.loans],
415
+ "settlement_units": [
416
+ value.to_record() for value in self.settlement_units
417
+ ],
418
+ "retained_backbone_prefix_receipt_sha256": (
419
+ self.retained_backbone_prefix_receipt_sha256
420
+ ),
421
+ "final_union_archive_receipt_sha256": (
422
+ self.final_union_archive_receipt_sha256
423
+ ),
424
+ "physical_budget_closed": True,
425
+ "open_debt_units": 0,
426
+ "path_interference_for_retained_backbone": False,
427
+ }
428
+
429
+ @property
430
+ def settlement_sha256(self) -> str:
431
+ return _hash(_SETTLEMENT_DOMAIN, self._unsigned_record())
432
+
433
+ def to_record(self) -> dict[str, object]:
434
+ return {
435
+ **self._unsigned_record(),
436
+ "settlement_sha256": self.settlement_sha256,
437
+ }
438
+
439
+
440
+ @dataclass(slots=True)
441
+ class EvaluationEscrowLedger:
442
+ """Mutable campaign ledger with one final, immutable settlement."""
443
+
444
+ policy: EvaluationEscrowPolicy
445
+ capacity: TerminalSettlementCapacityReceipt
446
+ _loans: list[ChallengerEvaluationLoan] = field(
447
+ init=False,
448
+ default_factory=list,
449
+ )
450
+ _settlement: EvaluationEscrowSettlement | None = field(
451
+ init=False,
452
+ default=None,
453
+ )
454
+ _version: int = field(init=False, default=0)
455
+
456
+ def __post_init__(self) -> None:
457
+ if type(self.policy) is not EvaluationEscrowPolicy:
458
+ raise TypeError("policy must be an exact EvaluationEscrowPolicy")
459
+ if type(self.capacity) is not TerminalSettlementCapacityReceipt:
460
+ raise TypeError(
461
+ "capacity must be an exact TerminalSettlementCapacityReceipt"
462
+ )
463
+ EvaluationEscrowPolicy.__post_init__(self.policy)
464
+ TerminalSettlementCapacityReceipt.__post_init__(self.capacity)
465
+ if self.policy.maximum_open_debt > self.capacity.maximum_settlement_units:
466
+ raise ValueError("policy debt cap exceeds terminal settlement capacity")
467
+
468
+ @property
469
+ def version(self) -> int:
470
+ return self._version
471
+
472
+ @property
473
+ def open_debt_units(self) -> int:
474
+ return 0 if self._settlement is not None else len(self._loans)
475
+
476
+ def record_loan(self, loan: ChallengerEvaluationLoan) -> None:
477
+ if self._settlement is not None:
478
+ raise RuntimeError("settled escrow cannot accept another loan")
479
+ if type(loan) is not ChallengerEvaluationLoan:
480
+ raise TypeError("loan must be an exact ChallengerEvaluationLoan")
481
+ ChallengerEvaluationLoan.__post_init__(loan)
482
+ if loan.policy_definition_sha256 != self.policy.definition_sha256:
483
+ raise ValueError("loan uses another escrow policy")
484
+ if len(self._loans) >= self.policy.maximum_open_debt:
485
+ raise ValueError("challenger loan exceeds the frozen debt cap")
486
+ if any(value.candidate_id == loan.candidate_id for value in self._loans):
487
+ raise ValueError("one challenger candidate cannot incur debt twice")
488
+ self._loans.append(loan)
489
+ self._version += 1
490
+
491
+ def settle(
492
+ self,
493
+ *,
494
+ settlement_units: tuple[BackboneSettlementUnit, ...],
495
+ actual_backbone_evaluations: int,
496
+ retained_backbone_prefix_receipt_sha256: str,
497
+ final_union_archive_receipt_sha256: str,
498
+ ) -> EvaluationEscrowSettlement:
499
+ if self._settlement is not None:
500
+ raise RuntimeError("evaluation escrow was already settled")
501
+ if not self._loans:
502
+ raise ValueError("debt-free escrow needs no settlement")
503
+ if any(value.mode is not self.capacity.mode for value in settlement_units):
504
+ raise ValueError("settlement mode differs from adapter capacity")
505
+ if len(settlement_units) > self.capacity.maximum_settlement_units:
506
+ raise ValueError("settlement exceeds adapter terminal capacity")
507
+ settlement = EvaluationEscrowSettlement(
508
+ policy_definition_sha256=self.policy.definition_sha256,
509
+ capacity_receipt_sha256=self.capacity.receipt_sha256,
510
+ physical_evaluation_budget=self.capacity.physical_evaluation_budget,
511
+ actual_backbone_evaluations=actual_backbone_evaluations,
512
+ loans=tuple(self._loans),
513
+ settlement_units=settlement_units,
514
+ retained_backbone_prefix_receipt_sha256=(
515
+ retained_backbone_prefix_receipt_sha256
516
+ ),
517
+ final_union_archive_receipt_sha256=final_union_archive_receipt_sha256,
518
+ )
519
+ self._settlement = settlement
520
+ self._version += 1
521
+ return settlement
522
+
523
+ def to_record(self) -> dict[str, object]:
524
+ return {
525
+ "schema_version": 1,
526
+ "policy": self.policy.to_record(),
527
+ "capacity": self.capacity.to_record(),
528
+ "ledger_version": self._version,
529
+ "loans": [value.to_record() for value in self._loans],
530
+ "open_debt_units": self.open_debt_units,
531
+ "settlement": (
532
+ None if self._settlement is None else self._settlement.to_record()
533
+ ),
534
+ "workload_model_provider_fields_consulted": False,
535
+ }
536
+
537
+
538
+ __all__ = [
539
+ "BackboneSettlementUnit",
540
+ "ChallengerEvaluationLoan",
541
+ "ChallengerLoanKind",
542
+ "EvaluationEscrowLedger",
543
+ "EvaluationEscrowPolicy",
544
+ "EvaluationEscrowSettlement",
545
+ "TerminalSettlementCapacityReceipt",
546
+ "TerminalSettlementMode",
547
+ ]