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,749 @@
1
+ """Workload-neutral parent coverage and on-demand residual composition.
2
+
3
+ Pareto archives summarize objective quality, but they need not preserve useful
4
+ genotype basins. This module maintains a bounded reachability basis over
5
+ already evaluated candidates and exposes a compact cross-parent finite-action
6
+ schema. Proposal experts select only a parent ID and opaque atomic option IDs;
7
+ trusted engine code resolves and materializes the exact child.
8
+
9
+ The module deliberately contains no workload, objective, model, or provider
10
+ identity. It is downstream of a benchmark's :class:`FiniteVariationCatalog`
11
+ and upstream of the real-evaluation broker.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from dataclasses import dataclass, field
17
+ from enum import Enum
18
+ import hashlib
19
+ import json
20
+ import re
21
+
22
+ from agent_evolve.domain.finite_variation import (
23
+ FiniteVariationContract,
24
+ validate_finite_variation_contract,
25
+ )
26
+ from agent_evolve.domain.ids import CandidateId
27
+ from agent_evolve.domain.patch import require_sha256
28
+ from agent_evolve.domain.typed_json import (
29
+ FrozenJsonObject,
30
+ freeze_json,
31
+ typed_json_sha256,
32
+ )
33
+ from agent_evolve.policies.variation.disjoint_recombination import (
34
+ DisjointPatchRecombiner,
35
+ )
36
+
37
+
38
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
39
+ _BASIS_POLICY_DOMAIN = b"agent-evolve:residual-reachability-basis-policy:v1\x00"
40
+ _BASIS_DOMAIN = b"agent-evolve:residual-reachability-basis:v1\x00"
41
+ _SCHEMA_DOMAIN = b"agent-evolve:cross-parent-finite-action-schema:v1\x00"
42
+ _PLAN_DOMAIN = b"agent-evolve:hierarchical-residual-plan:v1\x00"
43
+ _MATERIALIZATION_DOMAIN = b"agent-evolve:residual-plan-materialization:v1\x00"
44
+
45
+
46
+ def _canonical_bytes(value: object) -> bytes:
47
+ return json.dumps(
48
+ value,
49
+ allow_nan=False,
50
+ ensure_ascii=True,
51
+ separators=(",", ":"),
52
+ sort_keys=True,
53
+ ).encode("ascii", errors="strict")
54
+
55
+
56
+ def _hash(domain: bytes, value: object) -> str:
57
+ return hashlib.sha256(domain + _canonical_bytes(value)).hexdigest()
58
+
59
+
60
+ def _token(value: str, name: str) -> None:
61
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
62
+ raise ValueError(f"{name} must use the closed token grammar")
63
+
64
+
65
+ def _candidate(value: CandidateId, name: str = "candidate_id") -> None:
66
+ if type(value) is not CandidateId:
67
+ raise TypeError(f"{name} must be an exact CandidateId")
68
+ CandidateId.__post_init__(value)
69
+
70
+
71
+ class ResidualProposalRole(str, Enum):
72
+ """Scientific purpose of a proposal, independent of its workload."""
73
+
74
+ LOCAL_EXPLOIT = "local_exploit"
75
+ INTERACTION = "interaction"
76
+ DONOR_RECOMBINATION = "donor_recombination"
77
+ STRUCTURAL_COVERAGE = "structural_coverage"
78
+ RESTART = "restart"
79
+
80
+
81
+ class ReachabilityAdmissionReason(str, Enum):
82
+ """Authenticated route by which an evaluated parent enters the basis."""
83
+
84
+ QUALITY_ARCHIVE = "quality_archive"
85
+ INITIAL_DESIGN = "initial_design"
86
+ EARNED_LINEAGE = "earned_lineage"
87
+ STRUCTURAL_COVER = "structural_cover"
88
+ CAPACITY_FILL = "capacity_fill"
89
+
90
+
91
+ @dataclass(frozen=True, slots=True)
92
+ class ReachabilityCandidate:
93
+ """Prompt-independent evidence for one already evaluated parent."""
94
+
95
+ candidate_id: CandidateId
96
+ configuration: FrozenJsonObject
97
+ phenotype_identity_sha256: str
98
+ evaluation_ordinal: int
99
+ structural_cell: str
100
+ quality_archive_member: bool
101
+ initial_design_member: bool
102
+ earned_positive_lineage: bool
103
+
104
+ def __post_init__(self) -> None:
105
+ _candidate(self.candidate_id)
106
+ if type(self.configuration) is not FrozenJsonObject:
107
+ raise TypeError("configuration must be an exact FrozenJsonObject")
108
+ if freeze_json(self.configuration) is not self.configuration:
109
+ raise TypeError("configuration must already be frozen typed JSON")
110
+ require_sha256(
111
+ self.phenotype_identity_sha256,
112
+ "phenotype_identity_sha256",
113
+ )
114
+ if type(self.evaluation_ordinal) is not int or self.evaluation_ordinal <= 0:
115
+ raise ValueError("evaluation_ordinal must be positive")
116
+ _token(self.structural_cell, "structural_cell")
117
+ for name in (
118
+ "quality_archive_member",
119
+ "initial_design_member",
120
+ "earned_positive_lineage",
121
+ ):
122
+ if type(getattr(self, name)) is not bool:
123
+ raise TypeError(f"{name} must be an exact bool")
124
+
125
+ @property
126
+ def configuration_sha256(self) -> str:
127
+ self.__post_init__()
128
+ return typed_json_sha256(self.configuration)
129
+
130
+ def to_record(self) -> dict[str, object]:
131
+ self.__post_init__()
132
+ return {
133
+ "candidate_id": self.candidate_id.value,
134
+ "configuration_sha256": self.configuration_sha256,
135
+ "phenotype_identity_sha256": self.phenotype_identity_sha256,
136
+ "evaluation_ordinal": self.evaluation_ordinal,
137
+ "structural_cell": self.structural_cell,
138
+ "quality_archive_member": self.quality_archive_member,
139
+ "initial_design_member": self.initial_design_member,
140
+ "earned_positive_lineage": self.earned_positive_lineage,
141
+ }
142
+
143
+
144
+ @dataclass(frozen=True, slots=True)
145
+ class ResidualReachabilityBasisPolicy:
146
+ """Bounded, deterministic dual-archive parent retention policy."""
147
+
148
+ maximum_parents: int = 32
149
+ maximum_quality_archive_parents: int = 16
150
+ maximum_initial_design_parents: int = 16
151
+ maximum_earned_lineage_parents: int = 8
152
+ maximum_structural_cover_parents: int = 8
153
+ policy_id: str = "bounded_dual_archive_reachability_basis"
154
+ policy_version: int = 1
155
+
156
+ def __post_init__(self) -> None:
157
+ _token(self.policy_id, "policy_id")
158
+ if type(self.policy_version) is not int or self.policy_version <= 0:
159
+ raise ValueError("policy_version must be positive")
160
+ for name in (
161
+ "maximum_parents",
162
+ "maximum_quality_archive_parents",
163
+ "maximum_initial_design_parents",
164
+ "maximum_earned_lineage_parents",
165
+ "maximum_structural_cover_parents",
166
+ ):
167
+ value = getattr(self, name)
168
+ if type(value) is not int or value <= 0:
169
+ raise ValueError(f"{name} must be positive")
170
+ if name != "maximum_parents" and value > self.maximum_parents:
171
+ raise ValueError(f"{name} cannot exceed maximum_parents")
172
+
173
+ def _unsigned_record(self) -> dict[str, object]:
174
+ self.__post_init__()
175
+ return {
176
+ "schema_version": 1,
177
+ "policy_id": self.policy_id,
178
+ "policy_version": self.policy_version,
179
+ "maximum_parents": self.maximum_parents,
180
+ "maximum_quality_archive_parents": (
181
+ self.maximum_quality_archive_parents
182
+ ),
183
+ "maximum_initial_design_parents": self.maximum_initial_design_parents,
184
+ "maximum_earned_lineage_parents": self.maximum_earned_lineage_parents,
185
+ "maximum_structural_cover_parents": (
186
+ self.maximum_structural_cover_parents
187
+ ),
188
+ "outcomes_consulted": [
189
+ "quality_archive_membership",
190
+ "earned_positive_lineage",
191
+ ],
192
+ "forbidden_fields": ["workload_id", "model_id", "provider_id"],
193
+ }
194
+
195
+ @property
196
+ def definition_sha256(self) -> str:
197
+ return _hash(_BASIS_POLICY_DOMAIN, self._unsigned_record())
198
+
199
+ def to_record(self) -> dict[str, object]:
200
+ return {**self._unsigned_record(), "definition_sha256": self.definition_sha256}
201
+
202
+
203
+ @dataclass(frozen=True, slots=True)
204
+ class ReachabilityBasisMember:
205
+ candidate: ReachabilityCandidate
206
+ admission_reasons: tuple[ReachabilityAdmissionReason, ...]
207
+
208
+ def __post_init__(self) -> None:
209
+ if type(self.candidate) is not ReachabilityCandidate:
210
+ raise TypeError("candidate must be an exact ReachabilityCandidate")
211
+ ReachabilityCandidate.__post_init__(self.candidate)
212
+ if type(self.admission_reasons) is not tuple or not self.admission_reasons:
213
+ raise ValueError("admission_reasons must be a non-empty exact tuple")
214
+ if any(type(value) is not ReachabilityAdmissionReason for value in self.admission_reasons):
215
+ raise TypeError("admission_reasons contain a foreign value")
216
+ canonical = tuple(sorted(set(self.admission_reasons), key=lambda value: value.value))
217
+ if self.admission_reasons != canonical:
218
+ raise ValueError("admission_reasons must be unique and canonical")
219
+
220
+ def to_record(self) -> dict[str, object]:
221
+ self.__post_init__()
222
+ return {
223
+ "candidate": self.candidate.to_record(),
224
+ "admission_reasons": [value.value for value in self.admission_reasons],
225
+ }
226
+
227
+
228
+ @dataclass(frozen=True, slots=True)
229
+ class ResidualReachabilityBasis:
230
+ policy_definition_sha256: str
231
+ source_candidate_count: int
232
+ members: tuple[ReachabilityBasisMember, ...]
233
+ basis_sha256: str = field(init=False)
234
+
235
+ def __post_init__(self) -> None:
236
+ require_sha256(self.policy_definition_sha256, "policy_definition_sha256")
237
+ if type(self.source_candidate_count) is not int or self.source_candidate_count <= 0:
238
+ raise ValueError("source_candidate_count must be positive")
239
+ if type(self.members) is not tuple or not self.members:
240
+ raise ValueError("members must be a non-empty exact tuple")
241
+ if any(type(value) is not ReachabilityBasisMember for value in self.members):
242
+ raise TypeError("members contain a foreign value")
243
+ for value in self.members:
244
+ ReachabilityBasisMember.__post_init__(value)
245
+ ids = tuple(value.candidate.candidate_id.value for value in self.members)
246
+ if ids != tuple(sorted(set(ids))):
247
+ raise ValueError("members must have unique canonical candidate order")
248
+ if len(self.members) > self.source_candidate_count:
249
+ raise ValueError("basis cannot exceed its source population")
250
+ object.__setattr__(self, "basis_sha256", _hash(_BASIS_DOMAIN, self._unsigned_record()))
251
+
252
+ def _unsigned_record(self) -> dict[str, object]:
253
+ return {
254
+ "schema_version": 1,
255
+ "policy_definition_sha256": self.policy_definition_sha256,
256
+ "source_candidate_count": self.source_candidate_count,
257
+ "members": [value.to_record() for value in self.members],
258
+ }
259
+
260
+ def to_record(self) -> dict[str, object]:
261
+ self.__post_init__()
262
+ return {**self._unsigned_record(), "basis_sha256": self.basis_sha256}
263
+
264
+
265
+ def select_residual_reachability_basis(
266
+ candidates: tuple[ReachabilityCandidate, ...],
267
+ policy: ResidualReachabilityBasisPolicy,
268
+ ) -> ResidualReachabilityBasis:
269
+ """Retain quality and bounded structural stepping-stone parents.
270
+
271
+ Selection is deterministic. Earlier evaluated candidates break ties so a
272
+ later outcome cannot retroactively change a frozen prefix basis.
273
+ """
274
+
275
+ if type(candidates) is not tuple or not candidates:
276
+ raise ValueError("candidates must be a non-empty exact tuple")
277
+ if any(type(value) is not ReachabilityCandidate for value in candidates):
278
+ raise TypeError("candidates contain a foreign value")
279
+ for value in candidates:
280
+ ReachabilityCandidate.__post_init__(value)
281
+ if type(policy) is not ResidualReachabilityBasisPolicy:
282
+ raise TypeError("policy must be an exact ResidualReachabilityBasisPolicy")
283
+ policy.__post_init__()
284
+ ids = tuple(value.candidate_id for value in candidates)
285
+ phenotypes = tuple(value.phenotype_identity_sha256 for value in candidates)
286
+ ordinals = tuple(value.evaluation_ordinal for value in candidates)
287
+ if len(set(ids)) != len(ids) or len(set(phenotypes)) != len(phenotypes):
288
+ raise ValueError("source candidates must have unique IDs and phenotypes")
289
+ if len(set(ordinals)) != len(ordinals):
290
+ raise ValueError("source candidates must have unique evaluation ordinals")
291
+
292
+ ordered = tuple(sorted(candidates, key=lambda value: value.evaluation_ordinal))
293
+ reasons: dict[CandidateId, set[ReachabilityAdmissionReason]] = {}
294
+ selected: dict[CandidateId, ReachabilityCandidate] = {}
295
+
296
+ def admit(
297
+ pool: tuple[ReachabilityCandidate, ...],
298
+ reason: ReachabilityAdmissionReason,
299
+ limit: int,
300
+ ) -> None:
301
+ admitted = 0
302
+ for value in pool:
303
+ if admitted >= limit or len(selected) >= policy.maximum_parents:
304
+ break
305
+ if value.candidate_id not in selected:
306
+ selected[value.candidate_id] = value
307
+ admitted += 1
308
+ reasons.setdefault(value.candidate_id, set()).add(reason)
309
+
310
+ admit(
311
+ tuple(value for value in ordered if value.quality_archive_member),
312
+ ReachabilityAdmissionReason.QUALITY_ARCHIVE,
313
+ policy.maximum_quality_archive_parents,
314
+ )
315
+ admit(
316
+ tuple(value for value in ordered if value.initial_design_member),
317
+ ReachabilityAdmissionReason.INITIAL_DESIGN,
318
+ policy.maximum_initial_design_parents,
319
+ )
320
+ admit(
321
+ tuple(value for value in ordered if value.earned_positive_lineage),
322
+ ReachabilityAdmissionReason.EARNED_LINEAGE,
323
+ policy.maximum_earned_lineage_parents,
324
+ )
325
+
326
+ covered_cells = {value.structural_cell for value in selected.values()}
327
+ structural_pool: list[ReachabilityCandidate] = []
328
+ for value in ordered:
329
+ if value.candidate_id in selected or value.structural_cell in covered_cells:
330
+ continue
331
+ structural_pool.append(value)
332
+ covered_cells.add(value.structural_cell)
333
+ admit(
334
+ tuple(structural_pool),
335
+ ReachabilityAdmissionReason.STRUCTURAL_COVER,
336
+ policy.maximum_structural_cover_parents,
337
+ )
338
+
339
+ if len(selected) < policy.maximum_parents:
340
+ admit(
341
+ tuple(value for value in reversed(ordered) if value.candidate_id not in selected),
342
+ ReachabilityAdmissionReason.CAPACITY_FILL,
343
+ policy.maximum_parents - len(selected),
344
+ )
345
+
346
+ members = tuple(
347
+ ReachabilityBasisMember(
348
+ candidate=value,
349
+ admission_reasons=tuple(sorted(reasons[value.candidate_id], key=lambda item: item.value)),
350
+ )
351
+ for value in sorted(selected.values(), key=lambda item: item.candidate_id.value)
352
+ )
353
+ return ResidualReachabilityBasis(
354
+ policy_definition_sha256=policy.definition_sha256,
355
+ source_candidate_count=len(candidates),
356
+ members=members,
357
+ )
358
+
359
+
360
+ @dataclass(frozen=True, slots=True)
361
+ class ParentFiniteVariationBinding:
362
+ parent_candidate_id: CandidateId
363
+ contract: FiniteVariationContract
364
+
365
+ def __post_init__(self) -> None:
366
+ _candidate(self.parent_candidate_id, "parent_candidate_id")
367
+ if type(self.contract) is not FiniteVariationContract:
368
+ raise TypeError("contract must be an exact FiniteVariationContract")
369
+ validate_finite_variation_contract(self.contract)
370
+
371
+
372
+ @dataclass(frozen=True, slots=True)
373
+ class CrossParentFiniteActionSchema:
374
+ """Prompt-compact union of compatible parent-bound finite contracts."""
375
+
376
+ bindings: tuple[ParentFiniteVariationBinding, ...]
377
+ action_prompt_records: tuple[dict[str, object], ...]
378
+ schema_sha256: str = field(init=False)
379
+
380
+ def __post_init__(self) -> None:
381
+ if type(self.bindings) is not tuple or not self.bindings:
382
+ raise ValueError("bindings must be a non-empty exact tuple")
383
+ if any(type(value) is not ParentFiniteVariationBinding for value in self.bindings):
384
+ raise TypeError("bindings contain a foreign value")
385
+ for value in self.bindings:
386
+ ParentFiniteVariationBinding.__post_init__(value)
387
+ ids = tuple(value.parent_candidate_id.value for value in self.bindings)
388
+ if ids != tuple(sorted(set(ids))):
389
+ raise ValueError("bindings must use unique canonical parent order")
390
+ if type(self.action_prompt_records) is not tuple or not self.action_prompt_records:
391
+ raise ValueError("action_prompt_records must be non-empty")
392
+ option_ids = tuple(str(value.get("option_id")) for value in self.action_prompt_records)
393
+ if option_ids != tuple(sorted(set(option_ids))):
394
+ raise ValueError("action prompt records must use canonical option order")
395
+ object.__setattr__(self, "schema_sha256", _hash(_SCHEMA_DOMAIN, self._unsigned_record()))
396
+
397
+ @property
398
+ def option_ids(self) -> tuple[str, ...]:
399
+ return tuple(str(value["option_id"]) for value in self.action_prompt_records)
400
+
401
+ def contract_for(self, parent_id: CandidateId) -> FiniteVariationContract:
402
+ _candidate(parent_id, "parent_id")
403
+ matches = tuple(value.contract for value in self.bindings if value.parent_candidate_id == parent_id)
404
+ if len(matches) != 1:
405
+ raise ValueError("parent_id is outside the cross-parent schema")
406
+ return matches[0]
407
+
408
+ def _unsigned_record(self) -> dict[str, object]:
409
+ union_ids = set(self.option_ids)
410
+ return {
411
+ "schema_version": 1,
412
+ "action_prompt_records": list(self.action_prompt_records),
413
+ "parents": [
414
+ {
415
+ "parent_candidate_id": value.parent_candidate_id.value,
416
+ "contract_identity_sha256": value.contract.identity_sha256,
417
+ "unavailable_option_ids": sorted(
418
+ union_ids - {option.option_id for option in value.contract.options}
419
+ ),
420
+ }
421
+ for value in self.bindings
422
+ ],
423
+ "model_materialization_authority": False,
424
+ }
425
+
426
+ def prompt_record(self) -> dict[str, object]:
427
+ """Return compact semantic choices; retain hashes in the schema receipt.
428
+
429
+ Catalog, action-definition, and source digests are valuable audit
430
+ evidence but waste model attention when repeated across hundreds of
431
+ choices. The schema digest already authenticates those fields. The
432
+ prompt projection therefore removes metadata keys ending in
433
+ ``_sha256`` while preserving action IDs, families, descriptions, and
434
+ non-digest semantics.
435
+ """
436
+
437
+ self.__post_init__()
438
+ union_ids = set(self.option_ids)
439
+ return {
440
+ "schema_version": 1,
441
+ "schema_sha256": self.schema_sha256,
442
+ "actions": [
443
+ {
444
+ "option_id": value["option_id"],
445
+ "family": value["family"],
446
+ "description": value["description"],
447
+ "metadata": {
448
+ key: item
449
+ for key, item in dict(value["metadata"]).items()
450
+ if not key.endswith("_sha256")
451
+ },
452
+ "parent_specific_description_omitted": value[
453
+ "parent_specific_description_omitted"
454
+ ],
455
+ }
456
+ for value in self.action_prompt_records
457
+ ],
458
+ "parents": [
459
+ {
460
+ "parent_candidate_id": value.parent_candidate_id.value,
461
+ "unavailable_option_ids": sorted(
462
+ union_ids
463
+ - {option.option_id for option in value.contract.options}
464
+ ),
465
+ }
466
+ for value in self.bindings
467
+ ],
468
+ "model_selects_parent_and_atomic_ids_only": True,
469
+ "model_materialization_authority": False,
470
+ }
471
+
472
+ def evidence_record(self) -> dict[str, object]:
473
+ self.__post_init__()
474
+ return {**self._unsigned_record(), "schema_sha256": self.schema_sha256}
475
+
476
+
477
+ def bind_cross_parent_finite_action_schema(
478
+ bindings: tuple[ParentFiniteVariationBinding, ...],
479
+ ) -> CrossParentFiniteActionSchema:
480
+ """Deduplicate action semantics while retaining exact parent eligibility.
481
+
482
+ A catalog description may name the current parent value (for example,
483
+ ``replace X with Y``), so exact description text need not be stable across
484
+ parents. Family and structured semantic metadata remain authoritative.
485
+ Metadata values whose keys end in ``_sha256`` are parent-bound evidence
486
+ (for example, a compiled-child phenotype digest), not shared action
487
+ meaning. Every exact value remains authenticated by its parent contract
488
+ identity, while the common schema records only those evidence-key names.
489
+ When semantic fields agree but descriptions differ, the common schema
490
+ records that the parent-specific prose was omitted; proposal context can
491
+ still expose the exact parent configuration. Any disagreement in family
492
+ or non-digest metadata fails closed.
493
+ """
494
+
495
+ if type(bindings) is not tuple or not bindings:
496
+ raise ValueError("bindings must be a non-empty exact tuple")
497
+ canonical = tuple(sorted(bindings, key=lambda value: value.parent_candidate_id.value))
498
+ if bindings != canonical:
499
+ raise ValueError("bindings must already use canonical parent order")
500
+ semantics_by_id: dict[str, tuple[str, dict[str, object]]] = {}
501
+ descriptions_by_id: dict[str, set[str]] = {}
502
+ evidence_keys_by_id: dict[str, set[str]] = {}
503
+ for binding in bindings:
504
+ ParentFiniteVariationBinding.__post_init__(binding)
505
+ for option in binding.contract.options:
506
+ prompt = option.prompt_record()
507
+ metadata = dict(prompt["metadata"])
508
+ semantics = (
509
+ option.family,
510
+ {
511
+ key: item
512
+ for key, item in metadata.items()
513
+ if not key.endswith("_sha256")
514
+ },
515
+ )
516
+ previous = semantics_by_id.setdefault(option.option_id, semantics)
517
+ if previous != semantics:
518
+ raise ValueError(
519
+ "an option ID has inconsistent prompt semantics across parents"
520
+ )
521
+ descriptions_by_id.setdefault(option.option_id, set()).add(
522
+ option.description
523
+ )
524
+ evidence_keys_by_id.setdefault(option.option_id, set()).update(
525
+ key for key in metadata if key.endswith("_sha256")
526
+ )
527
+ prompt_by_id: dict[str, dict[str, object]] = {}
528
+ for option_id in sorted(semantics_by_id):
529
+ family, metadata = semantics_by_id[option_id]
530
+ descriptions = descriptions_by_id[option_id]
531
+ prompt_by_id[option_id] = {
532
+ "option_id": option_id,
533
+ "family": family,
534
+ "description": next(iter(descriptions)) if len(descriptions) == 1 else None,
535
+ "metadata": metadata,
536
+ "parent_bound_evidence_metadata_keys": sorted(
537
+ evidence_keys_by_id[option_id]
538
+ ),
539
+ "parent_specific_description_omitted": len(descriptions) != 1,
540
+ }
541
+ return CrossParentFiniteActionSchema(
542
+ bindings=bindings,
543
+ action_prompt_records=tuple(prompt_by_id[key] for key in sorted(prompt_by_id)),
544
+ )
545
+
546
+
547
+ @dataclass(frozen=True, slots=True)
548
+ class HierarchicalResidualPlan:
549
+ """One model- or engine-proposed parent plus atomic-ID tuple."""
550
+
551
+ parent_candidate_id: CandidateId
552
+ parent_contract_sha256: str
553
+ action_schema_sha256: str
554
+ component_option_ids: tuple[str, ...]
555
+ role: ResidualProposalRole
556
+ expert_id: str
557
+ expert_definition_sha256: str
558
+ native_rank: int
559
+ decision_receipt_sha256: str
560
+
561
+ def __post_init__(self) -> None:
562
+ _candidate(self.parent_candidate_id, "parent_candidate_id")
563
+ for name in (
564
+ "parent_contract_sha256",
565
+ "action_schema_sha256",
566
+ "expert_definition_sha256",
567
+ "decision_receipt_sha256",
568
+ ):
569
+ require_sha256(getattr(self, name), name)
570
+ if (
571
+ type(self.component_option_ids) is not tuple
572
+ or not 1 <= len(self.component_option_ids) <= 2
573
+ ):
574
+ raise ValueError("component_option_ids must have radius one or two")
575
+ if any(type(value) is not str or not value for value in self.component_option_ids):
576
+ raise TypeError("component_option_ids must contain non-empty strings")
577
+ if self.component_option_ids != tuple(sorted(set(self.component_option_ids))):
578
+ raise ValueError("component_option_ids must be unique and canonical")
579
+ if type(self.role) is not ResidualProposalRole:
580
+ raise TypeError("role must be an exact ResidualProposalRole")
581
+ _token(self.expert_id, "expert_id")
582
+ if type(self.native_rank) is not int or self.native_rank <= 0:
583
+ raise ValueError("native_rank must be positive")
584
+
585
+ @property
586
+ def radius(self) -> int:
587
+ return len(self.component_option_ids)
588
+
589
+ def _unsigned_record(self) -> dict[str, object]:
590
+ self.__post_init__()
591
+ return {
592
+ "schema_version": 1,
593
+ "parent_candidate_id": self.parent_candidate_id.value,
594
+ "parent_contract_sha256": self.parent_contract_sha256,
595
+ "action_schema_sha256": self.action_schema_sha256,
596
+ "component_option_ids": list(self.component_option_ids),
597
+ "radius": self.radius,
598
+ "role": self.role.value,
599
+ "expert_id": self.expert_id,
600
+ "expert_definition_sha256": self.expert_definition_sha256,
601
+ "native_rank": self.native_rank,
602
+ "decision_receipt_sha256": self.decision_receipt_sha256,
603
+ "model_authored_configuration": False,
604
+ }
605
+
606
+ @property
607
+ def plan_sha256(self) -> str:
608
+ return _hash(_PLAN_DOMAIN, self._unsigned_record())
609
+
610
+ def to_record(self) -> dict[str, object]:
611
+ return {**self._unsigned_record(), "plan_sha256": self.plan_sha256}
612
+
613
+
614
+ @dataclass(frozen=True, slots=True)
615
+ class MaterializedResidualProposal:
616
+ plan: HierarchicalResidualPlan
617
+ target_candidate_id: CandidateId
618
+ configuration: FrozenJsonObject
619
+ component_option_identity_sha256s: tuple[str, ...]
620
+ engine_materialization_receipt_sha256: str
621
+ proposal_sha256: str = field(init=False)
622
+
623
+ def __post_init__(self) -> None:
624
+ if type(self.plan) is not HierarchicalResidualPlan:
625
+ raise TypeError("plan must be an exact HierarchicalResidualPlan")
626
+ HierarchicalResidualPlan.__post_init__(self.plan)
627
+ _candidate(self.target_candidate_id, "target_candidate_id")
628
+ if self.target_candidate_id == self.plan.parent_candidate_id:
629
+ raise ValueError("target candidate must differ from its parent")
630
+ if type(self.configuration) is not FrozenJsonObject:
631
+ raise TypeError("configuration must be an exact FrozenJsonObject")
632
+ if freeze_json(self.configuration) is not self.configuration:
633
+ raise TypeError("configuration must already be frozen typed JSON")
634
+ if (
635
+ type(self.component_option_identity_sha256s) is not tuple
636
+ or len(self.component_option_identity_sha256s) != self.plan.radius
637
+ ):
638
+ raise ValueError("component identities must match the plan radius")
639
+ for value in self.component_option_identity_sha256s:
640
+ require_sha256(value, "component_option_identity_sha256")
641
+ require_sha256(
642
+ self.engine_materialization_receipt_sha256,
643
+ "engine_materialization_receipt_sha256",
644
+ )
645
+ object.__setattr__(self, "proposal_sha256", _hash(_MATERIALIZATION_DOMAIN, self._unsigned_record()))
646
+
647
+ @property
648
+ def configuration_sha256(self) -> str:
649
+ return typed_json_sha256(self.configuration)
650
+
651
+ def _unsigned_record(self) -> dict[str, object]:
652
+ return {
653
+ "schema_version": 1,
654
+ "plan_sha256": self.plan.plan_sha256,
655
+ "target_candidate_id": self.target_candidate_id.value,
656
+ "configuration_sha256": self.configuration_sha256,
657
+ "component_option_identity_sha256s": list(
658
+ self.component_option_identity_sha256s
659
+ ),
660
+ "engine_materialization_receipt_sha256": (
661
+ self.engine_materialization_receipt_sha256
662
+ ),
663
+ }
664
+
665
+ def to_record(self, *, include_configuration: bool = False) -> dict[str, object]:
666
+ self.__post_init__()
667
+ record = {**self._unsigned_record(), "proposal_sha256": self.proposal_sha256}
668
+ if include_configuration:
669
+ record["configuration"] = self.configuration
670
+ return record
671
+
672
+
673
+ def materialize_hierarchical_residual_plan(
674
+ *,
675
+ schema: CrossParentFiniteActionSchema,
676
+ plan: HierarchicalResidualPlan,
677
+ target_candidate_id: CandidateId,
678
+ ) -> MaterializedResidualProposal:
679
+ """Resolve and replay a radius-one or safe radius-two residual plan."""
680
+
681
+ if type(schema) is not CrossParentFiniteActionSchema:
682
+ raise TypeError("schema must be an exact CrossParentFiniteActionSchema")
683
+ schema.__post_init__()
684
+ if type(plan) is not HierarchicalResidualPlan:
685
+ raise TypeError("plan must be an exact HierarchicalResidualPlan")
686
+ plan.__post_init__()
687
+ _candidate(target_candidate_id, "target_candidate_id")
688
+ if plan.action_schema_sha256 != schema.schema_sha256:
689
+ raise ValueError("plan is bound to a different cross-parent schema")
690
+ contract = schema.contract_for(plan.parent_candidate_id)
691
+ if plan.parent_contract_sha256 != contract.identity_sha256:
692
+ raise ValueError("plan is bound to a different parent contract")
693
+ options = tuple(contract.resolve(value) for value in plan.component_option_ids)
694
+ if len(options) == 1:
695
+ configuration = options[0].child_configuration
696
+ receipt = _hash(
697
+ _MATERIALIZATION_DOMAIN,
698
+ {
699
+ "kind": "sealed_atomic_option",
700
+ "plan_sha256": plan.plan_sha256,
701
+ "contract_identity_sha256": contract.identity_sha256,
702
+ "option_identity_sha256": options[0].identity_sha256,
703
+ "configuration_sha256": options[0].child_configuration_sha256,
704
+ },
705
+ )
706
+ else:
707
+ materialization = DisjointPatchRecombiner().materialize(
708
+ ancestor=contract.parent_configuration,
709
+ ancestor_candidate_id=plan.parent_candidate_id,
710
+ left=options[0].child_configuration,
711
+ left_candidate_id=CandidateId(
712
+ f"candidate_residual_component_left_{plan.plan_sha256[:16]}"
713
+ ),
714
+ right=options[1].child_configuration,
715
+ right_candidate_id=CandidateId(
716
+ f"candidate_residual_component_right_{plan.plan_sha256[:16]}"
717
+ ),
718
+ target_candidate_id=target_candidate_id,
719
+ )
720
+ if type(materialization.configuration) is not FrozenJsonObject:
721
+ raise TypeError("residual materialization must retain an object root")
722
+ configuration = materialization.configuration
723
+ receipt = materialization.receipt_sha256
724
+ return MaterializedResidualProposal(
725
+ plan=plan,
726
+ target_candidate_id=target_candidate_id,
727
+ configuration=configuration,
728
+ component_option_identity_sha256s=tuple(
729
+ value.identity_sha256 for value in options
730
+ ),
731
+ engine_materialization_receipt_sha256=receipt,
732
+ )
733
+
734
+
735
+ __all__ = [
736
+ "CrossParentFiniteActionSchema",
737
+ "HierarchicalResidualPlan",
738
+ "MaterializedResidualProposal",
739
+ "ParentFiniteVariationBinding",
740
+ "ReachabilityAdmissionReason",
741
+ "ReachabilityBasisMember",
742
+ "ReachabilityCandidate",
743
+ "ResidualProposalRole",
744
+ "ResidualReachabilityBasis",
745
+ "ResidualReachabilityBasisPolicy",
746
+ "bind_cross_parent_finite_action_schema",
747
+ "materialize_hierarchical_residual_plan",
748
+ "select_residual_reachability_basis",
749
+ ]