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,396 @@
1
+ """Workload-neutral port for coordinated Pareto-frontier search targets."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import math
8
+ import re
9
+ from dataclasses import dataclass, field
10
+ from typing import TYPE_CHECKING, Protocol, runtime_checkable
11
+
12
+ from agent_evolve.domain.patch import require_sha256
13
+ from agent_evolve.domain.typed_json import (
14
+ FrozenJsonObject,
15
+ freeze_json,
16
+ thaw_json,
17
+ typed_json_sha256,
18
+ )
19
+
20
+ if TYPE_CHECKING:
21
+ from agent_evolve.application.agentic_evolution import EvolutionCandidate
22
+ from agent_evolve.application.evolution_campaign import ArchiveUtilitySnapshot
23
+
24
+
25
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
26
+ _TARGET_DOMAIN = b"agent-evolve:campaign-frontier-region-target:v1\x00"
27
+
28
+
29
+ def _canonical_json(value: object) -> bytes:
30
+ return json.dumps(
31
+ value,
32
+ allow_nan=False,
33
+ ensure_ascii=True,
34
+ separators=(",", ":"),
35
+ sort_keys=True,
36
+ ).encode("ascii", errors="strict")
37
+
38
+
39
+ def _finite_decimal(value: object, *, name: str) -> float:
40
+ """Decode the canonical decimal text used by frontier-target payloads."""
41
+
42
+ if type(value) is not str or not value:
43
+ raise TypeError(f"{name} must be non-empty decimal text")
44
+ try:
45
+ decoded = float(value)
46
+ except ValueError as error:
47
+ raise ValueError(f"{name} must be finite decimal text") from error
48
+ if not math.isfinite(decoded):
49
+ raise ValueError(f"{name} must be finite decimal text")
50
+ return decoded
51
+
52
+
53
+ @dataclass(frozen=True, slots=True)
54
+ class ObjectiveSpaceTargetAxis:
55
+ """One authenticated parent-to-aspiration axis in raw metric units.
56
+
57
+ This is deliberately a port-level value. Action forecasters and set
58
+ allocators can consume it without importing the residual-frontier policy
59
+ that happened to produce it, and benchmark adapters never need to expose
60
+ workload names or known-good configurations.
61
+ """
62
+
63
+ metric_id: str
64
+ goal: str
65
+ ideal: float
66
+ reference: float
67
+ parent_value: float
68
+ aspiration_value: float
69
+ signed_parent_to_aspiration_delta: float
70
+ improving_raw_delta_sign: str
71
+
72
+ def __post_init__(self) -> None:
73
+ if type(self.metric_id) is not str or _TOKEN.fullmatch(self.metric_id) is None:
74
+ raise ValueError("objective target metric_id must use the closed grammar")
75
+ if self.goal not in {"min", "max"}:
76
+ raise ValueError("objective target goal must be min or max")
77
+ for name in (
78
+ "ideal",
79
+ "reference",
80
+ "parent_value",
81
+ "aspiration_value",
82
+ "signed_parent_to_aspiration_delta",
83
+ ):
84
+ value = getattr(self, name)
85
+ if type(value) is not float or not math.isfinite(value):
86
+ raise TypeError(f"{name} must be a finite exact float")
87
+ if self.goal == "min" and not self.reference > self.ideal:
88
+ raise ValueError("minimization target reference must exceed ideal")
89
+ if self.goal == "max" and not self.ideal > self.reference:
90
+ raise ValueError("maximization target ideal must exceed reference")
91
+ expected_sign = "negative" if self.goal == "min" else "positive"
92
+ if self.improving_raw_delta_sign != expected_sign:
93
+ raise ValueError("objective target improving sign differs from its goal")
94
+ if (
95
+ self.aspiration_value - self.parent_value
96
+ != self.signed_parent_to_aspiration_delta
97
+ ):
98
+ raise ValueError("objective target signed delta differs from its endpoints")
99
+
100
+ def normalize(self, value: float) -> float:
101
+ """Map raw metric units into the shared lower-is-better affine frame."""
102
+
103
+ self.__post_init__()
104
+ if type(value) is not float or not math.isfinite(value):
105
+ raise TypeError("objective target value must be a finite exact float")
106
+ if self.goal == "min":
107
+ return (value - self.ideal) / (self.reference - self.ideal)
108
+ return (self.ideal - value) / (self.ideal - self.reference)
109
+
110
+ @property
111
+ def parent_normalized(self) -> float:
112
+ return self.normalize(self.parent_value)
113
+
114
+ @property
115
+ def aspiration_normalized(self) -> float:
116
+ return self.normalize(self.aspiration_value)
117
+
118
+ @property
119
+ def parent_shortfall(self) -> float:
120
+ """One-sided distance by which the parent fails to dominate the target."""
121
+
122
+ return max(0.0, self.parent_normalized - self.aspiration_normalized)
123
+
124
+ def to_record(self) -> dict[str, str]:
125
+ self.__post_init__()
126
+ return {
127
+ "metric_id": self.metric_id,
128
+ "goal": self.goal,
129
+ "ideal_hex": self.ideal.hex(),
130
+ "reference_hex": self.reference.hex(),
131
+ "parent_value_hex": self.parent_value.hex(),
132
+ "aspiration_value_hex": self.aspiration_value.hex(),
133
+ "signed_parent_to_aspiration_delta_hex": (
134
+ self.signed_parent_to_aspiration_delta.hex()
135
+ ),
136
+ "improving_raw_delta_sign": self.improving_raw_delta_sign,
137
+ }
138
+
139
+
140
+ @dataclass(frozen=True, slots=True)
141
+ class ObjectiveSpaceTarget:
142
+ """Typed action-to-frontier target projected from one campaign assignment."""
143
+
144
+ campaign_target_sha256: str
145
+ purpose: str
146
+ axes: tuple[ObjectiveSpaceTargetAxis, ...]
147
+
148
+ def __post_init__(self) -> None:
149
+ require_sha256(self.campaign_target_sha256, "campaign_target_sha256")
150
+ if type(self.purpose) is not str or not self.purpose:
151
+ raise ValueError("objective target purpose must be non-empty")
152
+ if type(self.axes) is not tuple or not self.axes or any(
153
+ type(value) is not ObjectiveSpaceTargetAxis for value in self.axes
154
+ ):
155
+ raise ValueError("objective target axes must be a non-empty exact tuple")
156
+ for value in self.axes:
157
+ value.__post_init__()
158
+ metric_ids = tuple(value.metric_id for value in self.axes)
159
+ if metric_ids != tuple(sorted(set(metric_ids))):
160
+ raise ValueError("objective target axes must be unique and canonical")
161
+
162
+ @property
163
+ def metric_ids(self) -> tuple[str, ...]:
164
+ self.__post_init__()
165
+ return tuple(value.metric_id for value in self.axes)
166
+
167
+ def to_record(self) -> dict[str, object]:
168
+ self.__post_init__()
169
+ return {
170
+ "schema_version": 1,
171
+ "campaign_target_sha256": self.campaign_target_sha256,
172
+ "purpose": self.purpose,
173
+ "axes": [value.to_record() for value in self.axes],
174
+ }
175
+
176
+
177
+ @dataclass(frozen=True, slots=True)
178
+ class CampaignPortfolioFrontierTarget:
179
+ """One prior-only frontier target assigned to one concurrent parent lane."""
180
+
181
+ allocator_id: str
182
+ allocator_version: int
183
+ definition_sha256: str
184
+ archive_utility_snapshot_sha256: str
185
+ lane_id: str
186
+ parent_configuration_sha256: str
187
+ direction_id: str
188
+ opportunity_rank: int
189
+ payload: FrozenJsonObject
190
+ target_sha256: str = field(init=False)
191
+
192
+ def __post_init__(self) -> None:
193
+ for name in ("allocator_id", "lane_id", "direction_id"):
194
+ value = getattr(self, name)
195
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
196
+ raise ValueError(f"{name} must use the closed token grammar")
197
+ if type(self.allocator_version) is not int or self.allocator_version <= 0:
198
+ raise ValueError("allocator_version must be positive")
199
+ if type(self.opportunity_rank) is not int or self.opportunity_rank <= 0:
200
+ raise ValueError("opportunity_rank must be positive")
201
+ for name in (
202
+ "definition_sha256",
203
+ "archive_utility_snapshot_sha256",
204
+ "parent_configuration_sha256",
205
+ ):
206
+ require_sha256(getattr(self, name), name)
207
+ if (
208
+ type(self.payload) is not FrozenJsonObject
209
+ or freeze_json(self.payload) is not self.payload
210
+ ):
211
+ raise TypeError("payload must be an exact frozen typed-JSON object")
212
+ object.__setattr__(
213
+ self,
214
+ "target_sha256",
215
+ hashlib.sha256(
216
+ _TARGET_DOMAIN + _canonical_json(self._unsigned_record())
217
+ ).hexdigest(),
218
+ )
219
+
220
+ def _unsigned_record(self) -> dict[str, object]:
221
+ return {
222
+ "schema_version": 1,
223
+ "allocator": {
224
+ "allocator_id": self.allocator_id,
225
+ "allocator_version": self.allocator_version,
226
+ "definition_sha256": self.definition_sha256,
227
+ },
228
+ "archive_utility_snapshot_sha256": (self.archive_utility_snapshot_sha256),
229
+ "lane_id": self.lane_id,
230
+ "parent_configuration_sha256": self.parent_configuration_sha256,
231
+ "direction_id": self.direction_id,
232
+ "opportunity_rank": self.opportunity_rank,
233
+ "payload_sha256": typed_json_sha256(self.payload),
234
+ "payload": thaw_json(self.payload),
235
+ }
236
+
237
+ def to_record(self) -> dict[str, object]:
238
+ self.__post_init__()
239
+ return {**self._unsigned_record(), "target_sha256": self.target_sha256}
240
+
241
+
242
+ def objective_space_target_from_campaign_target(
243
+ target: CampaignPortfolioFrontierTarget,
244
+ ) -> ObjectiveSpaceTarget | None:
245
+ """Project the optional schema-v2 raw target without policy coupling.
246
+
247
+ Historical frontier assignments did not expose raw parent/aspiration
248
+ coordinates and therefore return ``None``. Once the field is present it
249
+ is fail-closed: malformed or internally inconsistent axes cannot silently
250
+ become model or allocation evidence.
251
+ """
252
+
253
+ if type(target) is not CampaignPortfolioFrontierTarget:
254
+ raise TypeError("target must be an exact CampaignPortfolioFrontierTarget")
255
+ target.__post_init__()
256
+ payload = thaw_json(target.payload)
257
+ if type(payload) is not dict: # pragma: no cover - frozen root is closed.
258
+ raise AssertionError("campaign frontier target payload is not an object")
259
+ raw = payload.get("objective_space_target")
260
+ if raw is None:
261
+ return None
262
+ if type(raw) is not dict or set(raw) != {"purpose", "axes"}:
263
+ raise ValueError("objective_space_target has an invalid field set")
264
+ rows = raw["axes"]
265
+ if type(rows) is not list or not rows:
266
+ raise ValueError("objective_space_target axes must be a non-empty list")
267
+ expected_fields = {
268
+ "metric_id",
269
+ "goal",
270
+ "ideal_decimal",
271
+ "reference_decimal",
272
+ "parent_value_decimal",
273
+ "aspiration_value_decimal",
274
+ "signed_parent_to_aspiration_delta_decimal",
275
+ "improving_raw_delta_sign",
276
+ }
277
+ axes: list[ObjectiveSpaceTargetAxis] = []
278
+ for index, row in enumerate(rows):
279
+ if type(row) is not dict or set(row) != expected_fields:
280
+ raise ValueError("objective_space_target axis has an invalid field set")
281
+ axes.append(
282
+ ObjectiveSpaceTargetAxis(
283
+ metric_id=row["metric_id"],
284
+ goal=row["goal"],
285
+ ideal=_finite_decimal(
286
+ row["ideal_decimal"], name=f"axes[{index}].ideal_decimal"
287
+ ),
288
+ reference=_finite_decimal(
289
+ row["reference_decimal"],
290
+ name=f"axes[{index}].reference_decimal",
291
+ ),
292
+ parent_value=_finite_decimal(
293
+ row["parent_value_decimal"],
294
+ name=f"axes[{index}].parent_value_decimal",
295
+ ),
296
+ aspiration_value=_finite_decimal(
297
+ row["aspiration_value_decimal"],
298
+ name=f"axes[{index}].aspiration_value_decimal",
299
+ ),
300
+ signed_parent_to_aspiration_delta=_finite_decimal(
301
+ row["signed_parent_to_aspiration_delta_decimal"],
302
+ name=(
303
+ f"axes[{index}].signed_parent_to_aspiration_delta_decimal"
304
+ ),
305
+ ),
306
+ improving_raw_delta_sign=row["improving_raw_delta_sign"],
307
+ )
308
+ )
309
+ return ObjectiveSpaceTarget(
310
+ campaign_target_sha256=target.target_sha256,
311
+ purpose=raw["purpose"],
312
+ axes=tuple(sorted(axes, key=lambda value: value.metric_id)),
313
+ )
314
+
315
+
316
+ def campaign_frontier_target_from_record(
317
+ record: object,
318
+ ) -> CampaignPortfolioFrontierTarget:
319
+ """Rebuild and authenticate one serialized campaign target.
320
+
321
+ Campaign contexts intentionally carry only typed JSON. Downstream generic
322
+ policies therefore need a fail-closed inverse of :meth:`to_record` rather
323
+ than reaching back into the planner that created the target. Recomputing
324
+ both the payload and target digests makes the context record a sufficient
325
+ authenticated boundary for action forecasting and allocation.
326
+ """
327
+
328
+ if type(record) is not dict or set(record) != {
329
+ "schema_version",
330
+ "allocator",
331
+ "archive_utility_snapshot_sha256",
332
+ "lane_id",
333
+ "parent_configuration_sha256",
334
+ "direction_id",
335
+ "opportunity_rank",
336
+ "payload_sha256",
337
+ "payload",
338
+ "target_sha256",
339
+ }:
340
+ raise ValueError("campaign frontier target record has an invalid field set")
341
+ if record["schema_version"] != 1:
342
+ raise ValueError("campaign frontier target record has an unsupported schema")
343
+ allocator = record["allocator"]
344
+ if type(allocator) is not dict or set(allocator) != {
345
+ "allocator_id",
346
+ "allocator_version",
347
+ "definition_sha256",
348
+ }:
349
+ raise ValueError("campaign frontier target allocator record is malformed")
350
+ payload = freeze_json(record["payload"])
351
+ if type(payload) is not FrozenJsonObject:
352
+ raise TypeError("campaign frontier target payload must be an object")
353
+ if typed_json_sha256(payload) != record["payload_sha256"]:
354
+ raise ValueError("campaign frontier target payload digest does not match")
355
+ target = CampaignPortfolioFrontierTarget(
356
+ allocator_id=allocator["allocator_id"],
357
+ allocator_version=allocator["allocator_version"],
358
+ definition_sha256=allocator["definition_sha256"],
359
+ archive_utility_snapshot_sha256=record[
360
+ "archive_utility_snapshot_sha256"
361
+ ],
362
+ lane_id=record["lane_id"],
363
+ parent_configuration_sha256=record["parent_configuration_sha256"],
364
+ direction_id=record["direction_id"],
365
+ opportunity_rank=record["opportunity_rank"],
366
+ payload=payload,
367
+ )
368
+ if target.target_sha256 != record["target_sha256"]:
369
+ raise ValueError("campaign frontier target digest does not match")
370
+ return target
371
+
372
+
373
+ @runtime_checkable
374
+ class CampaignPortfolioFrontierTargetAllocator(Protocol):
375
+ """Assign distinct generic frontier opportunities across parent lanes."""
376
+
377
+ allocator_id: str
378
+ allocator_version: int
379
+ definition_sha256: str
380
+
381
+ def allocate(
382
+ self,
383
+ *,
384
+ archive_utility: ArchiveUtilitySnapshot,
385
+ lanes: tuple[tuple[str, EvolutionCandidate], ...],
386
+ ) -> tuple[CampaignPortfolioFrontierTarget, ...]: ...
387
+
388
+
389
+ __all__ = [
390
+ "CampaignPortfolioFrontierTarget",
391
+ "CampaignPortfolioFrontierTargetAllocator",
392
+ "ObjectiveSpaceTarget",
393
+ "ObjectiveSpaceTargetAxis",
394
+ "campaign_frontier_target_from_record",
395
+ "objective_space_target_from_campaign_target",
396
+ ]
@@ -0,0 +1,43 @@
1
+ """Provider-neutral terminal classification for agentic generation failures.
2
+
3
+ Application services must not infer causal failure semantics from exception class
4
+ names or provider-specific status text. Adapters may expose this deliberately
5
+ small projection; every absent, malformed, or hostile projection fails closed as
6
+ infrastructure. Only an explicit structured/model-output failure is eligible for
7
+ the preregistered no-yield intention-to-treat path.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from enum import Enum
13
+ from typing import Protocol, runtime_checkable
14
+
15
+
16
+ class GenerationFailureDisposition(str, Enum):
17
+ MODEL_OR_SCHEMA_FAILURE = "model_or_schema_failure"
18
+ INFRASTRUCTURE_FAILURE = "infrastructure_failure"
19
+
20
+
21
+ @runtime_checkable
22
+ class ClassifiedGenerationFailure(Protocol):
23
+ @property
24
+ def generation_failure_disposition(self) -> GenerationFailureDisposition: ...
25
+
26
+
27
+ def classify_generation_failure(error: BaseException) -> GenerationFailureDisposition:
28
+ """Return a closed terminal class, defaulting every untyped failure to infra."""
29
+
30
+ try:
31
+ disposition = getattr(error, "generation_failure_disposition", None)
32
+ except Exception:
33
+ return GenerationFailureDisposition.INFRASTRUCTURE_FAILURE
34
+ if type(disposition) is not GenerationFailureDisposition:
35
+ return GenerationFailureDisposition.INFRASTRUCTURE_FAILURE
36
+ return disposition
37
+
38
+
39
+ __all__ = [
40
+ "ClassifiedGenerationFailure",
41
+ "GenerationFailureDisposition",
42
+ "classify_generation_failure",
43
+ ]
@@ -0,0 +1,233 @@
1
+ """Outcome-blind exact-feasibility boundary for candidate screening.
2
+
3
+ This port is deliberately narrower than a learned proxy. A workload adapter
4
+ may reject a configuration only when it can publish an exact, evaluator-bound
5
+ proof of infeasibility. ``UNKNOWN`` is the safe default and must remain in the
6
+ ordinary evaluation pool. Objective values and predicted quality never cross
7
+ this boundary.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import json
14
+ import re
15
+ from dataclasses import dataclass, field
16
+ from enum import Enum
17
+ from typing import Protocol, Sequence, runtime_checkable
18
+
19
+ from agent_evolve.domain.patch import require_sha256
20
+ from agent_evolve.domain.typed_json import (
21
+ FrozenJsonObject,
22
+ freeze_json,
23
+ thaw_json,
24
+ typed_json_sha256,
25
+ )
26
+
27
+
28
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,127}$")
29
+ _REQUEST_DOMAIN = b"agent-evolve:hard-feasibility-request:v1\x00"
30
+ _DECISION_DOMAIN = b"agent-evolve:hard-feasibility-decision:v1\x00"
31
+ _DECISION_BATCH_DOMAIN = b"agent-evolve:hard-feasibility-decision-batch:v1\x00"
32
+
33
+
34
+ def _canonical_json(value: object) -> bytes:
35
+ return json.dumps(
36
+ value,
37
+ allow_nan=False,
38
+ ensure_ascii=True,
39
+ separators=(",", ":"),
40
+ sort_keys=True,
41
+ ).encode("ascii", errors="strict")
42
+
43
+
44
+ def _identity(port: "HardFeasibilityPort") -> tuple[str, int, str]:
45
+ if not isinstance(port, HardFeasibilityPort):
46
+ raise TypeError("hard feasibility adapter must implement its port")
47
+ values = (
48
+ getattr(port, "policy_id", None),
49
+ getattr(port, "policy_version", None),
50
+ getattr(port, "definition_sha256", None),
51
+ )
52
+ if type(values[0]) is not str or _TOKEN.fullmatch(values[0]) is None:
53
+ raise ValueError("hard feasibility policy_id has invalid syntax")
54
+ if type(values[1]) is not int or values[1] <= 0:
55
+ raise ValueError("hard feasibility policy_version must be positive")
56
+ require_sha256(values[2], "hard feasibility definition_sha256")
57
+ return values # type: ignore[return-value]
58
+
59
+
60
+ class HardFeasibilityVerdict(str, Enum):
61
+ """Three-valued proof outcome; only ``INFEASIBLE`` authorizes rejection."""
62
+
63
+ FEASIBLE = "feasible"
64
+ INFEASIBLE = "infeasible"
65
+ UNKNOWN = "unknown"
66
+
67
+
68
+ @dataclass(frozen=True, slots=True)
69
+ class HardFeasibilityRequest:
70
+ campaign_scope_sha256: str
71
+ cutoff_index: int
72
+ configuration: FrozenJsonObject
73
+ request_sha256: str = field(init=False, default="")
74
+
75
+ def __post_init__(self) -> None:
76
+ require_sha256(self.campaign_scope_sha256, "campaign_scope_sha256")
77
+ if type(self.cutoff_index) is not int or self.cutoff_index < 1:
78
+ raise ValueError("cutoff_index must be positive")
79
+ if (
80
+ type(self.configuration) is not FrozenJsonObject
81
+ or freeze_json(self.configuration) is not self.configuration
82
+ ):
83
+ raise TypeError("configuration must be a frozen typed-JSON object")
84
+ computed = hashlib.sha256(
85
+ _REQUEST_DOMAIN + _canonical_json(self._unsigned_record())
86
+ ).hexdigest()
87
+ if self.request_sha256 not in ("", computed):
88
+ raise ValueError("request_sha256 does not authenticate the request")
89
+ object.__setattr__(self, "request_sha256", computed)
90
+
91
+ def _unsigned_record(self) -> dict[str, object]:
92
+ return {
93
+ "schema_version": 1,
94
+ "campaign_scope_sha256": self.campaign_scope_sha256,
95
+ "cutoff_index": self.cutoff_index,
96
+ "configuration_sha256": typed_json_sha256(self.configuration),
97
+ "outcome_access": False,
98
+ }
99
+
100
+ def to_record(self) -> dict[str, object]:
101
+ self.__post_init__()
102
+ return {**self._unsigned_record(), "request_sha256": self.request_sha256}
103
+
104
+
105
+ @dataclass(frozen=True, slots=True)
106
+ class HardFeasibilityDecision:
107
+ request_sha256: str
108
+ policy_id: str
109
+ policy_version: int
110
+ policy_definition_sha256: str
111
+ verdict: HardFeasibilityVerdict
112
+ proof: FrozenJsonObject
113
+ decision_sha256: str = field(init=False, default="")
114
+
115
+ def __post_init__(self) -> None:
116
+ require_sha256(self.request_sha256, "request_sha256")
117
+ if type(self.policy_id) is not str or _TOKEN.fullmatch(self.policy_id) is None:
118
+ raise ValueError("policy_id has invalid syntax")
119
+ if type(self.policy_version) is not int or self.policy_version <= 0:
120
+ raise ValueError("policy_version must be positive")
121
+ require_sha256(
122
+ self.policy_definition_sha256,
123
+ "policy_definition_sha256",
124
+ )
125
+ if type(self.verdict) is not HardFeasibilityVerdict:
126
+ raise TypeError("verdict must be HardFeasibilityVerdict")
127
+ if type(self.proof) is not FrozenJsonObject or freeze_json(self.proof) is not self.proof:
128
+ raise TypeError("proof must be a frozen typed-JSON object")
129
+ proof_record = thaw_json(self.proof)
130
+ if self.verdict is HardFeasibilityVerdict.INFEASIBLE and not proof_record:
131
+ raise ValueError("infeasible decisions require a non-empty exact proof")
132
+ computed = hashlib.sha256(
133
+ _DECISION_DOMAIN + _canonical_json(self._unsigned_record())
134
+ ).hexdigest()
135
+ if self.decision_sha256 not in ("", computed):
136
+ raise ValueError("decision_sha256 does not authenticate the decision")
137
+ object.__setattr__(self, "decision_sha256", computed)
138
+
139
+ def _unsigned_record(self) -> dict[str, object]:
140
+ return {
141
+ "schema_version": 1,
142
+ "request_sha256": self.request_sha256,
143
+ "policy": {
144
+ "policy_id": self.policy_id,
145
+ "policy_version": self.policy_version,
146
+ "definition_sha256": self.policy_definition_sha256,
147
+ },
148
+ "verdict": self.verdict.value,
149
+ "proof": thaw_json(self.proof),
150
+ "rejection_authorized": (
151
+ self.verdict is HardFeasibilityVerdict.INFEASIBLE
152
+ ),
153
+ "objective_access": False,
154
+ }
155
+
156
+ def to_record(self) -> dict[str, object]:
157
+ self.__post_init__()
158
+ return {**self._unsigned_record(), "decision_sha256": self.decision_sha256}
159
+
160
+
161
+ @runtime_checkable
162
+ class HardFeasibilityPort(Protocol):
163
+ """Publish exact static feasibility evidence for one configuration."""
164
+
165
+ policy_id: str
166
+ policy_version: int
167
+ definition_sha256: str
168
+
169
+ def assess(self, request: HardFeasibilityRequest) -> HardFeasibilityDecision: ...
170
+
171
+
172
+ def validate_hard_feasibility_port(
173
+ port: HardFeasibilityPort,
174
+ ) -> tuple[str, int, str]:
175
+ return _identity(port)
176
+
177
+
178
+ def assess_hard_feasibility(
179
+ port: HardFeasibilityPort,
180
+ request: HardFeasibilityRequest,
181
+ ) -> HardFeasibilityDecision:
182
+ identity = _identity(port)
183
+ if type(request) is not HardFeasibilityRequest:
184
+ raise TypeError("request must be exact")
185
+ request.__post_init__()
186
+ decision = port.assess(request)
187
+ if type(decision) is not HardFeasibilityDecision:
188
+ raise TypeError("hard feasibility adapter returned a foreign decision")
189
+ decision.__post_init__()
190
+ if decision.request_sha256 != request.request_sha256:
191
+ raise ValueError("hard feasibility decision targets another request")
192
+ if (
193
+ decision.policy_id,
194
+ decision.policy_version,
195
+ decision.policy_definition_sha256,
196
+ ) != identity:
197
+ raise ValueError("hard feasibility decision has a foreign policy identity")
198
+ return decision
199
+
200
+
201
+ def hard_feasibility_decision_batch_sha256(
202
+ decision_sha256s: Sequence[str],
203
+ ) -> str:
204
+ """Commit an ordered feasibility audit without inlining every decision."""
205
+
206
+ if isinstance(decision_sha256s, (str, bytes)) or not isinstance(
207
+ decision_sha256s,
208
+ Sequence,
209
+ ):
210
+ raise TypeError("decision_sha256s must be a non-string sequence")
211
+ values = tuple(decision_sha256s)
212
+ for index, value in enumerate(values):
213
+ require_sha256(value, f"decision_sha256s[{index}]")
214
+ return hashlib.sha256(
215
+ _DECISION_BATCH_DOMAIN
216
+ + _canonical_json(
217
+ {
218
+ "schema_version": 1,
219
+ "decision_sha256s": values,
220
+ }
221
+ )
222
+ ).hexdigest()
223
+
224
+
225
+ __all__ = [
226
+ "HardFeasibilityDecision",
227
+ "HardFeasibilityPort",
228
+ "HardFeasibilityRequest",
229
+ "HardFeasibilityVerdict",
230
+ "assess_hard_feasibility",
231
+ "hard_feasibility_decision_batch_sha256",
232
+ "validate_hard_feasibility_port",
233
+ ]